Сразу попрошу воздержаться от плевков ))
Да, я понимаю, что php не совсем тот самый язык, на котором можно это делать, но
все же, хочу попробовать.
Нужно сделать простую болталку, которая будет отвечать на хотя бы 70% вопросов "в
тему"? и задавать свои.
Хотелось бы услышать мнения спецов.
То, что уже существует - хочу примерно тоже, но по-русски.
Как оно работает у них, реальный пример:
Victor: how are you doing?
ALICE: Not too bad.
Victor: great
ALICE: Thanks for the compliment.
Victor: what's new?
ALICE: I am chatting with clients on
the internet.
Victor: what is your name?
ALICE: I am called ALICE.
Victor: My name is Victor
ALICE: Hi there Victor.
Victor: you remember my name?
ALICE: You said your name is Victor?
Victor: yes
ALICE: Really.
Подчеркну: нужно не пояснение тех части, а алгоритм работы.
Заранее спасибо :)
Ответы
Ответ 1
Делаешь большой словарь(можно хранить в мускле) фраз-ответов.
Делаешь словарь ключевых слов и фраз
Парсишь фразу от пользователя
Выбираешь контрольные слова
Делаешь запрос в бд за ответом
Профит
Вариант 2:
Нанимаешь бабулек или китайцев
Садишь на другую сторону чата
Они отвечают на все вопросы
Профит
ГЗВ
Интересный образец.
Ответ 2
Я тоже пытался сделать "умного" бота на сайт. Делал базы данных, пробовал функции
с ответами. Но это громоздкая работа. Всё таки для таких вещей лучше использовать другие
языки программирования. Хотя, чтобы поломать мозг - можно и делать на PHP.
Некоторые действия:
Нужна база слов без склонений и окончаний
Нужен парсер, который будет убирать окончания
Нужно over9999 часов, чтобы делать ответы на вопросы
Нужно около месяца общаться через свой чат, чтобы вытаскивать оттуда фразы, которые
использовались, и возможные ответы. Тем самым Вы обучите бота обычным разговорам.
Нужно построить дерево фраз (как на iii)
Установить уже сделанного и проверенного бота от другого создателя и удалить всё
своё индусство
Ответ 3
Берем нейронную сеть, есть интересная библиотека (работает с кучей языков, в том
числе php, через api): http://leenissen.dk/fann/wp/ пишем ИИ, учим, захватываем мир.
Параллельно можно и чатик замутить.
Здравствуйте, хотелось бы узнать , примеры приложений , да и в целом, где и как применяются
нейронные сети и ИИ в приложениях.
Сам пишу на java под android, и хотелось бы узнать, реально ли совмещать данные занятия:"Изучение
нейронных сетей и ИИ и практиковаться и внедрять их в Мобильных Приложениях?
Ответы
Ответ 1
Как показала моя практика это возможно, однако писать нейросеть в самом приложении
не самая лучшая идея. Когда начинал изучение нейросетей, с 0 написал свою нейросеть
в виде библеотеки для андроид. Использую ее в 2 своих проектах: анализ рынка акций
и анализ предпочтений фильмов. В обоих случаях все работает, но дает очень большую
нагрузку на ЦП телефона и он буквально становиться сковордкой на которй можно жарить
яишницу. Если кончено сеть не глубокая и данных для обработки не много то можно и так,
но почитав кучу статей понял что намного лучше релизвать нейросеть отдельно на сервере
и общаться с ней по сети. На мой взгляд лучший фреймворк для НС это TensorFlow от гугла.
Ответ 2
Вполне реально совмещать. Нейронные сети используются в Prisma для обработки фотографий,
в Snapchat для наложения масок(применяется распознавание лиц в реальном времени с помощью
нейросети, а после уже применяются эффекты). В мобильном приложении Auto.ru нейронные
сети дают возможность по фотографии найти нужный автомобиль в продаже. В целом, применение
нейросетей широко, поэтому некоторые задачи и в мобильных приложениях с их помощью
решаются очень эффективно. Особенно те, что связаны с распознаванием образов.
Пример реализации нейросетей на Java
Нейронная сеть обучаемая по алгоритму обратного распространения ошибки
нейронная сеть типа-многослойный перцептрон
Пытаюсь как-то уложить все в голове, интересует какие сети лучше подойдут для задач
и почему
Знаю, некоторые задачи решаются вовсе не сетями, но легче сказать конечную цель,
чем абстрактно описывать сеть, которую я бы хотел найти
Допустим, задачи такие:
Распознавание голоса
Обучение музыкальному вкусу и поиск похожих песен
Контроль температуры инерционной системы (нужно очень быстрое обучение прям в процессе,
иначе что-то может перегреется или переохладится)
Распознавание графиков (допустим, спектра)
Научить узнавать человека с камеры по одному его фото
Ответы
Ответ 1
Существует несколько основных типов нейронный сетей которые используются для решения
некоторых типов задач. Очень и очень кратко:
FFNN Сеть прямого распространения - самая простая и в основном используется для анализа
данных в которых можно выявить повторяющийся паттерн.
RNN Рекурентная нейронная сеть - сеть которая делает вывод основываясь не только
на настоящих данных но и на прошедших. Используется там где важно учитивать влияние
нескольких факторов.
LSTM Сеть с длинной и короткой памятью - подвид рекурентных сетей, но в отличии от
обычной рекурентной сети может запоминать данные на долгий период иными словами понимать
контекст.
CNN Сверточная нейронная сеть - НС которая обрабатывает данные с помощью фильтров
и сети прямого распространения.
Отвечая на Ваш вопрос:
1 и 2 - LSTM. Все что связанно с обработкой речи и анализом текста нуждается в контексте,
также по умолчанию предложение это последовательная расстановка слов которые связанны
друг с другом по смыслу.
3 - FFNN. Не совсем понял суть но если логика заключается в том чтобы в заисимости
от набора факторов выставлять температуру то сеть прямого распространения подойдет
лучше всего.
4 - Либо FFNN либо RNN в зависимости от сложности и "предсказуемости" графика.
5 - CNN. Все что связанно с распознавание обьектов и анализом фото или видео, всегда
используется сверточная нейронная сеть.
Я делаю для презентации лабораторной работы программу где реализован логический ИИ.
Сдел её на JS.
Часть исполнения таково: есть "вход" где появляется группа пикселей "муравьев", бесцельно
бродящих близ "входа" и как только на поле выложить "еду" (пиксели другого цвета),
то "муравьи" идут к еде и "тащат" её на "выход".
В целом всё готово, но мне не понравилось, что "муравей" выбирает свою целевую еду
слишком просто - берется следующий элемент массива, где хранятся объекты "еда". Я решил
сделать так, что бы "муравей" выбирал ближайший от своей текущей координаты объект "еда".
Однако не смотря на, казалось бы, правильно (по моему мнению) написанный код, все
равно ничего не выходит.
Вот функция поиска "цели" "муравья":
function checkEat(id) //Проверка на наличие еды
{
var bestTarget = "";
var t = Infinity,l = Infinity; //будущие координаты "цели"
if (!antArmy[id].antOnTheHunt) //если муравей еще не охотится
if (eatStock.length > storageCount) { //если вся "еда" еще не утащена на "выход"
for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) { //идем по
массиву объектов "еда"
if (eatStock[eatAll] != "returned") //если "еда" уже не утащена
if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget)
//если "еда" не схвачена другим "муравьем"
{
//и на неё не претендует другой "муравей"...
var AntPT = getElemCoordinates(antArmy[id].name, "top");
//координаты текущего муравья
var AntPL = getElemCoordinates(antArmy[id].name, "left");
var eatPT = getElemCoordinates(eatStock[eatAll].name, "top");
//координаты текущей еды
var eatPL = getElemCoordinates(eatStock[eatAll].name, "left");
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) <
(t + l)) { //сравниваем сумму координат
t = eatPT; //если следующая сумма координат будет меньше
( а то есть ближе к "муравью")
l = eatPL; // то будут вписаны новые координаты ближайшего
объекта
bestTarget = eatStock[eatAll].name; //пока не выберется
ближайшая "еда"
}
}
}
}
alert(bestTarget); //проверка на работу (проверка не успешна)
antArmy[id].antOnTheHunt = true; //"муравей" выходит на охоту
antArmy[id].targetEat = bestTarget; //выбирает ближайшую "еду"
eatStock[bestTarget].onTarget = true; //"еда" "помечена"
storageCount++;
}
Посоветуете что-нибудь, пожалуйста? А то не смотря на дни, просиженные над этим куском
кода, ошибка мне не понятна. А узнать и реализовать очень интересно (
Вот полный код всей программы. Здесь нет предыдущей вставки и она рабочая.
Правда желательно запускать не через какой-то веб редактор, а напрямую с файла, дабы
не было каких-то ошибок.
var enter = false;
var exit = false;
var eat = false;
var enter_place = false;
var exit_place = false;
var eat_place = false;
var antArmy = [];
var antArmyFull = false;
var eatStock = [];
var storageCount = 0; //Подсчет кол-во отнесенной на выход еды
function ruler(command) { //подтверждает выбор инструмента. Когда пользователь кликнет
на поле, ruler определит,
//что установить на поле
if (command) {
switch (command) {
case "enter":
enter_place = true;
exit_place = false;
eat_place = false;
if (enter) document.getElementById('choose').innerHTML = '"Enter"
is already placed';
else document.getElementById('choose').innerHTML = '"Enter" is choosed';
break;
case "exit":
enter_place = false;
exit_place = true;
eat_place = false;
if (exit) document.getElementById('choose').innerHTML = '"Exit" is
already placed';
else document.getElementById('choose').innerHTML = '"Exit" is choosed';
break;
case "eat":
enter_place = false;
exit_place = false;
eat_place = true;
if (eat) document.getElementById('choose').innerHTML = '"Eat" is
already placed';
else document.getElementById('choose').innerHTML = '"Eat" is choosed';
break;
default:
alert("something wrong with function 'ruler'.");
}
}
}
function releaseAnt() { //конвеер муравьев
if (enter === true) {
while (antArmyFull === false) {
antArmy[antArmy.length] = new MakeAnt("ant" + antArmy.length);
if (antArmy.length >= 50) antArmyFull = true;
}
document.getElementById('numOfAnts').innerHTML = 'Ant army size: ' + antArmy.length
+ '.';
moveAnt();
}
}
function releaseEat(posX, posY){ //конвеер еды
var x = posX;
var y = posY;
var placing = eatStock.length + 60;
while (eatStock.length <= placing) {
if (x >= posX+40) {
x = posX;
y++;
}
eatStock[eatStock.length] = new PlaceEat(eatStock.length, x, y);
x++;
}
eat = true;
}
///////////////////////ANT/////////////////////////
function MakeAnt(name) { //конструктор муравья
this.name = name;
this.antOnTheHunt = false;
this.targetEat = "";
this.antGrabEat = false;
var positionOfHome = document.getElementById("enterance");
var ant_div = document.body.appendChild(document.createElement('div')); //создаем
div с атррибутами
ant_div.setAttribute("id", name);
/* В качестве начальных координат используются координаты "Входа" */
ant_div.style.cssText="position:absolute;\
top:" + parseInt(positionOfHome.style.top, 10) +
";\left:" + parseInt(positionOfHome.style.left, 10) + ";";
var annt_canvas = ant_div.appendChild(document.createElement('canvas')); //создаем
холст с атррибутами
annt_canvas.setAttribute("id", "a" + name);
var ant_canvas = document.getElementById("a" + name);//находим холст
var ant_context = ant_canvas.getContext("2d");//устанавливаем 2d рисование
ant_context.fillStyle = "#000000";//цвет заливки
ant_context.fillRect(0, 0, 1, 1);//создаем квадрат и заливаем
}
///////////////////////ANT MOVE////////////////////////
function moveAnt() { //управляющая выбором движения муравья функция
for (var i = 0; i < antArmy.length; i++) {
if (eat) checkEat(i);
if (!antArmy[i].antOnTheHunt && !antArmy[i].antGrabEat) {
checkMove(antArmy[i].name);
walkLikeADrunk(i); //хаотичное передвижение
}
if (exit) {
// if (!antArmy[i].antOnTheHunt) moveToTheExit(i); //Двигаться к выходу,
если он существует
if (antArmy[i].antOnTheHunt && antArmy[i].antGrabEat) bringEatBack(i);
//Двигаться с едой к выходу
}
if (antArmy[i].antOnTheHunt && !antArmy[i].antGrabEat) huntForEat(i); //охотится
за едой
}
setTimeout("moveAnt()", 100)
}
function move(who,where,line) { //line === "left" or "top"
if (line === "left") document.getElementById(who).style.left=parseInt(document.getElementById(who).style.left)+where;
if (line === "top") document.getElementById(who).style.top=parseInt(document.getElementById(who).style.top)+where;
}
function walkLikeADrunk(id) {
var rand = Math.round(Math.random() * (4 - 1) + 1);
switch (rand) {
case 2:
move(antArmy[id].name, 1, "left");
break;
case 3:
move(antArmy[id].name, -1, "left");
break;
case 1:
move(antArmy[id].name, 1, "top");
break;
case 4:
move(antArmy[id].name, -1, "top");
break;
default:
alert("move ant error");
}
}
function huntForEat(id)
{
if (antArmy[id].targetEat !== "")
{
var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top");
var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left");
var AntPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntPosLeft = getElemCoordinates(antArmy[id].name,"left");
if (eatPosTop < AntPosTop) move(antArmy[id].name, -1, "top");
else move(antArmy[id].name, 1, "top");
if (eatPosLeft < AntPosLeft) move(antArmy[id].name, -1, "left");
else move(antArmy[id].name, 1, "left");
checkEatBorder(id);
}
}
function bringEatBack(id)
{
var AntCurrPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntCurrPosLeft = getElemCoordinates(antArmy[id].name,"left");
var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top");
var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left");
moveToTheExit(id);
var AntPastPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntPastPosLeft = getElemCoordinates(antArmy[id].name,"left");
if (AntPastPosTop <= AntCurrPosTop) eatPosTop = AntPastPosTop-1;
else eatPosTop = AntPastPosTop+1;
if (AntPastPosLeft <= AntCurrPosLeft) eatPosLeft = AntPastPosLeft-1;
else eatPosLeft = AntPastPosLeft+1;
document.getElementById(antArmy[id].targetEat).style.left=eatPosLeft;
document.getElementById(antArmy[id].targetEat).style.top=eatPosTop;
}
function checkMove(name) //Проверка движения муравья, относительно положения "Входа"
{ //Если муравей не на "охоте", то он не уходит за установленные
границы
var AntPosCheckTop = getElemCoordinates(name,"top");
var AntPosCheckLeft = getElemCoordinates(name,"left");
var borderLineTop = getElemCoordinates("enterance","top");
var borderLineLeft = getElemCoordinates("enterance","left");
if ((borderLineTop < AntPosCheckTop) && (borderLineLeft < AntPosCheckLeft)) {
if (((borderLineLeft + 50) < AntPosCheckLeft) || ((borderLineTop + 50) <
AntPosCheckTop)) {
if (borderLineTop < AntPosCheckTop) move(name, -1, "top");
if (borderLineLeft < AntPosCheckLeft) move(name, -1, "left");
}
}
if ((borderLineTop > AntPosCheckTop) && (borderLineLeft < AntPosCheckLeft)) {
if (((borderLineLeft + 50) < AntPosCheckLeft) || ((borderLineTop - 50) >
AntPosCheckTop)) {
if (borderLineTop > AntPosCheckTop) move(name, 1, "top");
if (borderLineLeft < AntPosCheckLeft) move(name, -1, "left");
}
}
if ((borderLineTop > AntPosCheckTop) && (borderLineLeft > AntPosCheckLeft)) {
if (((borderLineLeft - 50) > AntPosCheckLeft) || ((borderLineTop - 50) >
AntPosCheckTop)) {
if (borderLineTop > AntPosCheckTop) move(name, 1, "top");
if (borderLineLeft > AntPosCheckLeft) move(name, 1, "left");
}
}
if ((borderLineTop < AntPosCheckTop) && (borderLineLeft > AntPosCheckLeft)) {
if (((borderLineLeft - 50) > AntPosCheckLeft) || ((borderLineTop + 50) <
AntPosCheckTop)) {
if (borderLineTop < AntPosCheckTop) move(name, -1, "top");
if (borderLineLeft > AntPosCheckLeft) move(name, 1, "left");
}
}
}
function checkExitBorder(id)
{
var AntPosCheckTop = getElemCoordinates(antArmy[id].name, "top"); //позиция муравья
var AntPosCheckLeft = getElemCoordinates(antArmy[id].name, "left");
var exitLineTop = getElemCoordinates("exit", "top"); //позиция выхода
var exitLineLeft = getElemCoordinates("exit", "left");
var startLineTop = getElemCoordinates("enterance", "top"); //позиция входа
var startLineLeft = getElemCoordinates("enterance", "left"); //это нам нужно
что бы возвратить муравья
if ((exitLineTop <= AntPosCheckTop) && (exitLineLeft <= AntPosCheckLeft)) {
if (((exitLineLeft + 5) > AntPosCheckLeft) && ((exitLineTop + 5) > AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop
+ "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft
+ "px";
}
}
if ((exitLineTop > AntPosCheckTop) && (exitLineLeft < AntPosCheckLeft)) {
if (((exitLineLeft + 5) > AntPosCheckLeft) && ((exitLineTop - 5) < AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop
+ "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft
+ "px";
}
}
if ((exitLineTop >= AntPosCheckTop) && (exitLineLeft >= AntPosCheckLeft)) {
if (((exitLineLeft - 5) < AntPosCheckLeft) && ((exitLineTop - 5) < AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop
+ "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft
+ "px";
}
}
if ((exitLineTop < AntPosCheckTop) && (exitLineLeft > AntPosCheckLeft)) {
if (((exitLineLeft - 5) < AntPosCheckLeft) && ((exitLineTop + 5) > AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop
+ "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft
+ "px";
}
}
}
function checkEatBorder(id)
{
var AntPosCheckTop = getElemCoordinates(antArmy[id].name,"top"); //позиция муравья
var AntPosCheckLeft = getElemCoordinates(antArmy[id].name,"left");
var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top");
var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left");
if ((eatPosTop <= AntPosCheckTop) && (eatPosLeft <= AntPosCheckLeft)) {
if (((eatPosLeft + 2) > AntPosCheckLeft) && ((eatPosTop + 2) > AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
if ((eatPosTop > AntPosCheckTop) && (eatPosLeft < AntPosCheckLeft)) {
if (((eatPosLeft + 2) > AntPosCheckLeft) && ((eatPosTop - 2) < AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
if ((eatPosTop >= AntPosCheckTop) && (eatPosLeft >= AntPosCheckLeft)) {
if (((eatPosLeft - 2) < AntPosCheckLeft) && ((eatPosTop - 2) < AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
if ((eatPosTop < AntPosCheckTop) && (eatPosLeft > AntPosCheckLeft)) {
if (((eatPosLeft - 2) < AntPosCheckLeft) && ((eatPosTop + 2) > AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
}
/*function checkEat(id) //Проверка на наличие еды
{
var bestTarget = "";
var t = Infinity,l = Infinity;
if (!antArmy[id].antOnTheHunt)
if (eatStock.length > storageCount) {
for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) {
if (eatStock[eatAll] != "returned")
if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) {
var AntPT = getElemCoordinates(antArmy[id].name, "top");
var AntPL = getElemCoordinates(antArmy[id].name, "left");
var eatPT = getElemCoordinates(eatStock[eatAll].name, "top");
var eatPL = getElemCoordinates(eatStock[eatAll].name, "left");
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l)) {
t = eatPT;
l = eatPL;
bestTarget = eatStock[eatAll].name;
}
}
}
}*/
function checkEat(id) //Проверка на наличие еды
{
if (!antArmy[id].antOnTheHunt)
if (eatStock.length > storageCount) {
for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) {
if (eatStock[eatAll] != "returned")
if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) {
antArmy[id].antOnTheHunt = true;
antArmy[id].targetEat = eatAll;
eatStock[eatAll].onTarget = true;
storageCount++;
break;
}
}
}
}
function moveToTheExit(id)
{
var exitPosTop = getElemCoordinates("exit","top");
var exitPosLeft = getElemCoordinates("exit","left");
var AntPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntPosLeft = getElemCoordinates(antArmy[id].name,"left");
checkExitBorder(id);
if (exitPosTop < AntPosTop) move(antArmy[id].name, -1, "top");
else move(antArmy[id].name, 1, "top");
if (exitPosLeft < AntPosLeft) move(antArmy[id].name, -1, "left");
else move(antArmy[id].name, 1, "left");
}
function PlaceEat(eatid, posX, posY) { //конструктор еды
this.name = eatid;
this.onTarget = false;
this.grabbed = false;
var eat_div = document.body.appendChild(document.createElement('div')); //создаем
div с атррибутами
eat_div.setAttribute("id", eatid);
eat_div.style.cssText = "position:absolute;\
top:" + posY +
";\left:" + posX + ";";
var eaat_canvas = eat_div.appendChild(document.createElement('canvas')); //создаем
холст с атррибутами
eaat_canvas.setAttribute("id", "eat" + eatid);
var eat_canvas = document.getElementById("eat" + eatid);//находим холст
var eat_context = eat_canvas.getContext("2d");//устанавливаем 2d рисование
eat_context.fillStyle = "#FFA500";//цвет заливки
eat_context.fillRect(0, 0, 1, 1);//создаем квадрат и заливаем
}
//Функция реагирования на "клик" пользователя.
//Если инструмент выбран...
document.addEventListener('click', function (e) {
if ((document.elementFromPoint(e.clientX, e.clientY).tagName) != "BUTTON") {
////////////////////ENTERANCE/////////////////////
if (enter_place === true) {
if (enter === false) {
var enter_div = document.body.appendChild(document.createElement('div'));
//создаем div с атррибутами
enter_div.setAttribute("id", "enterance");
enter_div.style.cssText="position:absolute;\
top:" + e.pageY +
";\left:" + e.pageX + ";";
var enteer_canvas = enter_div.appendChild(document.createElement('canvas'));
//создаем холст с атррибутами
enteer_canvas.setAttribute("id", "e");
var enter_canvas = document.getElementById("e");//находим холст
var enter_context = enter_canvas.getContext("2d");//устанавливаем
2d рисование
enter_context.fillStyle = "#000080";//цвет заливки
enter_context.fillRect(0, 0, 10, 10);//создаем квадрат и заливаем
enter = true;
releaseAnt();
}
}
//////////////////EXIT////////////////////////
if (exit_place === true) {
if (exit === false) {
var exit_div = document.body.appendChild(document.createElement('div'));
//создаем div с атррибутами
exit_div.setAttribute("id", "exit");
exit_div.style.cssText="position:absolute;\
top:" + e.pageY +
";\left:" + e.pageX + ";";
var exiit_canvas = exit_div.appendChild(document.createElement('canvas'));
//создаем холст с атррибутами
exiit_canvas.setAttribute("id", "ex");
var exit_canvas = document.getElementById("ex");//находим холст
var exit_context = exit_canvas.getContext("2d");//устанавливаем 2d
рисование
exit_context.fillStyle = "#FF0000";//цвет заливки
exit_context.fillRect(0, 0, 10, 10);//создаем квадрат и заливаем
exit = true;
}
}
////////////////EAT////////////////////////
if (eat_place === true) {
releaseEat(e.pageX, e.pageY);
}
}
}, false);
function getElemCoordinates(name,side) //side = top/left
{
if (side === "top") return parseInt(document.getElementById(name).style.top, 10);
if (side === "left") return parseInt(document.getElementById(name).style.left, 10);
}
//Вызов elem.cloneNode(true) создаст «глубокую» копию элемента
//parentElem.removeChild(elem)
Ответы
Ответ 1
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l))
Вы берете расстояние между муравьем и едой и сравниваете с абсолютными координатами
другой еды, что в корне не верно.
Вам надо помнить САМО РАССТОЯНИЕ
var t=Infinity;
...
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < t)
{
t=(Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL);
....
}
Закрыт. Данный вопрос необходимо конкретизировать. Ответы
на него в данный момент не принимаются.
Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он был сосредоточен только на одной проблеме, отредактировав его.
Закрыт 4 месяца назад.
Подскажите, может кто видел такую статистику: какие фразы и слова говорят люди, когда
беседуют с роботом или программой искусственного интеллекта.
Пишу программку, где человеку предстоит пообщаться с роботом, нужно подготовить ответы
на пару тысяч самых популярных фраз. Подскажите, где поискать такую статистику.. Гугл
заводит в тупик.
Ответы
Ответ 1
Попpобуйте сделать так: заходите в гугл/яндекс, и введите запрос "почему в/как/почему/где/зачем/каким
образом/какой". Далее смотриье подсказки - это будут самые популярные вопросы пользователей.
Также попробуйте посмотреть здесь, иногда тоже попадается что-то интересное.
И ещё: представьте, что у вас появилась машина, которая ответит на все ваши вопросы.
Какие бы вы задали, такие и добавьте вашему боту.
UPD Загляните сюда.
UPD 2 Поговорил с андроид-версией бота в стиле Зелёного Слоника. Ничего не менял.
Вопрос к разработчикам проектов по распознаванию образов. Как лучше организовать
архитектуру подобного сервиса?
Сейчас склоняюсь к решению использовать для работы с данными (а особенно для обучения)
специализированные GPU-инстансы Amazon EC2 P2. На серверах установлено ПО только для
работы искусственных нейронных сетей (Python, Anaconda, Keras, TensorFlow). В production-режиме
сервер на вход принимает изображения с метаданными (как именно обработать изображение
и какие данные вернуть), на выходе возвращает JSON-массив в зависимости от типа метаданных.
Никакой особой логики там не хранится, вся аналитика происходит на серверах web-приложений.
Обучающие и тестовые выборки хранятся в отдельном кластере (обычные сервера с большим
дисковым пространством). Туда же загружаются изображения из сети найденные собственными
поисковыми ботами (через соцсети и поисковые системы).
Взаимодействие web-приложения с нейронной сетью осуществляется через API-запросы
к GPU-серверам. Далее результат уже выдается на клиенты (аналогично с клиентов все
идет на web-приложение, а затем на обработку в нейронную сеть).
Теперь основные вопросы:
На каком участке вы проводите аналитику? (например, чтобы определить, что на фотографии
на человеке надет синий мужской пиджак к нейронной сети выполняется каскад запросов
"поиск мужчины"->"поиск пиджака"->"определение цвета пиджака". для получения более
высокого качества ответа и снижения нагрузки на сеть каждый запрос выполняется отдельно
при утвердительном предыдущем). Имеет ли смысл реализовывать все варианты поиска в
рамках единой нейросети или лучше создать множество отдельных нейросетей, заточенных
под достаточно простые задачи?
Как вы оптимизируете потребление ресурсов на этапах обучения и работы сети? Пока
на уме только вариант с созданием специализированного GPU-кластера под обучение в рамках
облачного хостинга и его периодическое включение по мере надобности (иначе дорого получается).
Ответы
Ответ 1
Ваши вопросы говорят о том что, вы не осознаете всей сложности проблемы поиска мужчины
на фото, не говоря уж о поиске пиджака. Хотя бы найти объект произвольного размера
на фото по меркам на конец 2017 года - это уже передний край науки.
Сначала начните с простого. Попытайтесь хотя бы в общих чертах решить вашу проблему,
о которой ни слова в вопросе. Арендуете ли вы для этого один сервер, или купите подходящую
видеокарту - дело второе. Можно и без видеокарт. Как только вы поймете что для радикального
уменьшения ошибки обучения вам нужны годы на ваших мощностях, тогда можно будет говорить
об аренде кластера. И тогда вы можете обратиться к документации на TensorFlow чтобы
узнать как конкретно решаются подобные проблемы.
Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
Хотите улучшить этот вопрос? Update the question so it
can be answered with facts and citations by editing this post.
Закрыт 3 года назад.
Если возможна, будет ли эта модель "настоящей" душой (то есть требуется ли для "настоящести"
биологический мозг)? Если нет, верите ли вы в возможность научного исследования и описания
невычислимого разума?
Ответы
Ответ 1
Верю.
P.S. Аргументов нет, потому что категория верю/не верю не подразумевает аргументацию
Update
Придется аргументировать раз такая пьянка пошла :)
Вопрос на самом то деле упирается не в верю/не верю в модель разума, а в верю/не
верю в душу. А душа есть субстанция с которой оперирует Господь. То есть все упирается
в верю/не верю в Бога. Если душу можно смоделировать машиной, значит Бога нет. Если
нельзя значит Бог есть. Путем несложным логических выкладок теперь можно легко убедиться
кто в этой дискуссии верит в Бога, а кто атеист.
Ответ 2
Мой ответ хоть и запоздалый, но, надеюсь, он более подробный, так как я длительное
время занимаюсь темами ИИ и когнитивной науки.
Определимся с понятиями:
Под интеллектом будем понимать способность обрабатывать информацию и приходить к
какому-то решению. Без понимания, зачем это и почему. Тогда интеллектуальны в какой-то
мере все вычислительные машины, хотя конечно, нейронная сеть будет более интеллектуальная,
чем калькулятор. А оценивать интеллект можно по количеству обрабатываемой разнородной
информации и способности к обучению.
Сознание, разум — это сильный интеллект (т.е., способный обучаться обрабатывать новые
виды информации), который обладает каким-либо пониманием себя и своего места в мире,
своих целей. Не обязательно в физическом мире, можно представить операционную систему
будущего, которая будет общаться с пользователем посредством человеческого языка и
с другими компьютерами для достижения своих целей.
Таким образом, гипотетически можно построить искусственный разум, задать ему алгоритмы
обучения, систему ценностей, даже эмоции, которые будут влиять на поведение. (Здесь
уместно задаться вопросом, такой разум будет действительно чувствовать или только симулировать
это? Пища для размышлений.) Но будет ли этот созданный разум сопоставим с человеческим?
Очевидно, что мы обладаем мощными способностями к пониманию и обучению. Значит, для
аналогичных способностей нужна универсальная система представления знаний и такой же
универсальный алгоритм обучения. Под словом "универсальный" я понимаю "сопоставимый
с человеческим", потому как вполне могут быть иметь место интеллектуальные способности
выше человеческих, но об этом чуть позже.
На искусственные нейронные сети с самого их создания регулярно возлагают слишком
большие надежды. Которые не оправдываются. Стоит обратить внимание на тот факт, что
ИНС не имеют вычислительной полноты. Подробнее об этом можно почитать здесь. Также,
у них совсем нет полноты представления знаний; сложно представить, как в ИНС будет
храниться знание "Маша никогда не забывает чистить зубы перед сном".
Встают закономерные вопросы, а можно ли в принципе создать (1) систему представления
знания и (2) механизм обучения сопоставимый или выше человеческого? Здесь стоит указать,
что я искренний христианин и считаю, что наше сознание не ограничено мозгом, а имеет
также нематериальную природу.
1.
Наш мир дискретен (не будем принимать во внимание столь мало исследованную квантовую
физику). Дискретно всё, камни, буквы, печеньки, молекулы, атомы. И, конечно же, байты
с битами. При этом, сознание человека далеко не дискретно, в нём встречаются очень
расплывчатые взаимосвязи и сочетания сущностей. Но вдохните воздух — несмотря на дискретность,
он кажется очень не точечным. Потому, что состоит из множества маленьких частичек.
Вероятно, наши компьютеры смогут аналогично интегрировать знания до множества различных,
маленьких компонент. Это предполагает сложные алгоритмы и большие вычислительные ресурсы,
но, в принципе, система представления знания сопоставимая с таковой в человеческом
сознании возможна.
2.
Обучающиеся программы, машины способные заменить человека при решении удручающих
интеллектуальных задач, всегда были мечтой энтузиастов. Некоторые даже фантазируют
о самоулучшающемся ИИ, который будет создавать более интеллектуальный интеллект, а
тот ещё более, и ещё, что приведёт к технологической сингулярности. Но можно ли создать
хотя бы человеческий интеллект? Здесь точных аргументов нет, но я считаю, что нельзя.
Сколько учёные когнитивной психологии и другие не стараются описать фундаментальные
принципы человеческого мышления и познания, почти столько же у них это не получается.
Мы можем запрограммировать, а компьютеры выполнить только то, что мы можем понять и
описать. Но мы не можем понять самих себя, как мы думаем и мыслим, а значит, не можем
этого создать. Это трансцендентность. То есть, наше сознание основано на иных материях
и процессах, чём-то вроде гипервычислений.
Из всего выше получается, что искусственный разум можно создать, можно сделать его
приближенный к человеческим способностям, но такой же или мощнее — невозможно.
UPD. Современная наука довольно холодно относится к понятию души. Я же считаю, что
она, как и разум, является сущностью иной природы, которую в физическом мире засечь
очень трудно, если вообще возможно. А создать её и подавно нельзя.
В физике раньше считалось, что мир состоит только из материи и энергии. В последнее
время всё больше уделяется внимания информации как самостоятельной сущности. У меня
есть теория, что в основе бытия лежит именно информация (В начале было Слово, Ин.1:1),
а материя и энергия — её производные. Это похоже на цифровую физику, но в той считается,
что мир можно вычислить битами, я же считаю, что та информация, которая определяет
все законы нашего мироздания, трансцендентна, и точно не выразится байтами. То есть,
мы живём в физическом мире, можем осознавать и манипулировать им, хотя мы и сам мир
созданы и существуем в концепциях более высокого порядка, и ими манипулировать не можем.
Ответ 3
Будучи агностиком, о моделировании души ничего разумного сказать не могу.
А вот, можно ли смоделировать поведение (реакции на внешние сигналы)? Думаю, что да.
В качестве доказательства можно посмотреть на недавний успех в вождении автомобиля
по улицам без водителя.
В плане проявления интеллекта (точнее, сопоставления кучи известных "машине" фактов)
можно вспомнить игру Watson-а в Jeopardy.
А в некоторых областях (шахматы) нечеловеческий интеллект доказал свое превосходство.
Чемпионы играть с компьютерами уже перестали.
Ответ 4
Почему бы и нет — большущая нейронная сеть, обучающаяся многие годы, немного хаоса/случайностей,
немного эха событий. Огромный объём связанной информации может, даже какую-то ненулевую
добавленную массу будет иметь, и не пропадать бесследно после гибели (реинкарнироваться).
Представьте, что будет, если «погибнет» интернет ; )
«Настоящность» — вопрос для философских баталий, без единственного решения.
Я хочу построить регрессию с несколькими переменными (multiple features). В моих
данных у меня n = 23 переменных и m = 13000 тренировочных примеров. Вот график моих
тренировочных данных (площадь квартиры vs цена):
Здесь на графике отображены 13000 тренировочных данных. Как вы можете видеть, это
достаточно шумные данные. Мой вопрос: какой алгоритм регрессии больше подходит и обоснован
для использования в моем случае. Имею ввиду логично ли использовать простую линейную
регрессию или лучше использовать какой-либо нелинейный алгоритм регрессии.
Для наглядности приведу примеры.
Вот отвлеченный пример линейной регрессии:
А также отвлеченный пример нелинейной регрессии:
А вот примеры с гипотетическими линиями регрессии для моих данных:
Насколько я понимаю, примитивная линейная регрессия для моих данных произведет большую
суммарную погрешность (error cost), так как эти данные шумные и разбросанные. С другой
стороны, здесь также не прослеживается какой-либо отчетливой нелинейной зависимости
(например синусоидальной). Какой алгоритм регрессии более рационально использовать
в моем случае (цены на квартиры) для того чтобы получить более точное прогнозирование
цен. И почему этот алгоритм (линейный или нелинейный) более рационален?
Дополнение:
Вот так выглядит мой график линейной зависимости цены от всех 23 параметров:
Я не знаю, как бы выглядела НЕлинейная зависимость в таком случае. И была бы она
более рациональна чем линейная.
Ответы
Ответ 1
Для сравнения статистических моделей обычно используют информационные критерии, например,
информационный критерий Акаике. Если вы пишете на R, то посмотрите функцию stepAIC
- она позволяет упростить линейную модель, выкидывая из нее предикторы по одному, в
порядке возрастания значимости для модели.
Не так давно решил изучать нейронные сети, еще новичок. Понял, что сетей на самом
деле много. Не знаю какую выбрать.
Раньше с помощью OpenCV работал со снимками УЗИ, с помощью фильтров выделял контуры
органов, но проблема была в том, что руками приходилось подбирать параметры для фильтров,
что было не удобно.
Сейчас хочу реализовать программу, чтобы контуры органов определяла сеть. Подскажите,
при помощи каких инструментов можно реализовать?
Ответы
Ответ 1
Если Вы хотите решать задачу именно с помощью нейронных сетей, то одним из распространенных
вариантов являются Fully Convolutional neural networks. К примеру:
https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf
С точки зрения конкретного инструментария, то практически любой современный фреймворк
(TensorFlow, Torch, MXNet, Caffe, etc..) и даже высокоуровные wrapper'ы вроде Keras
без проблем справятся с реализацией такого рода сетей.
Closed. This question is opinion-based. It is not currently
accepting answers.
Want to improve this question? Update the question so
it can be answered with facts and citations by editing this post.
Closed 4 года назад.
Что читали и можете посоветовать по ИИ (искусственный интеллект)? Интересует как
и общие сведения, так и именно разработка ИИ для игровых проектов. Для начала хотелось
бы узнать, что можно почитать на русском, но так же рассмотрю варианты англоязычных
книг. Бумажный вариант даже приятнее, если он есть в продаже.
Ответы
Ответ 1
Я пока что не прочел ни одной книжки по ИИ (как академическом, так и игровом), но
думаю, это будет полезно:
Для начала хотелось бы узнать, что можно почитать на русском
Забудьте о существовании русского языка применительно к изучению ИИ. Вспоминать о
нем можно, задавая вопросы на gamedev.ru.
Литература, полезные ссылки:
Академический ИИ
Amazon - открыв ссылку на любую книгу, в конце странички можно увидеть рецензии людей,
купивших книгу и соотношение +/-.
Stanford AI - cовсем недавно прошел бесплатный видеокурс от Стенфорда, видео доступны
на youtube (по ссылке оглавление слева). Насколько я понимаю, книга, по которой они
идут: AI modern approach. (Кстати, насчет бесплатных курсов Стэнфорда: скоро они запускают
новый цикл курс (AI в нем не будет), идет запись желающих, например - Design and Analysis
of Algorithms I, остальные курсы в конце странички)
Игровой ИИ
Полезные ссылки - автор поста сам написал книгу, в его компетенции можно не сомневаться.
Programming Game AI by Example - действительно хороша, к ней приложены очень интересные
примеры программ на С++ с исходным кодом.
Gamedev.net AI - если возникают вопросы в процессе обучения, то стоит писать туда.
Ответ 2
Советую ознакомиться с материалами на этом сайте. Вообще, эта организация занимается
разработкой, исследованием и оценкой рисков, связанных со сверхчеловеческим искусственным
интеллектом.
Также стоит ознакомиться со статьями одного из участников этого проекта. Если есть
желание, то к этому проекту можно и присоединиться, но для этого нужно иметь очень
много нетривиальных знаний.
Целесообразно ли использовать ансамбль сверточных нейронных сетей (convolutional
neural network) для задач распознавания образов?
Согласно следующей англоязычной статье и соответствующей презентации, использование
ансамбля сверточных нейронных сетей ведет к значительному снижению ошибок. Показано
на примере распознавания образов цифр из базы MNIST.
Показано, что с увеличением количества моделей в ансамбле растет
точность распознавания:
Ансамблевый алгоритм может привести не только к улучшению точности
распознавания, но и к уменьшению времени, затраченному на обучение.
Я не смог найти год публикации данной статьи, также как и ученую степень ее автора.
Возможно, использование ансамбля сверточных нейросетей уже не актуально на сегодняшний
день или показало свою несостоятельность в задачах распознавания образов.
Также я обратил внимание на следующую русскоязычную статью датируемую 2012 годом:
Актуальные вопросы использования сверточных нейронных сетей и их комитетов в распознавании
образов цифр (Кузьмицкий Н.Н., 2012, pdf)
Здесь также производится распознавание образов цифр из различных баз. В статье и
работе наглядно продемонстрирована эффективность применения комитетов CNN, обученных
на базах с различным стилем начертания.
Вот одна из таблиц сравнения точности распознавания комитетами нейросетей и системы
KADMOS:
Но сам я сталкивался с противоположными мнениями экспертов, которые утверждали, что
использование ансамблей сверточных нейронных сетей не является актуальным на сегодняшний
день. Согласно их мнению, сегодня решение задач распознавания образов больше сконцентрировано
на оптимизации одной модели нейросети, чем на использовании их ансамблей.
И все-таки как же обстоят дела в этом вопросе? На данный момент, имеются ли значимые
преимущества использования ансамбля сверточных нейронных сетей перед вариантом с одной
нейронной сетью (без ансамбля) в задачах распознавания образов или нет?
Ответы
Ответ 1
Данный ответ представляет собой перевод ответа пользователя Franck Dernoncourt в
следующем вопросе на англ. языке.
На данный момент, имеются ли значимые преимущества использования ансамбля сверточных
нейронных сетей перед вариантом с одной нейронной
сетью (без ансамбля) в задачах распознавания образов?
Эмпирически, ансамбли сверточных нейронных сетей (CNNs) часто дают некоторое преимущество
в сравнении с одной сверточной нейросетью.
Пример классификации изображений приведен в статье авторов Krizhevsky Alex, Ilya
Sutskever и Geoffrey E. Hinton:
"ImageNet classification with deep convolutional neural networks/Классификация
изображений ImageNet с использованием сверточных нейронных сетей
(ENG, 2012, PDF)"
Там приведена следующая таблица:
Перевод:
Сравнение коэффициента ошибок на ILSVRC-2012 на проверочном/контрольном (validation)
и тестовом (test) множествах. Курсивом обозначены лучшие результаты, достигнутые другими
алгоритмами. Модели со звездочкой* были предварительно обучены классификации всей базы
изображений ImageNet 2011 (осенний релиз). Более подробно см. раздел 6.
На примере машинного перевода (c использованием LSTM сетей) имеется статья авторов:
Sutskever Ilya, Oriol Vinyals, и Quoc V. Le:
Sequence to sequence learning with neural networks/Обучение типа
“последовательность-в-последовательность” с нейронными сетями (ENG, 2014, PDF)
В статье приведена таблица:
Перевод:
Эффективность LSTM на WMT 2014 на тестовом множестве "С английского на французский
(ntst14)". Обратите внимание, что ансамбль из 5 LSTM сетей с размером пучка (beam size)
2 дешевле, чем одна LSTM-сеть с размером пучка 12.
Подскажите, пожалуйста, какие существуют способы порождения достоверных гипотез,
а так же их преимущества/недостатки? Какую русскоязычную литературу посоветуете почитать
на эту тему?
Ответы
Ответ 1
Нашел по крайней мере 2 метода:
GUHA-метод
ДСМ-метод
Литература:
Гаек П., Гавранек Т. Автоматическое образование гипотез. Математические основы общей
теории (GUHA метод)
ДСМ-метод автоматического порождения гипотез. Логические и эпистемологические основания
Автоматическое порождение гипотез в интеллектуальных системах
Достоверный и правдоподобный вывод в интеллектуальных системах
Из недостатков ДСМ-метода можно отметить неприменимость в условиях противоречий в
обучающих примерах, а так же
ДСМ-метод, не использующий
статистических критериев, может быть
«введён в заблуждение» шумовыми
данными.
Ответ 2
Не думаю, что ДСМ-метод вам поможет в выдвижении "достоверных" гипотез. Чтобы гипотеза
стала достоверной, её надо формально доказать; но это будет уже не гипотеза, а теорема.
А что касаемо гипотез, я думаю, в большинстве случаев сгодится нейросеть или метод
опорных векторов или дерево выбора, если хочется увидеть саму гипотезу.
Пытаюсь как-то уложить все в голове, интересует какие сети лучше подойдут для задач и почему Знаю, некоторые задачи решаются вовсе не сетями, но легче сказать конечную цель, чем абстрактно описывать сеть, которую я бы хотел найти Допустим, задачи такие:
Распознавание голоса
Обучение музыкальному вкусу и поиск похожих песен
Контроль температуры инерционной системы (нужно очень быстрое обучение прям в процессе, иначе что-то может перегреется или переохладится)
Распознавание графиков (допустим, спектра)
Научить узнавать человека с камеры по одному его фото
Ответ
Существует несколько основных типов нейронный сетей которые используются для решения некоторых типов задач. Очень и очень кратко FFNN Сеть прямого распространения - самая простая и в основном используется для анализа данных в которых можно выявить повторяющийся паттерн. RNN Рекурентная нейронная сеть - сеть которая делает вывод основываясь не только на настоящих данных но и на прошедших. Используется там где важно учитивать влияние нескольких факторов. LSTM Сеть с длинной и короткой памятью - подвид рекурентных сетей, но в отличии от обычной рекурентной сети может запоминать данные на долгий период иными словами понимать контекст. CNN Сверточная нейронная сеть - НС которая обрабатывает данные с помощью фильтров и сети прямого распространения. Отвечая на Ваш вопрос: 1 и 2 - LSTM. Все что связанно с обработкой речи и анализом текста нуждается в контексте, также по умолчанию предложение это последовательная расстановка слов которые связанны друг с другом по смыслу. 3 - FFNN. Не совсем понял суть но если логика заключается в том чтобы в заисимости от набора факторов выставлять температуру то сеть прямого распространения подойдет лучше всего. 4 - Либо FFNN либо RNN в зависимости от сложности и "предсказуемости" графика. 5 - CNN. Все что связанно с распознавание обьектов и анализом фото или видео, всегда используется сверточная нейронная сеть.
Какой принцип заложен в Яндекс Радио? Это Нейронная сеть или Рекомендательная система?
Ответ
А если погуглить?
цитата с блога яндекса за 4 июня 2015 года
В основе Яндекс.Радио лежит рекомендательная технология, разработанная
в Яндексе. Мы назвали её Диско, отчасти в честь музыкального жанра
(впервые Диско применили в Яндекс.Музыке), а отчасти по созвучию с
английским discovery — «открытие чего-то нового», словом, которое
очень точно отражает суть технологии. Диско учитывает ваши действия
(факты прослушивания и пропуска треков и оценки «нравится» и «не
нравится»), составляет картину музыкальных предпочтений и, сверяясь с
ней, определяет, какую музыку пускать в эфир станции.
Теперь зайдём на наш любимый вики:
цитата со статьи в википедии о сервисе яндекс.радио
Действует машинное обучение на основе истории прослушиваний:
пользователь может создать свою собственную радиостанцию, которая
будет ориентироваться на его предпочтения.
Здравствуйте, хотелось бы узнать , примеры приложений , да и в целом, где и как применяются нейронные сети и ИИ в приложениях.
Сам пишу на java под android, и хотелось бы узнать, реально ли совмещать данные занятия:"Изучение нейронных сетей и ИИ и практиковаться и внедрять их в Мобильных Приложениях?
Ответ
Как показала моя практика это возможно, однако писать нейросеть в самом приложении не самая лучшая идея. Когда начинал изучение нейросетей, с 0 написал свою нейросеть в виде библеотеки для андроид. Использую ее в 2 своих проектах: анализ рынка акций и анализ предпочтений фильмов. В обоих случаях все работает, но дает очень большую нагрузку на ЦП телефона и он буквально становиться сковордкой на которй можно жарить яишницу. Если кончено сеть не глубокая и данных для обработки не много то можно и так, но почитав кучу статей понял что намного лучше релизвать нейросеть отдельно на сервере и общаться с ней по сети. На мой взгляд лучший фреймворк для НС это TensorFlow от гугла.
Я делаю для презентации лабораторной работы программу где реализован логический ИИ. Сдел её на JS. Часть исполнения таково: есть "вход" где появляется группа пикселей "муравьев", бесцельно бродящих близ "входа" и как только на поле выложить "еду" (пиксели другого цвета), то "муравьи" идут к еде и "тащат" её на "выход". В целом всё готово, но мне не понравилось, что "муравей" выбирает свою целевую еду слишком просто - берется следующий элемент массива, где хранятся объекты "еда". Я решил сделать так, что бы "муравей" выбирал ближайший от своей текущей координаты объект "еда". Однако не смотря на, казалось бы, правильно (по моему мнению) написанный код, все равно ничего не выходит. Вот функция поиска "цели" "муравья":
function checkEat(id) //Проверка на наличие еды
{
var bestTarget = "";
var t = Infinity,l = Infinity; //будущие координаты "цели"
if (!antArmy[id].antOnTheHunt) //если муравей еще не охотится
if (eatStock.length > storageCount) { //если вся "еда" еще не утащена на "выход"
for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) { //идем по массиву объектов "еда"
if (eatStock[eatAll] != "returned") //если "еда" уже не утащена
if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) //если "еда" не схвачена другим "муравьем"
{ //и на неё не претендует другой "муравей"...
var AntPT = getElemCoordinates(antArmy[id].name, "top"); //координаты текущего муравья
var AntPL = getElemCoordinates(antArmy[id].name, "left");
var eatPT = getElemCoordinates(eatStock[eatAll].name, "top"); //координаты текущей еды
var eatPL = getElemCoordinates(eatStock[eatAll].name, "left");
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l)) { //сравниваем сумму координат
t = eatPT; //если следующая сумма координат будет меньше ( а то есть ближе к "муравью")
l = eatPL; // то будут вписаны новые координаты ближайшего объекта
bestTarget = eatStock[eatAll].name; //пока не выберется ближайшая "еда"
}
}
}
}
alert(bestTarget); //проверка на работу (проверка не успешна)
antArmy[id].antOnTheHunt = true; //"муравей" выходит на охоту
antArmy[id].targetEat = bestTarget; //выбирает ближайшую "еду"
eatStock[bestTarget].onTarget = true; //"еда" "помечена"
storageCount++;
}
Посоветуете что-нибудь, пожалуйста? А то не смотря на дни, просиженные над этим куском кода, ошибка мне не понятна. А узнать и реализовать очень интересно ( Вот полный код всей программы. Здесь нет предыдущей вставки и она рабочая.
Правда желательно запускать не через какой-то веб редактор, а напрямую с файла, дабы не было каких-то ошибок.
var enter = false;
var exit = false;
var eat = false;
var enter_place = false;
var exit_place = false;
var eat_place = false;
var antArmy = [];
var antArmyFull = false;
var eatStock = [];
var storageCount = 0; //Подсчет кол-во отнесенной на выход еды
function ruler(command) { //подтверждает выбор инструмента. Когда пользователь кликнет на поле, ruler определит,
//что установить на поле
if (command) {
switch (command) {
case "enter":
enter_place = true;
exit_place = false;
eat_place = false;
if (enter) document.getElementById('choose').innerHTML = '"Enter" is already placed';
else document.getElementById('choose').innerHTML = '"Enter" is choosed';
break;
case "exit":
enter_place = false;
exit_place = true;
eat_place = false;
if (exit) document.getElementById('choose').innerHTML = '"Exit" is already placed';
else document.getElementById('choose').innerHTML = '"Exit" is choosed';
break;
case "eat":
enter_place = false;
exit_place = false;
eat_place = true;
if (eat) document.getElementById('choose').innerHTML = '"Eat" is already placed';
else document.getElementById('choose').innerHTML = '"Eat" is choosed';
break;
default:
alert("something wrong with function 'ruler'.");
}
}
}
function releaseAnt() { //конвеер муравьев
if (enter === true) {
while (antArmyFull === false) {
antArmy[antArmy.length] = new MakeAnt("ant" + antArmy.length);
if (antArmy.length >= 50) antArmyFull = true;
}
document.getElementById('numOfAnts').innerHTML = 'Ant army size: ' + antArmy.length + '.';
moveAnt();
}
}
function releaseEat(posX, posY){ //конвеер еды
var x = posX;
var y = posY;
var placing = eatStock.length + 60;
while (eatStock.length <= placing) {
if (x >= posX+40) {
x = posX;
y++;
}
eatStock[eatStock.length] = new PlaceEat(eatStock.length, x, y);
x++;
}
eat = true;
}
///////////////////////ANT/////////////////////////
function MakeAnt(name) { //конструктор муравья
this.name = name;
this.antOnTheHunt = false;
this.targetEat = "";
this.antGrabEat = false;
var positionOfHome = document.getElementById("enterance");
var ant_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами
ant_div.setAttribute("id", name);
/* В качестве начальных координат используются координаты "Входа" */
ant_div.style.cssText="position:absolute;\
top:" + parseInt(positionOfHome.style.top, 10) +
";\left:" + parseInt(positionOfHome.style.left, 10) + ";";
var annt_canvas = ant_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами
annt_canvas.setAttribute("id", "a" + name);
var ant_canvas = document.getElementById("a" + name);//находим холст
var ant_context = ant_canvas.getContext("2d");//устанавливаем 2d рисование
ant_context.fillStyle = "#000000";//цвет заливки
ant_context.fillRect(0, 0, 1, 1);//создаем квадрат и заливаем
}
///////////////////////ANT MOVE////////////////////////
function moveAnt() { //управляющая выбором движения муравья функция
for (var i = 0; i < antArmy.length; i++) {
if (eat) checkEat(i);
if (!antArmy[i].antOnTheHunt && !antArmy[i].antGrabEat) {
checkMove(antArmy[i].name);
walkLikeADrunk(i); //хаотичное передвижение
}
if (exit) {
// if (!antArmy[i].antOnTheHunt) moveToTheExit(i); //Двигаться к выходу, если он существует
if (antArmy[i].antOnTheHunt && antArmy[i].antGrabEat) bringEatBack(i); //Двигаться с едой к выходу
}
if (antArmy[i].antOnTheHunt && !antArmy[i].antGrabEat) huntForEat(i); //охотится за едой
}
setTimeout("moveAnt()", 100)
}
function move(who,where,line) { //line === "left" or "top"
if (line === "left") document.getElementById(who).style.left=parseInt(document.getElementById(who).style.left)+where;
if (line === "top") document.getElementById(who).style.top=parseInt(document.getElementById(who).style.top)+where;
}
function walkLikeADrunk(id) {
var rand = Math.round(Math.random() * (4 - 1) + 1);
switch (rand) {
case 2:
move(antArmy[id].name, 1, "left");
break;
case 3:
move(antArmy[id].name, -1, "left");
break;
case 1:
move(antArmy[id].name, 1, "top");
break;
case 4:
move(antArmy[id].name, -1, "top");
break;
default:
alert("move ant error");
}
}
function huntForEat(id)
{
if (antArmy[id].targetEat !== "")
{
var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top");
var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left");
var AntPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntPosLeft = getElemCoordinates(antArmy[id].name,"left");
if (eatPosTop < AntPosTop) move(antArmy[id].name, -1, "top");
else move(antArmy[id].name, 1, "top");
if (eatPosLeft < AntPosLeft) move(antArmy[id].name, -1, "left");
else move(antArmy[id].name, 1, "left");
checkEatBorder(id);
}
}
function bringEatBack(id)
{
var AntCurrPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntCurrPosLeft = getElemCoordinates(antArmy[id].name,"left");
var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top");
var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left");
moveToTheExit(id);
var AntPastPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntPastPosLeft = getElemCoordinates(antArmy[id].name,"left");
if (AntPastPosTop <= AntCurrPosTop) eatPosTop = AntPastPosTop-1;
else eatPosTop = AntPastPosTop+1;
if (AntPastPosLeft <= AntCurrPosLeft) eatPosLeft = AntPastPosLeft-1;
else eatPosLeft = AntPastPosLeft+1;
document.getElementById(antArmy[id].targetEat).style.left=eatPosLeft;
document.getElementById(antArmy[id].targetEat).style.top=eatPosTop;
}
function checkMove(name) //Проверка движения муравья, относительно положения "Входа"
{ //Если муравей не на "охоте", то он не уходит за установленные границы
var AntPosCheckTop = getElemCoordinates(name,"top");
var AntPosCheckLeft = getElemCoordinates(name,"left");
var borderLineTop = getElemCoordinates("enterance","top");
var borderLineLeft = getElemCoordinates("enterance","left");
if ((borderLineTop < AntPosCheckTop) && (borderLineLeft < AntPosCheckLeft)) {
if (((borderLineLeft + 50) < AntPosCheckLeft) || ((borderLineTop + 50) < AntPosCheckTop)) {
if (borderLineTop < AntPosCheckTop) move(name, -1, "top");
if (borderLineLeft < AntPosCheckLeft) move(name, -1, "left");
}
}
if ((borderLineTop > AntPosCheckTop) && (borderLineLeft < AntPosCheckLeft)) {
if (((borderLineLeft + 50) < AntPosCheckLeft) || ((borderLineTop - 50) > AntPosCheckTop)) {
if (borderLineTop > AntPosCheckTop) move(name, 1, "top");
if (borderLineLeft < AntPosCheckLeft) move(name, -1, "left");
}
}
if ((borderLineTop > AntPosCheckTop) && (borderLineLeft > AntPosCheckLeft)) {
if (((borderLineLeft - 50) > AntPosCheckLeft) || ((borderLineTop - 50) > AntPosCheckTop)) {
if (borderLineTop > AntPosCheckTop) move(name, 1, "top");
if (borderLineLeft > AntPosCheckLeft) move(name, 1, "left");
}
}
if ((borderLineTop < AntPosCheckTop) && (borderLineLeft > AntPosCheckLeft)) {
if (((borderLineLeft - 50) > AntPosCheckLeft) || ((borderLineTop + 50) < AntPosCheckTop)) {
if (borderLineTop < AntPosCheckTop) move(name, -1, "top");
if (borderLineLeft > AntPosCheckLeft) move(name, 1, "left");
}
}
}
function checkExitBorder(id)
{
var AntPosCheckTop = getElemCoordinates(antArmy[id].name, "top"); //позиция муравья
var AntPosCheckLeft = getElemCoordinates(antArmy[id].name, "left");
var exitLineTop = getElemCoordinates("exit", "top"); //позиция выхода
var exitLineLeft = getElemCoordinates("exit", "left");
var startLineTop = getElemCoordinates("enterance", "top"); //позиция входа
var startLineLeft = getElemCoordinates("enterance", "left"); //это нам нужно что бы возвратить муравья
if ((exitLineTop <= AntPosCheckTop) && (exitLineLeft <= AntPosCheckLeft)) {
if (((exitLineLeft + 5) > AntPosCheckLeft) && ((exitLineTop + 5) > AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px";
}
}
if ((exitLineTop > AntPosCheckTop) && (exitLineLeft < AntPosCheckLeft)) {
if (((exitLineLeft + 5) > AntPosCheckLeft) && ((exitLineTop - 5) < AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px";
}
}
if ((exitLineTop >= AntPosCheckTop) && (exitLineLeft >= AntPosCheckLeft)) {
if (((exitLineLeft - 5) < AntPosCheckLeft) && ((exitLineTop - 5) < AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px";
}
}
if ((exitLineTop < AntPosCheckTop) && (exitLineLeft > AntPosCheckLeft)) {
if (((exitLineLeft - 5) < AntPosCheckLeft) && ((exitLineTop + 5) > AntPosCheckTop)) {
if (antArmy[id].antGrabEat) {
eatStock[antArmy[id].targetEat] = "returned";
antArmy[id].antOnTheHunt = false;
antArmy[id].antGrabEat = false;
}
document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px";
document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px";
}
}
}
function checkEatBorder(id)
{
var AntPosCheckTop = getElemCoordinates(antArmy[id].name,"top"); //позиция муравья
var AntPosCheckLeft = getElemCoordinates(antArmy[id].name,"left");
var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top");
var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left");
if ((eatPosTop <= AntPosCheckTop) && (eatPosLeft <= AntPosCheckLeft)) {
if (((eatPosLeft + 2) > AntPosCheckLeft) && ((eatPosTop + 2) > AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
if ((eatPosTop > AntPosCheckTop) && (eatPosLeft < AntPosCheckLeft)) {
if (((eatPosLeft + 2) > AntPosCheckLeft) && ((eatPosTop - 2) < AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
if ((eatPosTop >= AntPosCheckTop) && (eatPosLeft >= AntPosCheckLeft)) {
if (((eatPosLeft - 2) < AntPosCheckLeft) && ((eatPosTop - 2) < AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
if ((eatPosTop < AntPosCheckTop) && (eatPosLeft > AntPosCheckLeft)) {
if (((eatPosLeft - 2) < AntPosCheckLeft) && ((eatPosTop + 2) > AntPosCheckTop)) {
antArmy[id].antGrabEat = true;
eatStock[antArmy[id].targetEat].grabbed = true;
}
}
}
/*function checkEat(id) //Проверка на наличие еды
{
var bestTarget = "";
var t = Infinity,l = Infinity;
if (!antArmy[id].antOnTheHunt)
if (eatStock.length > storageCount) {
for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) {
if (eatStock[eatAll] != "returned")
if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) {
var AntPT = getElemCoordinates(antArmy[id].name, "top");
var AntPL = getElemCoordinates(antArmy[id].name, "left");
var eatPT = getElemCoordinates(eatStock[eatAll].name, "top");
var eatPL = getElemCoordinates(eatStock[eatAll].name, "left");
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l)) {
t = eatPT;
l = eatPL;
bestTarget = eatStock[eatAll].name;
}
}
}
}*/
function checkEat(id) //Проверка на наличие еды
{
if (!antArmy[id].antOnTheHunt)
if (eatStock.length > storageCount) {
for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) {
if (eatStock[eatAll] != "returned")
if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) {
antArmy[id].antOnTheHunt = true;
antArmy[id].targetEat = eatAll;
eatStock[eatAll].onTarget = true;
storageCount++;
break;
}
}
}
}
function moveToTheExit(id)
{
var exitPosTop = getElemCoordinates("exit","top");
var exitPosLeft = getElemCoordinates("exit","left");
var AntPosTop = getElemCoordinates(antArmy[id].name,"top");
var AntPosLeft = getElemCoordinates(antArmy[id].name,"left");
checkExitBorder(id);
if (exitPosTop < AntPosTop) move(antArmy[id].name, -1, "top");
else move(antArmy[id].name, 1, "top");
if (exitPosLeft < AntPosLeft) move(antArmy[id].name, -1, "left");
else move(antArmy[id].name, 1, "left");
}
function PlaceEat(eatid, posX, posY) { //конструктор еды
this.name = eatid;
this.onTarget = false;
this.grabbed = false;
var eat_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами
eat_div.setAttribute("id", eatid);
eat_div.style.cssText = "position:absolute;\
top:" + posY +
";\left:" + posX + ";";
var eaat_canvas = eat_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами
eaat_canvas.setAttribute("id", "eat" + eatid);
var eat_canvas = document.getElementById("eat" + eatid);//находим холст
var eat_context = eat_canvas.getContext("2d");//устанавливаем 2d рисование
eat_context.fillStyle = "#FFA500";//цвет заливки
eat_context.fillRect(0, 0, 1, 1);//создаем квадрат и заливаем
}
//Функция реагирования на "клик" пользователя.
//Если инструмент выбран...
document.addEventListener('click', function (e) {
if ((document.elementFromPoint(e.clientX, e.clientY).tagName) != "BUTTON") {
////////////////////ENTERANCE/////////////////////
if (enter_place === true) {
if (enter === false) {
var enter_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами
enter_div.setAttribute("id", "enterance");
enter_div.style.cssText="position:absolute;\
top:" + e.pageY +
";\left:" + e.pageX + ";";
var enteer_canvas = enter_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами
enteer_canvas.setAttribute("id", "e");
var enter_canvas = document.getElementById("e");//находим холст
var enter_context = enter_canvas.getContext("2d");//устанавливаем 2d рисование
enter_context.fillStyle = "#000080";//цвет заливки
enter_context.fillRect(0, 0, 10, 10);//создаем квадрат и заливаем
enter = true;
releaseAnt();
}
}
//////////////////EXIT////////////////////////
if (exit_place === true) {
if (exit === false) {
var exit_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами
exit_div.setAttribute("id", "exit");
exit_div.style.cssText="position:absolute;\
top:" + e.pageY +
";\left:" + e.pageX + ";";
var exiit_canvas = exit_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами
exiit_canvas.setAttribute("id", "ex");
var exit_canvas = document.getElementById("ex");//находим холст
var exit_context = exit_canvas.getContext("2d");//устанавливаем 2d рисование
exit_context.fillStyle = "#FF0000";//цвет заливки
exit_context.fillRect(0, 0, 10, 10);//создаем квадрат и заливаем
exit = true;
}
}
////////////////EAT////////////////////////
if (eat_place === true) {
releaseEat(e.pageX, e.pageY);
}
}
}, false);
function getElemCoordinates(name,side) //side = top/left
{
if (side === "top") return parseInt(document.getElementById(name).style.top, 10);
if (side === "left") return parseInt(document.getElementById(name).style.left, 10);
}
//Вызов elem.cloneNode(true) создаст «глубокую» копию элемента
//parentElem.removeChild(elem)
Ответ
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l))
Вы берете расстояние между муравьем и едой и сравниваете с абсолютными координатами другой еды, что в корне не верно.
Вам надо помнить САМО РАССТОЯНИЕ var t=Infinity;
...
if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < t)
{
t=(Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL);
....
}
Вопрос к разработчикам проектов по распознаванию образов. Как лучше организовать архитектуру подобного сервиса? Сейчас склоняюсь к решению использовать для работы с данными (а особенно для обучения) специализированные GPU-инстансы Amazon EC2 P2. На серверах установлено ПО только для работы искусственных нейронных сетей (Python, Anaconda, Keras, TensorFlow). В production-режиме сервер на вход принимает изображения с метаданными (как именно обработать изображение и какие данные вернуть), на выходе возвращает JSON-массив в зависимости от типа метаданных. Никакой особой логики там не хранится, вся аналитика происходит на серверах web-приложений. Обучающие и тестовые выборки хранятся в отдельном кластере (обычные сервера с большим дисковым пространством). Туда же загружаются изображения из сети найденные собственными поисковыми ботами (через соцсети и поисковые системы). Взаимодействие web-приложения с нейронной сетью осуществляется через API-запросы к GPU-серверам. Далее результат уже выдается на клиенты (аналогично с клиентов все идет на web-приложение, а затем на обработку в нейронную сеть). Теперь основные вопросы:
На каком участке вы проводите аналитику? (например, чтобы определить, что на фотографии на человеке надет синий мужской пиджак к нейронной сети выполняется каскад запросов "поиск мужчины"->"поиск пиджака"->"определение цвета пиджака". для получения более высокого качества ответа и снижения нагрузки на сеть каждый запрос выполняется отдельно при утвердительном предыдущем). Имеет ли смысл реализовывать все варианты поиска в рамках единой нейросети или лучше создать множество отдельных нейросетей, заточенных под достаточно простые задачи?
Как вы оптимизируете потребление ресурсов на этапах обучения и работы сети? Пока на уме только вариант с созданием специализированного GPU-кластера под обучение в рамках облачного хостинга и его периодическое включение по мере надобности (иначе дорого получается).
Ответ
Ваши вопросы говорят о том что, вы не осознаете всей сложности проблемы поиска мужчины на фото, не говоря уж о поиске пиджака. Хотя бы найти объект произвольного размера на фото по меркам на конец 2017 года - это уже передний край науки. Сначала начните с простого. Попытайтесь хотя бы в общих чертах решить вашу проблему, о которой ни слова в вопросе. Арендуете ли вы для этого один сервер, или купите подходящую видеокарту - дело второе. Можно и без видеокарт. Как только вы поймете что для радикального уменьшения ошибки обучения вам нужны годы на ваших мощностях, тогда можно будет говорить об аренде кластера. И тогда вы можете обратиться к документации на TensorFlow чтобы узнать как конкретно решаются подобные проблемы.
Я хочу построить регрессию с несколькими переменными (multiple features). В моих данных у меня n = 23 переменных и m = 13000 тренировочных примеров. Вот график моих тренировочных данных (площадь квартиры vs цена):
Здесь на графике отображены 13000 тренировочных данных. Как вы можете видеть, это достаточно шумные данные. Мой вопрос: какой алгоритм регрессии больше подходит и обоснован для использования в моем случае. Имею ввиду логично ли использовать простую линейную регрессию или лучше использовать какой-либо нелинейный алгоритм регрессии. Для наглядности приведу примеры.
Вот отвлеченный пример линейной регрессии:
А также отвлеченный пример нелинейной регрессии:
А вот примеры с гипотетическими линиями регрессии для моих данных:
Насколько я понимаю, примитивная линейная регрессия для моих данных произведет большую суммарную погрешность (error cost), так как эти данные шумные и разбросанные. С другой стороны, здесь также не прослеживается какой-либо отчетливой нелинейной зависимости (например синусоидальной). Какой алгоритм регрессии более рационально использовать в моем случае (цены на квартиры) для того чтобы получить более точное прогнозирование цен. И почему этот алгоритм (линейный или нелинейный) более рационален? Дополнение:
Вот так выглядит мой график линейной зависимости цены от всех 23 параметров:
Я не знаю, как бы выглядела НЕлинейная зависимость в таком случае. И была бы она более рациональна чем линейная.
Ответ
Для сравнения статистических моделей обычно используют информационные критерии, например, информационный критерий Акаике. Если вы пишете на R, то посмотрите функцию stepAIC - она позволяет упростить линейную модель, выкидывая из нее предикторы по одному, в порядке возрастания значимости для модели.
Если возможна, будет ли эта модель "настоящей" душой (то есть требуется ли для "настоящести" биологический мозг)? Если нет, верите ли вы в возможность научного исследования и описания невычислимого разума?
Ответ
Верю.
P.S. Аргументов нет, потому что категория верю/не верю не подразумевает аргументацию
Update
Придется аргументировать раз такая пьянка пошла :)
Вопрос на самом то деле упирается не в верю/не верю в модель разума, а в верю/не верю в душу. А душа есть субстанция с которой оперирует Господь. То есть все упирается в верю/не верю в Бога. Если душу можно смоделировать машиной, значит Бога нет. Если нельзя значит Бог есть. Путем несложным логических выкладок теперь можно легко убедиться кто в этой дискуссии верит в Бога, а кто атеист.
Структура вопроса следующая: сначала даю понятие о коллективном распознавании, далее объяснение разных методов коллективной классификации, которые я нашел и в конце я привожу свой вопрос. Кто уже съел собаку в этом деле и им возможно не требуется объяснять, что это такое и какие методы есть, может просто взглянуть на заголовки приведенных мною методов и перейти к вопросу.
Что такое коллективное распознавание/классификация Под коллективным (групповым) распознаванием подразумевается использование множества классификаторов, каждый из которых принимает решение о классе одной сущности, ситуации, образа с последующим объединением и согласованием решений отдельных классификаторов с помощью некоторого алгоритма. Использование множества классификаторов, как правило, приводит к более высокой точности распознавания и лучшим показателям вычислительной эффективности. Некоторые подходы объединения решений классификаторов:
основанные на понятии областей компетентности классификаторов и использовании процедур, позволяющих оценивать компетентность классификаторов по отношению к каждому входу системы классификации
методы объединении решений, основанные на применении нейронных сетей
Метод областей компетентности Идея коллективной классификации на базе областей компетентности в том, что каждый базовый классификатор может работать хорошо в некоторой области пространства признаков (область компетентности), превосходя в этой области остальные классификаторы по точности и достоверности решений. Область компетентности каждого базового классификатора должна как-то оцениваться. Соответствующая программа называется рефери. Задача классификации решается таким образом, что каждый алгоритм используется только в области своей компетентности, т.е. там, где он дает наилучшие результаты по сравнению с другими классификаторами. При этом в каждой области принимается во внимание решение только одного классификатора. Однако, необходимо иметь какой-то алгоритм, который для любого входа определяет, какой из классификаторов наиболее компетентен. Один из подходов предполагает, что вместе с каждым классификатором используется специальный алгоритм (рефери), который предназначен для оценки компетентности классификатора. Под компетентностью классификатора в данной области пространства представления объектов классификации понимается его точность, т.е. вероятность правильной классификации объектов, чье описание принадлежит этой области. Общая же схема обучения коллективному распознавания на основе оценки компетентности состоит из 2 шагов (рис. 1). На 1-м шаге производится обучение и тестирование каждого конкретного базового классификатора. Этот шаг не отличается от обычных схем обучения. На следующем шаге, после тестирования каждого классификатора, обучающая выборка, которая использовалась на этапе тестирования для некоторого классификатора, разделяется на два подмножества, L+ и L−. При этом в первое подмножество включаются те экземпляры исходной тестовой выборки, которые при тестировании были классифицированы правильно. Во второе подмножество включаются остальные экземпляры тестовой выборки, т.е. те, которые были классифицированы ошибочно. Рассматривая эти множества данных в качестве областей компетентности и некомпетентности классификатора соответственно, их можно использовать в качестве обучающих данных для обучения алгоритма «рефери». При классификации новых данных задача рефери состоит в том, чтобы для каждого входного примера определить, принадлежит ли он области компетентности алгоритма или нет, и если принадлежит, то какова вероятность правильной классификации этого примера. После этого рефери поручает наиболее компетентному классификатору решать задачу классификации.
Нейросетевые подходы. Нейросетевые подходы коллективной классификации делятся на методы, которые используют объединение классификаторов с помощью нейронной сети, ансамбли сетей (ensembles of neural networks) и те, которые используют нейронные сети, построенные из модулей. Нейросеть для объединения классификаторов Один из подходов, рассматривает использование нейронной сети для объединения решений базовых классификаторов (рис. 2).
Выходом каждого базового классификатора является вектор решений (вектор, содержащий в качестве значений мягкие метки), значения элементов которого принадлежат некоторому числовому интервалу [a, b]. Эти значения подаются на вход нейронной сети (она должна быть обучена объединению решений классификаторов базового уровня), выходом которой является решение в пользу того или иного класса. Выходом сети также может являться вектор, размерность которого равна количеству классов распознаваемых объектов, который на каждой позиции имеет значение некоторой меры доверия в пользу того или иного класса. В этом случае в качестве решения может быть выбран класс с максимальным значением такой меры. Система объединения решений функционирует следующим образом:
выбирается и обучается множество базовых классификаторов;
подготавливаются мета-данные для обучения нейронной сети. Для этого базовые классификаторы тестируются с использованием интерпретированной выборки данных и формируется для каждого тестового примера вектор решений базовых классификаторов, к которому добавляется компонента, в которую вносится имя истинного класса принадлежности тестированного примера;
выборка мета-данных используется для обучения нейронной сети, выполняющей объединение решений.
Метод модульных нейросетей Для модульных нейронных сетей предлагается использовать так называемую шлюзовую сеть (“gating network”), нейронную сеть для оценки компетентности классификаторов для конкретного входного вектора данных предъявляемых классификаторам. Этот вариант рассматривает нейросетевую парадигму для объединения решений на основе оценок компетентности. Соответствующая теория здесь называется mixture of experts — «смесь экспертов». Каждому классификатору ставится в соответствие программа «рефери», которая предсказывает степень его компетентности по отношению к конкретному входу, подаваемому на вход множества классификаторов базового уровня (рис. 3).
В зависимости от входного вектора Х решения различных классификаторов могут быть выбраны и использованы для принятия объединенного решения. Количество входов предсказывающей сети равно размерности входного вектора пространства признаков. Количество выходов сети равняется количеству классификаторов, т.е. L. Предсказывающая нейросеть обучается предсказывать меру компетентности каждого классификатора при предъявлении ей конкретного входного вектора, т.е. оценку того факта, что классификатор выдает правильное решение. Степень компетентности оценивается числом из интервала [0,1]
Ансамбли нейронных сетей Также, предлагается архитектура системы объединения решений, которая состоит из нескольких экспертов (нейросетей). Объединение знаний нейронных сетей в ансамбле доказало свою эффективность, продемонстрировав перспективность применения технологий коллективного распознавания в преодолении проблемы "хрупкости". Ансамбль нейронных сетей – это набор нейросетевых моделей, принимающий решение путем усреднения результатов работы отдельных моделей. В зависимости от того, как конструируется ансамбль, его использование позволяет решить одну из двух проблем: склонность базовой нейросетевой архитектуры к недообучению (эту проблему решает мета-алгоритм boosting), либо склонность базовой архитектуры к переобучению (мета-алгоритм bagging). Существуют различные универсальные схемы голосования, для которых победителем является класс:
максимальное – с максимальным откликом членов ансамбля;
усредняющее – с наибольшим средним откликом членов ансамбля;
большинством – с наибольшим числом голосов членов ансамбля.
Некоторые другие методы Существуют также такие ансамблевые алгоритмы машинного обучения как:
Random forest (заключающийся в использовании комитета (ансамбля) решающих деревьев)
Adaboost (алгоритм усиления классификаторов, путём объединения их в комитет, предложенный Йоавом Фройндом)
Мой вопрос Вопрос состоит в том, какую схему коллективного распознавания лучше использовать для распознавания символов/цифр/автономеров. Источники данных, с которых я брал информацию о различных схемах групповой классификации датируются 2006 годом и боюсь, что некоторые методы могли устареть. Какую схему будет более рационально использовать с точки зрения актуальности какого-либо метода. Мною были упомянуты следующие схемы:
на базе областей компетентности
на базе использования одной нейронной сети для объединения классификаторов
на базе использования модульной нейросети
на базе ансамблей нейронных сетей
комитетные методы Random forest и Adaboost
Какой из подходов в потенциале может выдать лучшие показатели точности и производительности в сфере распознавания символов/цифр/автономеров. Возможно, некоторые методы устарели или показали свою несостоятельность в определенных сферах. Возможно есть и другие более эффективные и актуальные методы коллективного распознавания (групповой классификации).
Источники с подробным описанием (оттуда я брал информацию о методах коллективного распознавания):
Методы и алгоритмы коллективного распознавания: Обзор (В. И.
Городецкий, 2006, pdf)
Актуальные вопросы использования сверточных нейронных сетей и их
комитетов в распознавании образов цифр (Кузьмицкий Н.Н., 2012, pdf)
Random forest (Wiki)
AdaBoost (Wiki)
Ответ
Данный ответ представляет собой микс перевода ответа пользователя D.W.♦ в этом вопросе на английском языке и ответов других экспертов StackExchange в моем вопросе в Cross Validated с похожей формулировкой.
Ответ пользователя D.W.♦ в этом вопросе
Современные методы для распознавания образов цифр не предполагают
использование коллективного распознавания, областей компетентности,
ансамблей или других алгоритмов упомянутых в вопросе.
Вместо этого, современные методы для распознавания цифр используют
сверточные нейронные сети. Только одну сверточную нейросеть: нет нужды
для использования нескольких CNN или каких-то других изощрений. Вместо
этого, акцент делается на конкретной архитектуре сверточной нейросети
(например, какое кол-во слоев, какой тип операции объединения
(pooling type) и на процедурах обучения (например, корректировка
коэффициента скорости обучения в методе стохастического градиента,
отсеве (dropout), «пакетной» нормализации (batch
normalization) и др.)
Насколько я знаю, это также является справедливым и для распознавания
объектов/символов.
Мой совет таков: хоть упомянутые в вопросе алгоритмы выглядят красиво
на бумаге, они на самом деле могут и не быть необходимы или полезны в
реальности для интересующих вас задач. Я не рекомендую использовать их
на практике.
Часть ответа Franck Dernoncourt в этом вопросе В одной из современных систем для классификации изображений получено ощутимое преимущество при использовании ансамбля (как и в большинстве других систем, насколько я знаю). Отражено в статье авторов He Kaiming, Xiangyu Zhang, Shaoqing Ren, и Jian Sun (эксперты Microsoft):
Deep residual learning for image recognition/Глубинное остаточное
обучение для классификации изображений (ENG, 2015, PDF)
В статье приведены таблицы:
Перевод: Таблица 4. Коэффициенты ошибок (%) в результатах с одиночными моделями (без ансамблей) на базе проверочного/контрольного множества (validation set) ImageNet.
Перевод: Таблица 5. Коэффициенты ошибок (%) в результатах с ансамблями. Top-5 error метрика на базе тестового множества ImageNet.
P.S. Top-5 error — метрика, в которой алгоритм может выдать 5 вариантов класса картинки и ошибка засчитывается, если среди всех этих вариантов нет правильного.
Заметка: объяснение о том, что такое top-1 error и top-5 error также дается здесь:
ImageNet: what is top-1 and top-5 error rate?
Команда MSRA c их моделью ResNets выиграли первое место на соревновании Large Scale Visual Recognition Challenge 2015 (ILSVRC2015)
Часть ответа пользователя jean в этом же вопросе
Предполагаю, что глубинное обучение достаточно актуально в
большинстве задач компьютерного зрения (распознавание,
обнаружение, получение сверхразрешения, выделение границ и т.д.) кроме
специфичных задач вроде SLAM, где глубинное обучение еще пока не
дотягивает до существующих методов.
Часто, чтобы получить некоторое процентное преимущество для победы в
соревнованиях по распознаванию, используют ансамбли и
усреднение. Но сети становятся настолько качественными, что это
уже не влияет так сильно на результаты.
Я бы сказал, что в течение 20 последующих лет, большинство продуктов
компьютерного зрения будет использовать глубинное обучение, даже в том
случае, если появится что-то более эффективное. Добавлю к ответу
Франка, что алгоритмы глубинного обучения меняются так быстро, что
ResNets от Kaiming He уже не являются наиболее актуальными
на данный момент. Сейчас на базе CIFAR, SVHN в свете софитов находятся:
- "Densely Connected Convolutional Networks/Плотно связанные сверточные сети" и
- SGDR: Stochastic Gradient Descent with Restarts/Метод стохастического градиента с перезапусками. Но даже эти
результаты скоро могут перестать быть актуальными на ближайшем
ILSVRC 2016