Debugger's Process
131 subscribers
130 photos
78 videos
3 files
70 links
Download Telegram
- Так ты в облаке стартани, сынко!
- В облако не лезет!
This media is not supported in your browser
VIEW IN TELEGRAM
"Эксперимент, очевидно, неудачный"
This media is not supported in your browser
VIEW IN TELEGRAM
Так, ну вот это уже лучше)

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

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

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

Это пока ранний эксперимент, если присмотреться, видно что местами нейромагия срабатывает не так, как хотелось бы - на то она и магия. Но это, я думаю, поправимо.
https://youtube.com/shorts/HMmCJVkNUY4?feature=share

Во. Отрендерил для ютуба, а то телега пережимает гифки.

Что сразу бросается в глаза, так это то, как нейросимуляция няшно обрабатывает высокоэнергетические столкновения. Я обучал ее на энергиях в 2.5 раза меньше, чем в этом видео. Симулятор в таких случаях просто "взрывается" - буквально за пару шагов симуляции энергия взлетает до бесконечности, достаточно одной "слишком быстрой" частицы, чтобы разлетелись вообще все.

Здесь же быстрые частицы спокойно пробивают массу и даже теряют энергию на столкновениях, увязая в ней!
https://youtube.com/shorts/B7dxL7CT5CI?feature=share

А это с другим рендером, сглаженным. Тут лучше видно след, который оставляют сверхбыстрые частицы, пролетающие через массу других.
Messages in this channel will be automatically deleted after 1 week
Messages in this channel will no longer be automatically deleted
Извините, зверюга прилёг на клавиатуру, пока я пытался понять, что с компьютером.
Ох, черт. Хотел удалить черновики сообщений из лички, вместо этого удалил с канала. Ну отлично, блин.
Надо больше спать, видимо(
Хорошо хоть черновики остались (иронично!), сейчас восстановлю.
Давайте я расскажу, над чем я сейчас работаю и чего хочу добиться.
Вообще я не люблю писать про проекты, в которых я не уверен, что получу хоть какой-то результат, но что поделать - это часть исследовательской работы.

Итак, начнем с того, что уже точно заработало.

Часть 1. Что уже есть.
Я использовал свой симулятор Simba для генерации обучающих данных и обучил нейронную сеть вычислять динамику частиц. Работает это так.

На входе у нас есть массив координат частиц и их скоростей - вся информация, необходимая, чтобы задать любое начальное состояние системы частиц в момент времени t0.
positions0 = [ [10, 20], [11,21] ]
velocities0 = [ [1, 2], [3,4] ]

На выходе надо получить positions1, velocities1 в момент времени t1. Между t0 и t1 всегда проходит dt=1.0/50 секунды, потому что это соответствует приятной глазу частоте кадров 50 FPS, а то, что происходит между кадрами меня не волнует - мне по сути-то нужны только позиции, чтобы отрисовывать частички.
При помощи Симбы я получаю целевые значения позиций и скоростей в нужные моменты.

Тут надо отметить, что симбе для этого нужно выполнить 25 шагов, а не один - это меня не волнует, что происходит между кадрами, а симулятор очень даже волнует - если попробовать посчитать выход одним шагом, сразу шагнув на 1/50 с, для симулятора это будет выглядеть, как будто все это время на все частицы действовали постоянные, не изменяющиеся силы. В каких-то случаях это не страшно, но в большинстве - критично, потому что частицы под действием таких сил начинают влетать друг в друга,
и там, где в реальности они бы успели затормозить под действием все возрастающего отталкивания, тут они весь интервал dt спокойно летят, и в итоге оказываются так близко друг к другу, что силы, действующие на них, становятся астрономическими, еще сильнее усугубляя проблему. Поэтому-то симуляции и "взрываются" - хватает всего пары шагов, чтобы все силы взлетели в бесконечность (которая, как мы знаем, не предел) и все частицы вылетели за пределы моей маленькой симулированной вселенной.


Ну так вот. Понятное дело, что превратить эти позиции и скорости во входные данные для нейросети можно бесконечным количеством способов. Я не буду описывать все, что я пробовал, опишу сразу вариант, который заработал. У меня, во всяком случае, получилось обучить сеть стабильной симуляции только таким образом.
Дальше пойдут картинки.
1) Берем каждую частицу и генерим, скажем так, ее "образ" 3х3 пикселя. Значение "пикселей" - это расстояние от центра частицы до центра самого "пикселя".
Целую часть координат отбрасываем, потому что она тут не важна - нам не важно, будет частица в координатах сетки (100.5, 100.7) или (10.5, 10.7). Важно только то, что центр частицы отстоит на (0.5, 0.7) от центра клеточки.

Расстояние, само собой, нормализовано по формуле (max_r-r)/max_r, где max_r - константа, подобранная так, чтобы в центре значение было 1.0, а по краям - ближе к нулю.
2) Эти 3х3 "картинки" накидываем на общее "поле" - просто берем 2D матрицу, заполненную изначально нулями, и прибавляем к нужным клеточкам (в позициях частиц) значения их "образов".
Получаем общее "поле", по которому можно примерно понять, где находятся частицы. Причем, заметьте - эта операция может быть великолепно распараллелена, потому что каждую частицу можно рисовать независимо от остальных, только прибавлять к полю надо атомарными операциями.
3) С позициями разобрались, остались скорости. Моя логика была в том, чтобы заэнкодить скорости таким же образом, как и позиции. "Безобразно, зато единообразно" - я предполагал, что так будет проще учить сеть. Как скорости превратить в позиции? Помножить на время, конечно! Множим скорости на dt, прибавляем к начальным позициям. Получаем новые позиции с интересным физическим смыслом.
Это не positions1, которые мы ищем, но это то, как двигались бы частицы, если бы не взаимодействовали друг с другом.
Теперь у нас есть две картинки "поля", содержащих информацию о позициях - начальной, и той, в которой бы оказались частицы, если бы двигались равномерно и прямолинейно, без действующих на них сил, по заветам Ньютона.

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

Получаем батч с размерностью (количество_частиц, 2, 15, 15), который так и просится на вход сверточной нейронной сети. А на выходе просим сеть выдать коррекцию координат (pos_correction) и скорости (vel_correction) относительно этого "линейного шага" - в смысле, мы по сути говорим "Вот так выглядело окружение частицы в момент времени t0. Вот так бы оно выглядело через интервал времени dt, если бы частицы не взаимодействовали. Дай мне коррекцию координат и скорости, чтобы я получил то, как они реально двигались, с учетом взаимодействий".
В итоге вычисляем
positions1 = positions0 + velocities0*dt + pos_correction и
velocities1 = velocities0 + vel_correction
Таким образом для частиц, на которые никакая сила не действует, сети достаточно всегда выдавать нули в качестве коррекций - потому что они и так двигаются линейно.

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

В следующем посте расскажу о том, над чем конкретно я работаю сейчас.
Часть 2.1. Над чем я работаю сейчас.

Меня занимает несколько вопросов, в этом посте я рассмотрю первый из них.
Этот "образ" частицы, картинку 3х3 я генерю ручками - в смысле, это я просто выбрал такую вот формулу для его расчета, и это заработало.
Но ведь его тоже можно выучить! Представьте, что вместо посчитанного через расстояние образа, у нас есть еще одна нейросетка, которая на вход получает координаты частицы (ведь мы помним, что образ зависит от координат, это не статичная картинка, а выход 2д функции, которая на вход получает дробную часть координат, а на выходе выдает 9 значений, которые потом и записываются в общее "поле"), а на выходе выдает искомую матрицу 3х3.
Теоретически, такой выученный образ может оказаться эффективнее, ведь он не ограничен одной формулой расстояния. Да и на вход можно подать не только координаты, но и, например, скорость. Да что угодно можно подать - пусть сеть сама определит, что ей нужнее всего в этом образе. Я эту сеть зову "энкодером".

Но так как нет эталонных образов, которым нужно учить энкодер, не получится и просто взять и посчитать расхождение выхода нейросети с целевым образом и распространить градиент в ее веса.
Чтобы ее обучить, нужно, чтобы градиент ошибки позиции и скорости тёк не только в веса той нейросетки, которая по упомянутому выше батчу генерит эти самые коррекции позиций и скорости, но и в матрицу самого батча, а оттуда, через поле в матрицу образа частицы, сгенеренной энкодером, а из нее - в веса энкодера.
Если эта фраза не очень понятна, то рекомендую старую статью "a gentle introduction to backpropagation", с которой я много лет назад начинал свой путь в машинное обучение. Ссылку приведу в конце.

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

К сожалению, результат несколько разочаровал. Да, сетка выучила образ. Он даже оказался похож на те, что я собирал вручную! Так что концепция работает. Но особого выигрыша в точности я не получил. То есть, да, он есть, но его можно заметить только если прогнать обучение по несколько раз, а результаты сгруппировать и сгладить. К счастью, это за меня делает wandb.
Wandb - это такой сервис + библиотека - Weights And Biases, делает примерно то же, что и Tensorboard и немного больше. В принципе, это дело вкуса, но я к ней привык и использую именно ее. Ссылку также приведу в конце.

Ну штош. Бывает. Хотя бы заработало, уже хорошо.
Из интересного - выученный сеткой образ напоминает тот, что я собирал вручную из расстояний, но если расстояния (разумеется) строго неотрицательны, то выученный образ не только включает в себя отрицательные значения, но иногда оказывается полностью инвертированным, эдакой "античастицей". В смысле, если запустить обучение, то выучиться может как обычный образ (где в центре число побольше, обычно положительное, по краям - поменьше), так и "антиобраз" (где в центре число поменьше, как правило, отрицательное, а по краям - побольше). По точности эти два варианта не отличаются.

Ниже привожу результаты, а в следующем посте я расскажу о самом долгом эксперименте этого проекта, его логическом продолжении, который прямо сейчас крутится на обучении в яндексовском облаке, потому что в мою видюху он не влезает
This media is not supported in your browser
VIEW IN TELEGRAM
Слева - выученный образ, справа - построенный вручную из расстояний.
This media is not supported in your browser
VIEW IN TELEGRAM
А это из той сессии, где выучилась "антиматерия" - слева выученный, справа - собранный вручную.
https://www.researchgate.net/publication/266396438_A_Gentle_Introduction_to_Backpropagation

Ссылка на статью "A Gentle Introduction to Backpropagation". В принципе, в ней содержится все, что необходимо для понимания любой системы машинного обучения, это основа основ.
https://wandb.ai/

Сервис wandb. Аналог Tensorboard, позволяет в реальном времени строить красивые графики лосс-функций, да и вообще всего, что только захочется.
А вот так в wandb выглядит разница в ошибке сетки с выучиваемым образом (зеленый график) и образом, собранным вручную из расстояний (синий график)
Графики построены агрегацией информации от 5 сессий обучения каждый.