Как стать автором
Обновить

Комментарии 27

А что будет, если ввести маленький штраф за каждое действие, не вызвавшее потери ХП противника? Чтобы НН научилась спокойно выжидать

Можно. Это и правда отсеяло бы стратегии, основанные на применении оружия в качестве часов!

У живых соперников с живыми нейросетями (даже у диких животных) есть чувство времени и чувство расстояния и направления, ощущение усталости оценка выгоды от окружающего рельефа.
Можно было бы дать бойцам их аналоги вместе с уменьшением на 1/1000 хп за действия — это аналог усталости (и на 1/10 — за чрезмерное затягивание поединка обоими или одним из бойцов), организовать влияние рельефа на бой — тогда они могут начать ещё и маневрировать перед схваткой, чтобы занять стратегическую позицию.

Я хотел сделать как можно меньше костылей. Сделать, чтобы у нейросети были входные и выходные данные, и простая метрика качества. То, что вы описываете, реализуется само собой, если я дам нейросети память: некий набор переменных, в которые она может на одной ходу вести запись, а на другом — чтение. Я над этим думал, но решил, что сделаю так в каком-нибудь другом AI.
Поучение/нанесение урона надо делать с шансом < 100%. Иначе это не интеллект, а просто просчет ходов. А вот если вероятность нанесения/получения урона будет зависить от нескольких факторов, таких как растояние, сопротивление урону и т.д., вот тогда интереснее получится.
Просто просчёт ходов можно сделать независимо от того, детерминированы ли последствия, или вероятностны. Тупой просчёт ходов сложно реализовать из-за комбинаторного взрыва — если не ошибаюсь, лучшие из современных шахматных компов умеют считать всего на 7 ходов вперёд.

Вы ошибаетесь. Отдельные ветки и до сотни полуходов доходить могут.

А на семь полных ходов без отсечений и DeepBlue считать умела. Ей в этом году двадцать лет исполняется.

Опять же, перебор в современных шахматных движках не "тупой", а очень даже рафинированный, с огромным количеством улучшений и эвристик, придуманных поверх классической альфа-беты за последние 50 лет.

Хорошо. Может, тогда литературу порекомендуете по этой теме? То, что вы говорите звучит очень интересно.
Хорошей стартовой точкой будет https://chessprogramming.wikispaces.com
Там есть много статей, ссылок, примеров кода.
Спасибо!
Попробуйте применить генетический алгоритм для параметров оценки эффективности.
Штрафы/бонусы за нанесение урона, потерю здоровья, бездействие, использование конкретного действия.
У вас будет много нейросетей, которые по разному оценивают свои результаты.
Можно и их сражения проводить между друг другом, а не рукописными ботами.
Результаты оценивает не нейросеть, а оптимизатор. То есть тот самый генетический алгоритм. Вообще, конечно, можно сделать генетический алгоритм внутри генетического алгоритма — верхний уровень подбирает метрику качества для оптимизации разницы в хп, а нижний подбирает нейросеть для этой метрики. Сложно, но реализуемо.
А нельзя было использовать для данной задачи не нейросеть, а построение дерева вариантов для игры с полной информацией и последующими стандартными оптимизациями (минимакс, альфабета). Данная игра будет длится не более 35 ходов (которые чисто бег, нанесении ударов — меньше) что вроде бы вполне нормально для таких подсчётов.

P.S картинка из героев меча и магии 5?
В данном конкретном случае можно строить и дерево вариантов. Но это специализированное решение, а я хотел получить более-менее универсальное. Алгоритм, который может и машину водить, и в драться — и всё это с минимальными изменениями, и без риска комбинаторного взрыва.

Да, картинка из пятых героев.

Проблема универсальных алгоритмов в том, что они будут проигрывать специализированным решениям в каждой из областей. Т.е. и драться плохо, и машину водить так себе. Даже для нейросетей это верно — та машина, которая год назад обыграла в го Ли Седоля, совершенно непригодна для распознавания изображений. Причем эта непригодность — именно на уровне архитектуры (количество слоёв, свёрточная функция, всё такое).

Это известная проблема универсальных алгоритмов. У всего свои плюсы и свои минусы.
Плюс универсальных алгоритмов заключается в том, что их можно быстрее вводить в эксплуатацию. Это как с языками высокого уровня — один и тот же код можно написать и на ассемблере, и на Питоне. На ассемблере он будет работать существенно быстрее, но от Питона люди не отказываются.
Геймдизайн нравится.
отрицательная метрика не нравится. Ну сделайте ей это минус 100 в момент отправки в оптимизацию.
Но это костыльный подход если честно.
Ваша логика минусов мне кажется является причиной по которой осторожная стратегия выигрывает.
Если ничего не делать, у нас минус. Большой. Если что-то делать, то рискуешь получить минус.
Естественно у вас есть кривизна, сжимающая функция и все такое. Так что еще больше минуса логарифмически больнее чем удовольствие от победы.
Не разобравшись с этим начали убирать миролюбивое решение кучей костылей — смертью за пределами,
уменьшением размера арены, агрессивность.
Если я не прав, то все равно убрать бегство лучше более изящно.
По сути координаты юнитов имеют мало значения. Значение имеет только расстояние между ними.
Соответственно лучше вместо двух координат бойцов передавать только расстояние между ними.
И соответственно вместо ВПРАВО/ВЛЕВО сделать НАСТУПАТЬ/ПЯТИТЬСЯ.
Это немного упростит работу сети, ведь именно эта информация ей нужна из координат, и не нужно ее вычленять. Одинаковые по сути ситуации когда бойцы поменялись местами, но разные решения ВЛЕВО/ВПРАВО становятся одинаковыми. Ну и если вернуться к нашим баранам, к миролюбию — можно сделать что отступают медленнее. Допустим два ожидания если пятишься и одно если наступаешь. Ну или назад за ход 0.5 двигаемся, или еще как. Если нужны целые числа то увеличиваем всё на коэффициент.
==
Не уверен что правильно понял вашу схему обучения, но как я понял вы даете подтверждения уже после окончания всей партии? Обучение с учителем? Это как-то далековато от реальности, да и непрактично.
Давайте небольшое подкрепление после каждого хода — положительное если увеличился разрыв в ХП или отрицательное если уменьшилось. Ну а по результату игры давать большее подтверждение.
Да, еще хорошо бы передавать при ходе — сколько осталось ходов до конца. В текущей метрике оно мало что даст, но если за убийство давать бонус, то может быть полезным для агрессивности.
==
Идея небольшого минуса в результат за каждый ход (или микроскопический расход ХП) кроме стояния на месте — хорошая. Причем цена может быть разной. Выстрел это один вес, нож другой…
==
Вообще мне не очень нравится архитектура с детерминированным выбором самого весомого варианта.
Победитель забирает всё — не только в выборе решения, но и при обучении.
Сеть будет находить ЛОКАЛЬНЫЙ экстремум, но не глобальный, поймав локальный максимум она просто не будет иметь шанса за него выйти.
Хорошо бы выходы сети интерпретировались как вероятности.
Ну обучать конечно исходя их того кто сработал.
«Ваша логика минусов мне кажется является причиной по которой осторожная стратегия выигрывает.
Если ничего не делать, у нас минус. Большой. Если что-то делать, то рискуешь получить минус.» — AI обучается не так, как обучаются животные, на механике рефлексов, а так, как эволюция создаёт животных. До размножения допускают тот вариант стратегии, у которой выше метрика. А то, что метрика отрицательная — неважно.

«По сути координаты юнитов имеют мало значения. Значение имеет только расстояние между ними.
Соответственно лучше вместо двух координат бойцов передавать только расстояние между ними.
И соответственно вместо ВПРАВО/ВЛЕВО сделать НАСТУПАТЬ/ПЯТИТЬСЯ.» — это разумно.

«Ну и если вернуться к нашим баранам, к миролюбию — можно сделать что отступают медленнее» — тут я не очень согласен. Есть множество стратегий класса «hit & run». Я бы не хотел совсем запрещать отступать — только лишь запрещать убегать далеко и надолго.

«Не уверен что правильно понял вашу схему обучения, но как я понял вы даете подтверждения уже после окончания всей партии?» — да.
«Обучение с учителем?» — нет, так как нет никаких «правильных ответов», известных учителю.
«Это как-то далековато от реальности, да и непрактично.» — эволюция работает именно так. Важно лишь, насколько частыми будут гены данного организма в популяции через несколько поколений, а остальное неважно. Насчёт непрактичности — данная схема обучения позволяет максимизировать выигрыш на момент конца партии. Схема «даём подкрепление каждый ход» называется Q-Learning и не очень хорошо работает, если надо вначале 20 ходов жертвовать своей функцией полезности, а потом в 1 ход всех победить. У Q-Learning свои плюсы, у перебора стратегий свои.

«Да, еще хорошо бы передавать при ходе — сколько осталось ходов до конца» — я пробовал. В этом случае AI сильно привязывается к этим числам, и становится склонным делать не гибкий алгоритм, а циклограмму — то есть он действует не по обстоятельствам, а по расписанию. По идее, такое вырождение в циклограмму произойдёт необязательно, так что идея разумная.

«Сеть будет находить ЛОКАЛЬНЫЙ экстремум, но не глобальный, поймав локальный максимум она просто не будет иметь шанса за него выйти.» — в задаче оптимизации в общем случае мы не можем знать, в локальном мы экстремуме застряли, или в глобальном. Поэтому на глобальный я бы вообще не рассчитывал. Застревание в локальных оптимумах и правда есть, но оптимизатор из них до определённого момента успешно выбирается. Я в основном использую негладкие методы оптимизации типа эволюции и пчелиного роя.

«Вообще мне не очень нравится архитектура с детерминированным выбором самого весомого варианта.» — я согласен, что такая архитектура склонна к застреванию. Но интерпретировать выходы как вероятности довольно сложно.
Есть 3 способа это сделать:
1) Допустим, идёт бой. Нейросеть вывела: 0, 0, 0.3, 0.7, 0, 0.
Дальше делаем fork и в 3 потоках нейросеть выполняет действие '3', а с 7 потоках действие '4'. Это ведёт к комбинаторному взрыву.
2) Идёт бой. Нейросеть вывела: 0, 0, 0.3, 0.7, 0, 0. С вероятностью 0.3 выполняем действие '3', с 0.7 — действие '4'. И оказывается, что при одних и тех же входных данных нейросеть выдаёт разное качество в разных случаях. В таком случае для её оптимизации уже не подойдут никакие алгоритмы, кроме эволюции.
3) Делаем так же, как в пункте 2, но каждое испытание проводим по многу раз — чтобы снизить недетерминированность метрики качества, вызванную рандомом. То есть мы в 70 случаях выбрали одно действие, и получили q=-60, а в 30 случаях — другое, и получили q=-100. В среднем будет получаться -72, и дисперсия будет небольшой. Тогда не-эволюционные стратегии оптимизации может быть, будут работать. Но для воплощения этого метода нам понадобится проводить очень большое количество боёв, что займёт много времени.
AI обучается не так, как обучаются животные, на механике рефлексов, а так, как эволюция создаёт животных. До размножения допускают тот вариант стратегии, у которой выше метрика. А то, что метрика отрицательная — неважно.

А к чему это, я не понял? У вас нейросеть? Значит есть сжимающая функция.
Сжимающая функция нелинейная. Не важно что это за функция. Важно что она нелинейная.
Какие гены, какие важно/неважно? У вас всё смешалось, и люди, и кони.
Если нейросеть, то рассуждения о генах и т.п. не имеют смысла.
«не важно» это конечно хорошо, но почему-то ведь ваш хак с минусами работает? Значит таки важно?
Я предположил причину откуда это могло взяться, и вы мне ответили в терминах эволюции, которая не относится к нейросетям, и не объясняет этот артефакт.
эволюция работает именно так. Важно лишь, насколько частыми будут гены данного организма в популяции через несколько поколений, а остальное неважно.

Какая эволюция? У вас нейросеть. Опять что-то не в тему.
Насчёт непрактичности — данная схема обучения позволяет максимизировать выигрыш на момент конца партии. Схема «даём подкрепление каждый ход» называется Q-Learning и не очень хорошо работает, если надо вначале 20 ходов жертвовать своей функцией полезности, а потом в 1 ход всех победить. У Q-Learning свои плюсы, у перебора стратегий свои.

На самом деле нет. Обе стратегии ищут локальный максимум.
Просто пошаговое подтверждение находит его быстрее, но да, более локальный.
Надо давать подтверждения И пошагово, и после победы/поражения, давая за гибель/победу больше бонус чем за уроны. Но то такое, я так понимаю что если вы путаете нейросети и генетику, то свою логику нейронов не потянете, так что замнем для ясности.
я пробовал. В этом случае AI сильно привязывается к этим числам, и становится склонным делать не гибкий алгоритм, а циклограмму — то есть он действует не по обстоятельствам, а по расписанию. По идее, такое вырождение в циклограмму произойдёт необязательно, так что идея разумная.

Вот тут надо смотреть почему у вас столько артефактов выползает. Уже не первый ведь.
Если циклограмма оптимальнее, то почему бы и не использовать ее? Вы ведь сами максимально детерминированный алгоритм хотите. Тут изучать надо, но скорее всего такой артефакт или от того что сети не хватает степеней свободы (мало нейронов и/или слоев, вырожденная топология сети и т.п.), или что более весомо — слишком детерминированная входная выборка боев. У вас фиксированный набор ваших поведений, у противника тоже шаблонное поведение, вот он и выхватывает несколько циклограмм. Больше разнообразия в противниках, в их поведении, изначальных позициях и т.п. должно уменьшить пользу циклограмм. А так то вообще это частая проблема нейросетей и прочих AI — сеть обучается не на тот признак что мы хотели, а на сопутствующий. Типа не собаку узнает а траву на ее фоне.
Я в основном использую негладкие методы оптимизации типа эволюции и пчелиного роя.

Стоп. Давайте определимся в терминах.
У вас не нейросеть, а что-то сетиподобное?
Основное свойство нейросетей в их атомарности. Каждый нейрон независим, его обучение и работа идет исключительно из тех данных что он получает на вход.
Что дает колосальную масштабируемость на реальных задачах.
У вас же как я понимаю расчет весов идет оптимизацией матрицы весов, причем не каждого нейрона отдельно а всей сети целиком?
Тогда в принципе понятно почему с одной стороны сеть показывает хорошую разрешающую способность при небольшом размере сети, с малым запасом, с другой стороны сильно ловит локальные экстремумы.
Нет, такие «ненастоящие» сети иногда называют нейросетями, но очень многие свойства нейросетей теряются.
И оказывается, что при одних и тех же входных данных нейросеть выдаёт разное качество в разных случаях. В таком случае для её оптимизации уже не подойдут никакие алгоритмы, кроме эволюции.

Мощь нейросетей проявляется в том числе и в том что они хорошо работают на простых алгоритмах.
Всегда когда хочу пристроить какой-то нестандартный алгоритм к НС, я представляю себе сеть из нескольких миллиардов нейронов работающую по моему алгоритму. Реализованную аппаратно.
Низкая связность, по возможности stateless. Таскать с собой большую таблицу прошлых образов и иметь доступ к чужим коэффициентам — дорого. Неимоверно дорого.
А всякие градиентные спуски и прочие вещи пригодные в таких условиях будут легко воспринимать недетерминированный контекст. Для них это родная стихия). Для оптимизации отдельного нейрона недетерминированность проблем не вызовет — главное что в среднем оно выходит предсказуемо.
Но для воплощения этого метода нам понадобится проводить очень большое количество боёв, что займёт много времени.

Вы их и так проводите. Только виртуально, внутри ваших оптимизаторов.
А логика НС подразумевает проводить их вживую, на сети.
«У вас же как я понимаю расчет весов идет оптимизацией матрицы весов, причем не каждого нейрона отдельно а всей сети целиком?» — да, именно. Я применяю обычные методы оптимизации (эволюцию, градиентный спуск и прочее) к весам и сдвигам нейросети. Никакого обучения на примерах здесь нет. И с учётом этого факта градиентный спуск при недетерминированном поведении сетки не будет вести к экстремуму.
Мой алгоритм эмулирует скорее не обучение готового мозга («Надо давать подтверждения И пошагово, и после победы/поражения, давая за гибель/победу больше бонус чем за уроны»), а подбор генокода, создающего мозг.
Обучение каждого нейрона независимо от других у меня и правда не производится.

«У вас фиксированный набор ваших поведений, у противника тоже шаблонное поведение, вот он и выхватывает несколько циклограмм. Больше разнообразия в противниках, в их поведении, изначальных позициях и т.п. должно уменьшить пользу циклограмм. А так то вообще это частая проблема нейросетей и прочих AI — сеть обучается не на тот признак что мы хотели, а на сопутствующий. » — пожалуй, так и правда можно было бы добиться лучшей стратегии. Имеет смысл проводить больше различающихся боёв, но всё равно никакого рандома внутри самой системы выбора ходов.

"«не важно» это конечно хорошо, но почему-то ведь ваш хак с минусами работает? Значит таки важно?" — мой хак с минусами работает потому, что мой оптимизатор (не нейросеть) изначально создавался как инструмент для подбора коэффициентов регрессий. Поэтому он считает, что выходное значение оптимизируемой функции — это mse или mae или ещё какая-нибудь метрика ошибки, которую надо приблизить к нулю. Поэтому у меня варианты — либо переписывать оптимизатор (который довольно большой, относительно эффективный и более-менее универсальный), либо как-то преобразовывать метрику. Оптимизатору не важно, улучшать ли метрику с -100 до -90, или с -10 до 0. Ему только важно, чтобы выше 0 ничего не поднималось.

Вроде на всё ответил? Да, у меня необычная система, и это «ненастоящая нейросеть» в вашей терминологии.

Я правильно понимаю, что вы знаете какие-то лучшие алгоритмы для создания оптимальной стратегии, чем то, что я предложил? Что-то из серии reinforcement learning, но не Q-learning? Если это так, не могли бы вы поделиться материалами по теме?
И с учётом этого факта градиентный спуск при недетерминированном поведении сетки не будет вести к экстремуму.

Почему не будет? Картинка у каждого отдельного нейрона будет более-менее стабильная.
Градиентный спуск это алгоритм малых приращений. Родственный ему — фильтр калмана, как раз для сглаживания таких недетерминированностей и используется. (Кстати в обучении без учителя он тоже используется).
Имеет смысл проводить больше различающихся боёв, но всё равно никакого рандома внутри самой системы выбора ходов.

Рандом в AI это сложная вещь, можно отстрелить себе ногу. Так что тут я не настаиваю. А с разнообразием поведения оппонентов поработать стоит однозначно.
Оптимизатору не важно, улучшать ли метрику с -100 до -90, или с -10 до 0. Ему только важно, чтобы выше 0 ничего не поднималось.

Не уверен что всё так просто. Наверняка у вас там есть нелинейность. Ну хоть метод средних квадратов, хоть еще что, не суть. И они дают то, что изменение от -100 до -101 (равное одному баллу) для оптимизатора «важнее» чем изменение между -100 и -99 (тоже один балл).
Чудес не бывает, у каждого артефакта есть свой математический бекграунд.
Если это так, не могли бы вы поделиться материалами по теме?

Материалов нет. AI сейчас не в приоритете, читаю, но всё чисто теория и в голове. Времени на всё это не хватает.

++
Есть такая штука как эпсилон жадная стратегия: сеть выбирает любое действие с малой вероятностью эпсилон, а в остальных случаях аргмакс из ответов сети. В DQN такая стратегия работает лучше, чем выбор пропорционально величине ответа сети.
Это на обучении, а на тесте конечно надо оптимально действовать.

Это приём хорошо работает в случае обучения типа q-learning, а в обучении типа «перебор стратегий» этот приём не прокатит. Потому что оцениваются не действия, а стратегии.
Вопрос к автору: был ли у нейросети некий аналог памяти (учитывала ли она в качестве одного из признаков своё предыдущее действие)? Учёт предыдущего действия позволил бы нейросети разучивать эффективные комбинации ударов. И в целом (возможно я пропустил описание в статье) какие именно признаки учитывала нейросеть?
Возможно, было бы полезным учитывать не только своё предыдущее действие, но и вообще все признаки со сдвигом во времени?
А статья очень интересная, пожалуй тоже поэксперементирую с аналогичными нейросетями.
«был ли у нейросети некий аналог памяти» — нет. Хотя местами она была бы полезна.
«какие именно признаки учитывала нейросеть»- на вход каждому бойцу поступает информация: x, hp и состояние отравлен/не отравлен о себе и о своём противнике. Кроме того, поступает значение cooldown противника.

«Возможно, было бы полезным учитывать не только своё предыдущее действие, но и вообще все признаки со сдвигом во времени» — это позволило бы узнать, скоро ли конец игры и какая стратегия у противника. И всё. В общем-то это полезно, но я решил пока не заморачиваться.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории