Найти в Дзене
Помоги себе сам

Модель мозга одноклеточного

Это статья про нейросети, Unity и программирование. Читателю может быть интересно простым языком на понятном примере поразбираться вместе со мной как работает простейшая нейросеть. Задача, которую я в ней решаю много раз решалась разными способами до меня, но мне хочется придумать свой. Возможно где-то есть даже программный код, который функция в функцию придуман кем-то раньше, но мой интерес в том, чтобы сделать это без подсказок, грубой силой, так же как (в моём понимании) это сделала и миллионы лет назад эволюция. Возвращаясь к истокам идеи искусственных нейронных сетей я хотел бы сделать как можно более простую модель одноклеточного и обучить его двигаться в сторону источника света, опираясь на мозг, состоящий из искусственных нейронов, то есть нейросеть. На рисунке выше нарисовал искусственный нейрон. Он имеет от одного до бесконечности входных сигналов и всего один выходной сигнал. Вес входного сигнала - это по-сути его коэффициент важности. Вес каждому входному сигналу назначает

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

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

модель нейрона
модель нейрона

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

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

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

группу нейронов, работающих над одним результатом, можно представить как один нейрон, считающий более сложную функцию
группу нейронов, работающих над одним результатом, можно представить как один нейрон, считающий более сложную функцию

Из поставленной задачи следует, что у нашего одноклеточного должны быть две функции:

1. Обдумывать происходящее вокруг и свои потребности.

2. Реагировать на результаты своей мыслительной деятельности.

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

Мы как высокоразвитые существа уже предполагаем простейшую стратегию:

1. Не видишь свет - стой и вращайся вправо.

2. Видишь свет - плыви прямо.

Для этой стратегии достаточно одного глаза с одним рецептором. И два варианта действий (в плоском мире с двумя измерениями). Тут надо предположить, что каждому рецептору соответствует два нейрона: активирующий и тормозящий, иначе пришлось бы использовать множество значений весов {-1, 0, 1}, но такое мне кажется менее соответствующим биологии, так как рецептор тоже по-сути нейрон. Это ограничивает меня в оперировании только положительными числами, что конечно снижает возможную математическую эффективность и увеличивает количество нейронов.

предполагаемая идеальная модель простейшего c тормозящим и активирующим нейроном (на практике получилось по-другому)
предполагаемая идеальная модель простейшего c тормозящим и активирующим нейроном (на практике получилось по-другому)

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

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

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

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

Для реализации нам понадобятся три вида нейронов:

1. Рецептор. У него всегда вес входа = 1 и ему назначается другой вид входной информации, нежели другим нейронам. Его активирующая функция - переводить входной тип информации в число от 0 до 1, так как мы предположили, что у нас именно такой информацией обмениваются нейроны.

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

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

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

Моделировать буду так:

1. Выпущу 1000 сперматозоидов одноклеточных вокруг одного яйцеклетки источника света. На случайном расстоянии со случайными значениями весов входных значений в диапазоне от 0 до 1. Скорость передвижения приму за треть длины тела, угол зрения = 30° , сила поворота = 15° в секунду (цифры тоже не имеют никакого обоснования - подбирал, чтобы выглядело естественно в реальном времени в процессе моделирования).

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

3. Подожду пока продолжительность жизни у всех усреднится.

После того как вся популяция обновилась параметры популяции стали постоянными
После того как вся популяция обновилась параметры популяции стали постоянными

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

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

Вторые же стоят на месте и вертятся до тех пор пока не увидят свет и только тогда начинают плыть прямой наводкой к нему.

Представители двух видов прошедших эволюционный отбор (параметры их нейронных связей)
Представители двух видов прошедших эволюционный отбор (параметры их нейронных связей)

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

Также сделал видео, с сокращённым пересказом этой статьи. Мне понравилось выступать в роли создателя искусственной жизни, поэтому скорее всего у этой статьи появится продолжение и тут появится ссылка. А пока дам ссылки на другие свои заметки: если хотите научиться программировать, но не знаете с чего начать; если хотите научиться основам 3D. Также по Unity мануал для новичков сделаю на основе этой модели (и тут появится ссылка), там расскажу с чего начать если хотите научиться делать игры (или подобные симуляции с графикой).