Проблемы задержек


Пусть есть четыре уровня иерархии цепочек, которые последовательно распознают — буквы в слоги, слоги в слова, слова в фразеологизм. На распознавание каждого уровня должен пройти один такт нейросети. Если ИНС читает по одной букве за такт, то распознавание самых высокоуровневых признаков будет сильно запаздывать. Если ИНС должна производить прогнозирование и выбор действий, то это совсем не годится.
В ЕНС такая проблема не сильно выражена, так как часто (например при распознавании речи на слух) нейроны работают намного быстрее, чем появляется очередной уровень иерархии.
Для ИНС проблему можно решить, если искусственно задерживать поступление очередного признака до того момента, пока все уровни иерархии не будут распознаны. Я называю такой метод «с адаптивной глубиной распознавания». Имеем цикл с постусловием — пока хотя бы еще один нейрон был распознан, не читать очередной признак в сенсоры, а продолжать распознавать то, что есть. Именно для отладки таких случаев пригождается усложнение виртуального времени NeuroTime, как было описано в прошлой статье.
Возникает другая проблема: каждый такт распознавания занимает время, и нейроны, которые запомнили, что у них только что активировались предусловия, могут за это время деакивироватся, и в следующем такте они не сработают, как надо. Эту проблему можно решить, если сделать связи двух типов — условно говоря, моментальные «вверх» и с задержками «вперед». Связи «вверх» посылают сигналы в цикле с адаптивной глубиной распознавания, и за это время ни один нейрон не деактивируется (не успевает деактивироваться, если по концепции). Лишь в конце цикла, когда приходит время обработать сигналы «вперед», происходит тик мира и такт времени, и нейроны деактивируются.
Такие связи можно (хотя и не обязательно) разделять по разным нейронам внутри нейрокластера. Раньше, когда я работал с отдельными нейронами, так и было: кластер все усложнялся, абстрактная модель из четырех нейронов на кластер…

… превратилась в восьминейронную:

При этом, управляющие связи у нейронов внутри кластера (выбор режимов 1ВЦ/2ВЦ и т. д.) не отображаются, так как их нету — они виртуальные: в пределах кластера оказалось намного проще передавать активацию кодом на С++ (типа cluster.neuronTemporalOutput.activate()), чем создавать связи, думать про задержки сигнала и пороги срабатывания.

От нейронов к кластерам — дедупликация


Впоследствии, все нейроны были объединены в кластер еще сильнее — например, какому-то нейрону не нужны входящие связи, так как он активируется программно из других нейронов кластера, и единственная его цель — посылать сигналы по исходящим связям. Какому-то другому нейрону не нужны исходящие связи, так как он передает активацию программно на другой нейрон кластера. Если у нас есть нейрон, который производит воспоминание — активацию признаков — его связи направлены «вниз», то у него набор связей тот же, что и у нейрона того же кластера, который принимает сигналы с этих признаков — у них отличаются лишь направление (вверх). Так зачем дублировать связи, зря тратить память? Вот тут и появились новые модели нейрокластера, где нейроны были виртуализированы — контейнеры связей отдельно (аксоны и дендриты), нейроны с потенциалами действия отдельно. Это не только экономило память, но и ускорило вычисления, так как повысило их локальность. ИНС стала меньше и визуально:

И стало легче просматривать иерархии с большим количеством уровней:


Сжатие информации и забывание


При распознавании, более высокоуровневые признаки могут тормозить низкоуровневые. Тогда низкоуровневые быстрее забудутся и очистят цепочку памяти. Тормозить может только тот кластер, который активировался сам, и только те признаки, которые он распознает — так как он сам уже занесен в цепочку памяти и уже учел эту дочернюю информацию, и она не потеряется при таком торможении. Как тормозить? Полностью деактивировать дочерние «нижние» признаки не целесообразно, достаточно лишь уменьшить силу связи, чтобы связь в цепочку памяти быстрее была удалена. Ведь в ближайшие несколько тактов информация может еще пригодится, даже если признак вроде бы учтен, поэтому не надо спешить удалять моментально.
Также сжатие информации приводит к тому, что почти безразлично, будет ли ИНС читать тексты по буквам или по словам. В финале останется только высокоуровневый смысл, а связи на побуквенное чтение будут довольно быстро удалены.

Выделение цепочек с учетом иерархий


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

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

Комментарии (0)