#Введение
У вас не возникало ощущения что все текущие нейросети какие-то слишком линейные? Посмотрим, например, на перцептрон:
Или на многослойную нейронную сеть:
Когда я только изучал эту тему, у меня была такая мысль:
Почему в них сигнал распространяется только в направлении слева-направо? Где циклы? Как без циклов возможны сложные вычисления?
Но на самом деле нейросети и не обязаны быть произвольными. Уже в таком виде они справляются с большим количеством задач.
Кстати, благодаря этой линейнойсти мы можем выжимать максимум из наших текущих вычислительных мощностей, используя очень большие нейросети. На них сигнал распространяется без всяких циклов, а значит это быстрее вычислять.
Да и для таких нейросетей придумали в своё время алгоритм обратного распространения ошибки.
#Пример произвольной нейросети
Не знаю откуда мы все это берём, но мы точно знаем, что в мозгу не могут быть такие однонаправленные связи, там полюбому должны присутсововать циклы и прочие очень сложные штуки. Нейросеть в нашем мозгу должна выглядеть примерно так:
png
То есть как просто простой направленный граф без всяких ограничений.
Очевидно, что такая нейросеть должна обладать возможность что-то "запоминать" на краткосрочный период, делать цикличные движения. Такая нейросеть идеально подходит для использования в агентах внутри симуляций.
Если мы симулируем агента в какой-то среде, то мы должны напрямую симулировать процесс "движения сигнала", задавать какие-то ограничения по количество этих передвижений сигнала для одного шага, накапливать результат на красных выходных нейронах и что-то подобное.
Я не стал на этом изображении расставлять веса нейронных связей, чтобы не загромождать изображение, но по факту они там должны быть.
Кстати, произвольная нейросеть была использована в этом видео:
И ведь действительно, интуитивно очевидно, что для симуляции агентов, пытающихся развиваться в виртуальном или реальном мире, надо использовать максимально общий класс нейросетей - произвольные!
Меня очень долго волновала проблема, почему нигде в интернете я не могу найти как учёные используют такие прозвольные нейросети, неужто целая категория нейронных сетей берёт и простаивает??? Значит могу прийти я со своими произвольными нейросетями и взорвать науку?!
К сожалению, нет.
#Реккурентная нейронная сеть
Чтобы понять дальнейшее повествование, надо понять что такое реккурентная нейросеть. Для ознакомления рекомендую это видео:
Тут расскажут не только как это работает в общем виде, но ещё и расскажут про одну очень хитрую современную архитектуру LSTM.
Ну, или можете это проигнорировать (всё-таки час идёт) и просто попытаться понять суть из контекста.
#Сводим произвольную нейросеть к реккурентной
Сначала пронумеруем все нейроны.
png
Затем уберём все связи, и расположим все нейроны сверху-вниз, и сделаем второй столбик-дубликат первого. Это показано на следующей картинке слева.
Теперь просто остаётся добавить связи, но добавлять будем таким образом, что связь может быть направлена только из левого столбика в правый. Результат показан на правой части картинки.
png
Это и есть реккурентная нейросеть, мы свели всё к ней! Значит, реккурентная нейросеть способна представить любую топологию нейросети, и нет смысла изобретать свои собственные велосипеды.
Как видно, здесь слева не используются выходные нейроны, а справа не используются входные нейроны.
И действительно, если подумать как здесь протекают сигналы, это просто другой способ обозначения нейросети с произвольной архитектурой. Это даже напоминает матрицу смежности для представления графа. То есть можно визуализировать это так:
png
Так как веса не заданы, то можно просто обозначить наличие связи при помощи красного квадрата. И в таком виде очевидно, что входные и выходные данные надо представлять как вектор, а саму нейросеть как матрицу.
Кстати в таком виде невозможно обозначить больше чем одну связь из одной ноды в другую. Вообще не знаю зачем это может понадобиться, кроме как использовать разные функции активации, да и это тоже вполне бессмысленная вещь, так что оставим этот случай.
png
#Почему это лучше
И я даже скажу, что в таком виде произвольная нейросеть получается лучше, чем её изначальный интуитивный вид. Почему?
Во-первых вы можете использовать всю мощь, что развилась вокруг реккурентных нейросетей, будь то софт для их обучения или множество научных работ, например про преодоление взрыва градиентов.
Во-вторых представлять её таким образом в памяти вычислительно эффективней. Предположим как бы вы стали реализовывать класс, обрабатывающий нейросеть, которую мы нарисовали в самом начале? Наверняка бы делали напрямик: хранили бы где-то массив импульсов, хранили бы граф связей и перемещали бы импульсы по этому графу. А распараллеливать это добро очень сложно.
А реккурентные нейросети очень легко представляются матрицей, которую можно просто умножать на вектор чисел. Это даже с точки зрения кэша процессора куда эффективнее. Тем более для умножения матриц уже написали вагон и маленькую тележку сверх-быстрых параллельных библиотек, не говоря о умножении матриц на видеокарте.
#Как я пришёл к этой идее
Совершенно случайно. Нигде об этом прямым текстом не пишется. Мне непонятно, почему, ведь это очень важно! Можно же было просто написать:
Реккурентная нейронная сеть позволяет имитировать нейросеть, представляющую из себя произвольный граф.
#Заключение
Так что не взорвём мы науку с нашими произвольными нейросетями, они уже существовали до нас, но скрывались под другим названием, просто никто толком не знал, что это они.
А теперь в следующий раз, когда надумаете писать свою эволюцию агентов с произвольными нейросетями и аниме-тянками, вы не наступите на грабли велосипедостроения, и сможете использовать отлаженный и оптимизированный инструментарий реккурентных нейросетей!
Кстати, приглашаю всех людей, заинтересованных в симуляции эволюции, в чатик в телеграме: https://t.me/emergevolution