dev optozorax @optozorax_dev Channel on Telegram

dev optozorax

@optozorax_dev


Дневник программирования: компьютерная графика, порталы, клавиатуры, QMK, парсеры, компьютерная алгебра.

ЯП: Rust.

98% контента делаю сам, редко репосчу.

Автор: @optozorax
Сайт: optozorax.github.io

dev optozorax (Russian)

Добро пожаловать в канал dev optozorax! Здесь вы найдете увлекательный дневник программирования, посвященный компьютерной графике, порталам, клавиатурам, QMK, парсерам и компьютерной алгебре. Язык программирования, который используется в канале, - Rust. 98% контента создается лично автором канала @optozorax, и редко появляются репосты. Автор канала делится своими знаниями и опытом в области программирования. Чтобы узнать больше о нем, вы можете посетить его сайт: optozorax.github.io. Присоединяйтесь к каналу, чтобы быть в курсе последних новостей и обсуждений в мире программирования!

dev optozorax

15 Nov, 08:04


Я увольняюсь с работы и становлюсь ютубером на full time

В этот раз по-настоящему, сегодня мой последний рабочий день на работе.

Как говорится в каждой шутке есть доля правды))) 1 апреля я не был уверен что действительно так поступлю, но за прошедшее время мне удалось решить множество проблем, препятствовавших этому решению, и появилось сильно больше уверенности и понимания. А ещё по работе я закончил свой большой проект, вот буквально вчера всё сошлось на 100%, так что ухожу с чистой душой)

Поэтому ждите! Будут видосы и по порталам, и по машинкам/эволюции, и много чего ещё!

dev optozorax

10 Nov, 18:56


Смена парадигмы в обучении #машинки

Итак, мои машинки вообще не могут обучаться сразу со сложной физики, поэтому я выдумывал всякое обучение с простой физики и дальнейшее дообучение на сложную. Но тут я нашёл невероятный метод, который может научиться всему, сразу со сложной физики!

Давайте начнём по порядку, у моей машинки нет памяти, нет знания о своих прошлых намерениях, нет рекуррентных нейронов, в общем для неё каждый кадр - как новая жизнь, с нуля. Это потому что она обычная нейросетка с Dense слоями. Она получает на вход текущее зрение, своё внутреннее состояние и ей нужно предсказать следующее действие в виде: насколько повернуть направо, насколько повернуть налево, насколько сильно сделать газ, насколько сильно тормозить. Ещё это называют задачей регрессии. Для задачи регрессии нейронка обучалась плохо, это красный график. Ну и у во всех моих прошлых постах всегда была именно задача регрессии.

Давайте попробуем задачу классификации? Возьмём 9 самых популярных действий и будем просить нейронку выбрать одно действие, то есть будет 9 выходных нейронов, и будет выбираться то действие, на котором находится максимальное число. Это зелёный график. Уже работает получше, но всё ещё не сходится к решению. Наверное здесь мораль в том, что делать классификацию чуток проще, чем регрессию.

Следующая задача - это задача скоринга. Скорее всего про такое вы не слышали. В этой задаче у нас есть нейронка, которая принимает на вход текущее состояние и предполагаемое действие, а на выход выдаёт 1 (одно) число. Далее мы перебираем среди наших 9 действий и выбираем то, у которого нейронка вернула самое большое число. В науке это называется Energy-based model, потому что это число называют энергией, и выбор оптимального действия на основе энергии называют "оптимизацией энергии". Может быть слышали есть такая JEPA у Яна ЛеКуна? Вот это оно. ЛеКун много писал в твиттере что это самая лучшая архитектура, в том числе и для генерации текста, чем регрессионные трансформеры, потому что почувствовать какой текст правильный намного проще, чем сгенерировать его сразу.

Я давно намотал это на ус и вот только недавно решил проверить его слова, и результат вы можете видеть на графике оранжевым цветом: ОНО РАБОТАЕТ ОФИГЕННО. Понимаете, эта нейронка всего за 200 поколений научилась проходить все трассы, с нулевым штрафом, без всяких ухищрений в виде простой физики, сразу со сложной физики, просто так! НАКОНЕЦ-ТО! Настоящая смена парадигмы.

Ещё вы можете видеть там синий график, это моя первоначальная версия, когда я для каждого действия симулировал мир на 1 шаг с этим дейстивем и подавал ещё и это на вход нейронке. Я думал что без хорошей модели мира это работать не будет, но это оказалось не нужно, оно даже не даёт ничего полезного.

Ещё там есть фиолетовый график, в нём выбирается не максимальное число, а самое близкое к нулю. Была идея в том что так нейронка может закодировать производную и тогда это типо должно легче обучаться. Но на самом деле нет.

В общем я очень очень рад новой парадигме, чувствую себя каким-то первооткрывателем, ибо вот никогда такого не видел для задачи обучения агентов! Теперь всё буду пробовать формулировать в виде energy-based model, может обучение будет сильно проще! Если у вас есть идеи какие подходы можно попробовать - пишите!

PS: Вот почему я в самом начале отказался от вашего дурацкого Reinforcement Learning и выбрал генетические алгоритмы, потому что вы можете себе представить чтобы я такой же эксперимент проводил с RL? Да я бы никогда это не сделал, у меня бы ни ума, ни времени, ни компьюта бы не хватило, чтобы обучить Energy-based model через RL. Они поэтому и не заслужили такую популярность, потому что их хрен обучишь. А для генетического алгоритма я это накодил за полчаса, и во время обучения ему хоть бы хны. Это называется СВОБОДА.

dev optozorax

09 Nov, 15:49


Уважаемые подписчики, а какой у вас процессор? Можете запустить мой бенчмарк?

Я просто думаю насчёт апгрейда компа (а то на нём железо 2014 года), и вот присматриваюсь к разным процессорам. Особенно интересен AMD Ryzen 9 9950X и новый Mac mini на M4 (если он хоть у кого-то есть).

Просто мои эксперименты я запускаю именно на процессоре, на видеокарту очень лень переписывать, и вряд ли оно будет там работать. Арендую 80-ядерный комп на время экспериментов.

Вот ссылка на бенчмарк: https://github.com/optozorax/car_drift/tree/8fbfd0f82f614d9d32bbf78176b77e98affdadcb (скомпилировать через Rust (rust-lang.org) и запустить cargo run --release, если вы не программист, то не парьтесь), можете почитать код, там ничего опасного не делается: запускается функция с эволюцией, а там 10 эволюций параллельно, в 30 поколений, ничего серьёзного, компиляция дольше займёт. Самое главное что там всё максимально распараллеливается и утилизируются все ядра, поэтому не важно 80 ядер у вас или 4.

Результаты бенчмарка:
* Мой домашний комп - 186с
* Арендуемый 80-ядерный сервер: 18.5с
* M3 Max (16-ядерный): 19.8с

Кидайте пожалуйста в комменты скриншоты вывода (там пишется время), ваш процессор и сколько у него ядер.

UPD: Всем большое спасибо! Можно больше не замерять. Пока выглядит так что я хочу AMD 9950, потому что 7950 уже работает быстрее всего что я видел.

dev optozorax

19 Oct, 21:40


Я обучил нейронку, способную ездить при любых физических условиях.

(в видео есть звук, но лучше сначала прочитать пост)

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

В этот раз взял такую нейронку: видит разницу между прошлой картинкой, один скрытый слой с 10 нейронами, функция ReLU, 3 RNN нейронов, знает номер текущего трека, угол обзора 180 градусов, итого 790 чисел в нейронке. Не то, чтобы всё это было категорически необходимо для хорошего обучения, но если уж начал обучать нейронку, то к делу нужно подходить серьёзно. А именно такие параметры подобрал через муторные сравнения 100 запусков с построением кучи графиков.

Как видно из прошлого поста, обучение нейронки с нуля таким образом работало плохо. Ещё хуже работало после добавления разных физических условий. Поэтому я пошёл по старому пути: сначала запускаю обучение на простой физике, она доходит до идеального состояния, когда ноль врезаний и все трассы проходит быстро. Затем постепенно усложняю физику и затем ещё 100 поколений на сложной физике.

После этого этапа включаю обучение сразу по множеству сложностей физики: простая физика + сложная физика + промежуточные между ними. Ещё 100 поколений. Идёт долго, но хорошо, по всем фронтам у машинки получается сходиться к нулевому числу врезаний и быстро проходить трассы.

И вот после этого добавляю к прошлому ещё разные физические условия на 100 поколений, но все физические условия запускаются только на сложной физике, поэтому оставляю ещё простую и промежуточные, чтобы она это не забывала.

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

И вот я получил нейронку, которая на каждой трассе врезается либо 1 раз, либо чаще вообще не врезается; умеет ездить при разной сложности физики, и при разных условиях сложной физики. Считаю это вполне хорошим майлстоуном и наверное можно чуток успокоиться с проектом, а то делаю его 24/7 в свободное время)))

К сожалению машинка всё ещё ездит медленней меня, и мне ещё ни разу не удавалось получить машинку быстрее. Не знаю почему так происходит, что-то я точно упускаю. Думаю это будем моим следующим фокусом к исследованиям.

#машинки

dev optozorax

19 Oct, 19:19


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

Конечно, чтобы это работало, я подаю нейронке на вход не только текущую картинку, но ещё и разницу между предыдущей и текущей! Чтобы она могла хоть как-то чувствовать различия в физике. А то есть подозрение что никак не обучится, у неё ведь нет памяти, и она не RNN.

Попробовал, и это на самом деле работает (но обучается в 5 раз дольше, так как все трассы проезжаются с разной степенью простой физики). Вот только работает не так хорошо, как хотелось бы: оно учится ездить трасы лучше, чем просто на ванильной сложной физике, но всё-равно делает это слишком долго и итоговый штраф ударов об стену никак не может опустить до 0. Идёт где-то 5 ударов за трассу и всё.

А жаль, тоже был перспективный подход.

#машинки

dev optozorax

13 Oct, 13:14


Теперь я научился почти гарантированно обучать нейронку управлять машинкой при сложной физике. Ради чего я и написал два прошлых поста.

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

Ну и я начал исследовать как же добиться того чтобы можно было начинать обучение с простой физики, а заканчивать сложной. Сравнил три разных подхода:
1. Начинать обучение сразу со сложной физики (x = 0.0).
2. Встроить сложность физики в параметр оптимизации и давать очень большую награду за его увеличение.
3. Начинать с простой (x = 1.0), а потом постепенно увеличивать сложность в цикле (x -= 0.02).

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

Второй вариант изображён зелёным цветом, и его суть в том что сложность физики эволюционируется рядом с параметрами нейросети, и награда за сложную физику даётся очень большая, больше чем прохождение конкретных уровней. Сделал награду такой: если все трассы пройдены, то давать награду за сложность физики, иначе штрафовать за сложность физики, чтобы она была максимально простой. Идея была в том что сначала нейронка обучается проходить все трассы на простой физике, и только как этого достигает, она начинает проходить по сложной физике, причём ей запрещено разучиваться проходить хотя бы одну трассу, иначе она теряет очень много награды.

Этот вариант был самым перспективным, и как мне казалось, гениальным. Я думал что смогу просто встроить в метрику любые подобные параметры, и не надо будет писать ручные циклы, а можно будет делать всё в рамках одного обучения. Но как оказалось, это обучалось очень плохо, доходило до простоты физики около 0.2, и дальше никак не эволюционировало. Как я посмотрел, машинка стала вилять, и из-за медленного прохождения трассы ей перестало хватать квоты на число шагов и поэтому она не могла дальше уменьшать простоту физики, ведь у неё есть требование что все трассы должны проходиться.

Я перепробовал очень много модификаций к этой идее, но ничего не смогло заставить её нормально сходиться.

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

Ну и третий вариант, изображён красным цветом, самый тупой: сначала тупо запускаем 100 поколений эволюции на простой физике, затем усложняем физику с шагом 0.02, и эволюционируем максимум 10 поколений, или пока новый скор не будет больше или равен старому. Затем снова эволюционируем 100 поколений чтобы машикна стала лучше ездить.

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

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

Пока у меня гипотеза что основной компьют тратится на обучение зрения, поэтому простая физика так легко дообучается до сложной, поэтому здесь есть идея добавить автокодировщик на зрение. Может тогда стабильность улучшится.

#машинки

dev optozorax

13 Oct, 01:57


А в чём её идея? Да в том что если машинка научилась проходить какую-то трассу, то ей невыгодно уже перестать уметь её проходить, потому что никакое изменение штрафа и раннего финиша не смогут дать ей такую награду, как пройденная трасса. Плюс, помимо такой дискретной составляющей у неё есть непрерывная - пройденное расстояние на трассе, и она может постепенно увеличивать это число, пока в какой-то момент оно не превратится в +1.

Прикрепляю график. Значит что на нём значит:
* Цветное - это новая метрика, а серый - старая.
* Первая строка - индивидуальные запуски, там ничего особо полезного.
* Вторая строка - тоже особо ничего полезного.
* Третья строка - график слева показывает число пройденных трасс, сплошная линия - новая метрика, пунктирная - старая. Самое-самое главное что новая метрика в большем % случаев проходит больше трасс, особенно смотрите на розовую трассу complex - самую сложную трассу (она участвует в гифках в прошлых постах).
* Затем идёт Early finish - это значит насколько быстро пройдена трасса, берётся среднее от всех трасс и рисуется здесь.
* Четвёртая строка - штрафы за удары в стену, первый график - среднее от всех трасс, второй график - максимальное среди всех трасс.
* Пятая строка - среднее пройденное расстояние и минимальное пройденное расстояние.

Сплошная линия показывает медиану, первая закрашенная область показывает значения между 25 и 75 перцентилями, а очень слабо закрашенная область показывает между 10 и 90 перцентилями. Напоминаю, что это 100 разных запусков обучения, и широта области показывает что в этом месте обучение оч нестабильно, и при разных запусках сходится к разной величине.

По графику в первую очередь видно что в среднем стало проходиться больше трас, они в среднем проходятся быстрее. Но вот меньше ударов в стену было у прошлой метрики, но это довольно старый график, я это уже как-то пофиксил, и новая метрика щас вообще очень хорошо по штрафу идёт, практически возле нуля.

(и да, представляете, я отсмотрел и проанализировал минимум 199 таких графиков...)

Ах да, забыл сказать, я называю эту метрику "уровни". Можно её делать многоуровневой, типо на втором уровне я щас экспериментирую с штрафами (три уровня: штраф < 15, штраф < 5, штраф = 0).

Очень горжусь этой метрикой и рад что её нашёл, с ней обучение реально стало лучше.

На самом деле эти два поста - вводная к следующему (тот самый достойный момент), но чот слишком много написал уже, завтра опубликую 😜, а вы пока читайте это.

#машинки

dev optozorax

13 Oct, 01:57


С момента прошлого поста про обучение машинок случилось ОЧЕНЬ много прогресса, о котором я тут не писал, потому что он был черновой, и не готовый к публикации, но вот наконец я достиг той точки, которая достойна.

В прошлом посте я сказал что мне удалось научить машинку ездить через изменение простоты физики - от простой к сложной.

Но когда я начал экспериментировать с разными параметрами нейросети, машинка не обучилась снова ездить. Вернул параметры обратно, а она снова не обучилась. Оказалось что моё обучение очень нестабильно, и в тот раз мне просто очень повезло. И его нифига нельзя использовать для дальнейших экспериментов. Поэтому я погрузился в кроличью нору исследования того как можно улучшить моё обучение, чтобы оно было быстрее и стабильнее. Я сделал следующее:
* Все параметры обучения вынес в тип конфига, чтобы всё что угодно можно было включать/выключать и настраивать числа
* Каждое обучения запускаю по 30-100 раз
* Сохраняю всю инфу в json файлики
* С помощью скрипта на python визуализирую графиками среднее и отклонение от среднего
* Мой компьютер слабенький, поэтому я арендовал сервак с 80 ядрами (!!!) и запускал все эксперименты на нём, нагружая все 80 ядер

Такое огромное число запусков нужно как раз из-за нестабильности обучения, чтобы на среднем видеть тренд, какое изменение в обучении реально влияет на него, а какое нет.

И так я проделал для каждого изменения в метрике обучения, я анализировал всё:
* величину штрафа за врезание в стену
* добавление случайного числа к ответу нейросети
* отключение и включение разных трасс
* изменение разных наград
* алгоритм оптимизации (!) (лучший - cma-es)
* итд итд...

Щас подсчитал все картинки что у меня лежат, и их ровно 199! То есть я провёл не менее 199 экспериментов с машинками, и у меня лежат гигабайты этих json файликов...

И после всего этого я выяснил самую эффективную метрику, которая влияет на скорость и стабильность обучения сильнее, чем все мои другие изменения что я вносил. Но сначала расскажу про прошлую метрику.

Раньше я делал так: машинка проезжала N трасс, и для каждой трассы я суммировал: пройденное расстояние + завершилась ли трасса + как быстро машинка её проехала + минус штраф за удары в стену, всё это с какими-то коэффициентами, а затем суммировал все эти числа в одно число, и старался его максимизировать (чтобы машинка старалась проходить трассы, увеличивать расстояние, а ещё чтобы меньше старалась врезаться, так как это уменьшает итоговое число). Звучит логично, да. Но на самом деле это довольно плохая метрика, так как она разменивает удары об стену на скорость прохождения. И она не стремится проходить все трассы, так как быстрое прохождение по очень простой трассе даст ей столько же очков как и медленное прохождение сложной трассы. А так как она не знает какую трассу проходит, то выбирает одну тактику на все.

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

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

Так что же за невероятная метрика, которая делает вау-эффект? Делаем следующее: за каждую пройденную трассу даём в метрику дискретное +1; далее все положительные награды уменьшаем до пределов [0; 1] и берём от них среднее и тоже прибавляем в метрику; а штраф тоже уменьшаем до [0; 1], но через функцию 1/(1+x), чтобы уменьшение штрафа вело к увеличению метрики. И всё, максимизируем это число.

Оказывается с такой метрикой обучение идёт НАМНОГО стабильней и быстрей, чем с прошлой. И если сравнивать по величине раннего финиша (насколько быстро проходит), количеству пройденных трасс, штрафу и прочим параметрам, она реально лучше.

#машинки

dev optozorax

28 Sep, 21:19


Эволюция хочет вывернуть эту дыню наизнанку...

dev optozorax

26 Sep, 19:29


Прочитал статью https://habr.com/ru/companies/yandex/articles/845958/

Это прикольно, но слишком сложно! У нас (людей, животных) нет никаких лидаров, 3D реконструкции, gaussian splatting, backpropagation, gps, 360° зрения итд. При этом мы можем выполнять задачи доставки в 100 раз лучше всех этих роботов.

У нас не хватает фундаментальных исследований и открытий в области машинного обучения. Deep Learning слишком полагается на данные и оффлайн-обучение по ним. При этом модели обученные DL толком не способны дообучаться, особенно в реальном времени.

Надеюсь я со своими машинками что-то новое открою.

dev optozorax

23 Sep, 01:44


В моей симуляции эволюции машинка наконец-то научилась водить со сложной физикой! Правда, водит она так себе, но это уже что-то, хотя бы трассу проходит.

В итоге наэволюционировал как и планировал: постепенно переходил от простой физике к сложной. Причём простую физику сделал так, чтобы она практически идентично работала со сложной, с точки зрения управления и оказываемого эффекта. Сделал параметр, который можно крутить, и поставил его постепенное движение в сторону сложной физики. На каждое изменение запускал по 50 поколений, чтобы нейронка успела адаптироваться.

Обучение шло очень хорошо, видимо такими методами я и смогу добиться чтобы машинка дрифтила и делала ещё много всяких сложных и интересных вещей)

#машинки

dev optozorax

19 Sep, 19:27


Ну шо народ, 20к подписчиков в ютубе?

Кстати, спасибо тем кто подписывается, я сам очень привередливый, и подписываюсь только когда посмотрю много контента от человека, и понимаю что он мне заходит. Редко бывает что подписываюсь почти сразу. А тут у меня всего 2 видео, перспективы странные, никаких выводов сделать толком нельзя, но люди всё-равно подписываются.

Проспойлерю: через 2 месяца вас ждёт один сюрприз.

dev optozorax

19 Sep, 10:24


У Онигири вышло новое видео про агентов на основе GPT, которые играют в Among Us. Довольно интересные результаты, особенно мне понравилось что (спойлер к видео) с двумя импосторами, импосторы выигрывают чаще, чем с одним.

Я, кстати принял там участие в озвучке зелёного амогуса)) Артём сказал что некоторые будут кривляться, вот и я вместо своего обычного монотонного голоса попробовал отыгрывать голос, похожий на саламандр из аудиокниги, которую рекомендовал выше. Мне тяжеловато эти моменты смотреть, кринжовенько 😅

https://www.youtube.com/watch?v=gHZzzNNrDz0

dev optozorax

16 Sep, 00:08


Про симуляцию эволюции - я думал что это приключение на 20 минут, что самым сложным была физика, но оказалось нет. Я написал модуль для нейросети, сделал эволюцию, запускаю её и... Нифига, оно не обучается. Дай бог делает один поворот и всё.

В прошлом посте можно видеть что были зелёные круги - они означают награду, при их пересечении даётся +1. И вот с помощью эволюции пытался максимизировать это число. Была идея что оно само сможет, лёгкая же задача.

Поэтому начал с того чтобы сделать эту награду более гладкой: добавил расстояние до следующей награды, и замеряю его. Не помогло.

Сделал чтобы машинка всегда стартовала с некоторым небольшим случайным смещением и направлением, чтобы сделать итог более гладким. Сделал чтобы таких запусков было несклько в одной оценке нейронки. Не помогло.

Сделал визуальный редактор трасс - первая анимация. На нём сделал кучу трасс с гладкими поворотами, резкими поворотами, движением по прямой, несколько поворотов, и ещё отразил всё зеркально. Не помогло.

Поменял алгоритм оптимизации на очень крутой CMA-ES, оставлял долго работать. Не помогло.

Менял туда-сюда десяток параметров награды, размеров сети, управления. Не помогло.

Даже функцию активации поменял! Не помогло.

И ведь если погуглить как люди обучают машинки ездить, то всё у них так просто получается, они берут и ездят сразу. Почему он, а не я! Что я делаю не так? Не может быть же так что я настолько туп, что у меня ничего не получается. Начал подсматривать, у них вообще за десяток поколений всё сходилось.

И только в этот момент до меня дошло, что я всё делал правильно, за исключением, что моя задача слишком сложна. Нейронка не может из неё научиться по такому малому числу трасс и вообще. Ну разве, если что сделать 100500 очень разнообразных трасс. Или сделать чтобы нейронка сначала научилась не проходить трассы, а управлять своим телом, хммм. И тут вспоминается данное видео про двойной маятник, там у автора тоже обучение никак не шло, и он решил усложнять задачу постепенно.

Я подумал что последнее что я не твикал - это сложность управления. Ведь у меня такая сложная физика, дрифты там, повороты, инерция (!). Может быть нейронка просто никак не может выучить как этим пользоваться? Минимизировал физику до абсурда: просто дал нейронке возможность разворачивать угол и двигаться вперёд. Никакой инерции и колёс.

И о чудо, обучение пошло!!!! На второй картинке можно видеть дебажный вывод который я использовал, чтобы понять сколько трасс пройдено. И она прошла ВСЕ! Посмотрите как эта она ездит по трассе. Не знаю почему, но напоминает мышку (крадёться). Два дня писал код по 14 часов и НАКОНЕЦ-ТО, ОНО РАБОТАЕТ!!!

Теперь я знаю что надо делать - надо постепенно увеличивать сложность. Сделаю чтобы в физике были отключаемые элементы, и потихоньку, через параметры буду их включать.

#машинки

dev optozorax

13 Sep, 21:33


За сегодня в симулятор добавил столкновения с простенькими стенами и награду за трассу.

Коллизии реализовал через возникновение силы в месте коллизии. В этом подходе появляется проблема как подобрать подходящую силу - чтобы на маленьких скоростях машинка не отлетала слишком сильно, и на больших чтобы она не проходила сквозь. В итоге очень много времени убил на отладку. Хорошим решением оказалось - занулять скорость машинки, когда она вошла слишком далеко в стену. Ничего физически правдоподобного я больше не придумал, да и не хотел. У меня же всё-таки приблизительный движок, и чем он проще, тем лучше.

Редактор трасс сделал очень тупым, зато это не в коде писать)

Осталось совсем немного сделать до эволюции, но уже надо спать((( Завтра надеюсь уже увижу первую самостоятельную машинку.

#машинки

dev optozorax

13 Sep, 08:07


А тем временем вышла новая моделька от OpenAI, которая умеет размышлять, вот кратко о ней: https://t.me/seeallochnaya/1783. Моя статья полуторагодовалой давности (которая, собственно, похожую концепцию и описывает) становится актуальна как никогда. Она довольно хорошо состарилась. Советую почитать, если ещё не прочитали: https://t.me/optozorax_dev/601.

Я попросил людей проверить новую модель на задаче из этой статьи, и вот что можно видеть: https://t.me/seeallochnaya/1782?comment=140122. Неверно, но уже очень неплохо. Надо этот подход развивать дальше.

dev optozorax

12 Sep, 16:53


В последнее время я одержим мыслями сделать обучение ИИ с машинками. Причём задач там можно сделать миллион, но самой интересной пока кажется - чтобы они научились дрифтовать.

И вот так получается, что я заболел, сижу дома на больничном. Одержимость взяла верх и я начал воплощать эту идею. Для начала надо написать физическую симуляцию. 8 лет назад я уже писал симуляцию машинки, без физики, просто основанную на геометрии (идея хорошо объясняется на первой минуте здесь). Она умела ездить, поворачивать, но ни про какой дрифт и прочие плюшки не могло быть и речи. Чтобы был дрифт, надо делать физику, надо инерцию, момент инерции итд.

Никогда не делал физическую симуляцию с этим всем, начал читать википедию, вспоминать. Спустя какое-то время удалось реализовать чтобы 2D прямоугольник получал силу от мышки (функция apply_force принимает позицию на объекте и вектор силы), и за счёт этого двигался линейно и вращался корректно с точки зрения физики.

Затем началась самая сложная часть - колёса. Пока ресёрчил, увидел фразу что "симуляция колёс - это половина работы симулятора машины")))0) Сначала наобум сделал просто силу, перпендикулярную направлению колеса, которая тем сильнее, чем больше угол между вектором движения колеса и его направлением. Это отлично работало, машинка автоматически поворачивала, её импульс изменялся просто за счёт существования этой силы, и симуляции физики. Было очень приятно. Даже уже было какое-то подобие дрифта.

Затем закопался в то как работает машина, чтобы сделать реалистичнее. Узнал пару интересных вещей.

Во-первых существует такая вещь как сцепление - это произведение коэффициента сцепления (от 0 до 1) на вес машины. Для обычного асфальта он равен 0.9. Так вот, сцепление - это максимальная сила, которую способны совершать колёса, будь то ускорение, или торможение, они все ограничены сцеплением. И тут сразу случается aha-moment, понял зачем на гоночные машины ставят спойлеры, потому что двигатель мощный, но он не может передать всю свою мощь на колёса. А коэффициент сцепления на льду скажем около 0.15 - поэтому мы не можем на нём нормально тормозить, постоянно заносит.

Во-вторых узнал более подробно про то как работает поворот у машин, про это уже написал в optorepost: https://t.me/optorepost/92.

Добавил это в симуляцию, по сути колёса создают несколько сил, и они все ограничиваются сцеплением. Из поддержанных сил: ускорение/торможение по направлению колеса, сила для поворота (cornering force) перпендикулярная колесу, трение качения, обычное трение (когда колесо перпендикулярно направление движения). Но это всё не прям честно-честно по промышленным моделям шин, а с какими-то костыльными коэффициентами, но получается довольно реалистично, дрифт есть и рисуется. У меня не получается идеально дрифтовать как в NFS, пока думаю из-за того что управление надо отдельно тюнить и костылить, дрифт требует особых условий. Но уверен, что нейронки справятся.

Писал и отлаживал симулятор через любимый egui, там в два клика добавляются графики для дебага, и возможность настройки параметров физики, что пипец как удобно. А ещё там в два клика добавляется деплой в веб-демку, поэтому играйтесь:

http://optozorax.github.io/car_drift (исходный код)

Управление: стрелки, тормоза - space, сброс - Esc.
А на картинке вы можете видеть интерфейс демки, и я там уже немного подрифтовал.

#машинки