#Введение

У вас не возникало ощущения что все текущие нейросети какие-то слишком линейные? Посмотрим, например, на перцептрон:

×1
png
Источник

Или на многослойную нейронную сеть:

×1
png
Источник

Когда я только изучал эту тему, у меня была такая мысль:

Почему в них сигнал распространяется только в направлении слева-направо? Где циклы? Как без циклов возможны сложные вычисления?

Но на самом деле нейросети и не обязаны быть произвольными. Уже в таком виде они справляются с большим количеством задач.

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

Да и для таких нейросетей придумали в своё время алгоритм обратного распространения ошибки.

#Пример произвольной нейросети

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

×1
png

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

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

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

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

Кстати, произвольная нейросеть была использована в этом видео:

И ведь действительно, интуитивно очевидно, что для симуляции агентов, пытающихся развиваться в виртуальном или реальном мире, надо использовать максимально общий класс нейросетей - произвольные!

Меня очень долго волновала проблема, почему нигде в интернете я не могу найти как учёные используют такие прозвольные нейросети, неужто целая категория нейронных сетей берёт и простаивает??? Значит могу прийти я со своими произвольными нейросетями и взорвать науку?!

К сожалению, нет.

#Реккурентная нейронная сеть

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

Тут расскажут не только как это работает в общем виде, но ещё и расскажут про одну очень хитрую современную архитектуру LSTM.

Ну, или можете это проигнорировать (всё-таки час идёт) и просто попытаться понять суть из контекста.

#Сводим произвольную нейросеть к реккурентной

Сначала пронумеруем все нейроны.

×1
png

Затем уберём все связи, и расположим все нейроны сверху-вниз, и сделаем второй столбик-дубликат первого. Это показано на следующей картинке слева.

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

×1
png

Это и есть реккурентная нейросеть, мы свели всё к ней! Значит, реккурентная нейросеть способна представить любую топологию нейросети, и нет смысла изобретать свои собственные велосипеды.

Как видно, здесь слева не используются выходные нейроны, а справа не используются входные нейроны.

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

×1
png

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

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

×1
png

#Почему это лучше

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

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

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

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

#Как я пришёл к этой идее

Совершенно случайно. Нигде об этом прямым текстом не пишется. Мне непонятно, почему, ведь это очень важно! Можно же было просто написать:

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

#Заключение

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

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

Кстати, приглашаю всех людей, заинтересованных в симуляции эволюции, в чатик в телеграме: https://t.me/emergevolution