Как стать автором
Обновить

Базовые принципы алгоритмов обучения Hierarchical Temporal Memory

Время на прочтение7 мин
Количество просмотров11K
Доброго времени суток!
В последнее время на хабре довольно часто появляются статьи, в которых авторы описывают современные теории и подходы к построению искусственного интеллекта и нейронных сетей. Однако примеров конкретной реализации приводится довольно скудное количество. Попробуем восполнить этот пробел. В данной статье я опишу только основные теоретические и практические моменты, использованные при написании рабочего макета алгоритмов, предоставленных Numenta Inc.

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

Архитектура HTM

Архитектура сети, как уверяет автор, базируется на строении коры головного мозга, а если быть точнее, на той её части, которую называют неокортексом. Базовые единицы — клетки-нейроны, организуются в колонки, которые в свою очередь составляют участки (region). Из участков в дальнейшем возможно построить ту самую иерархию, в честь которой названа сеть.
Картинка с официального сайта дает общее представление о строении участков:
image

Строение клетки, по аналогии с естественным нейроном, предусматривает наличие дендритных сегментов (состоящих из некоторого множества дендритов) и синапсов — мест соединения между аксоном другой клетки и собственным дендритом. Каждый синапс в HTM фактически представлен «прочностью» (permanence) — вещественным числом от 0 до 1. Если прочность синапса меньше задаваемого значения, то синапс считается «несуществующим», в противоположном случае — действующим. В этом заключается понятие потенциального синапса (potential synapse).
Дендритные сегменты одной клетки делятся на дистальные и проксимальные. Проксимальные используются для получения входной информации, дистальные — для связи клеток между собой, внутри данного участка. В предлагаемой Numenta архитектуре каждая колонка клеток имеет один общий проксимальный сегмент, что способствует увеличению быстродействия. Каждый дендритный сегмент (как дистальный, так и проксимальный) содержит некоторое множество потенциальных синапсов.
Входные биты информации представляются в виде слоя клеток, способных формировать синапсы с проксимальными дендритами.
На базе данной архитектуры работают алгоритмы обучения, состоящие из двух фаз: пространственного (spatial) и временного (temporal, темпорального?) группировщиков.

Пространственный группировщик

Пространственный группировщик включает в себя три фазы: перекрытия (overlap), подавления (inhibition), обучения (learning).
В фазе перекрытия для каждой колонки вычисляется величина, отражающая «охват» синапсами проксимального дендритного сегмента данной колонки «единичных» битов входной информации входной информации. Активным считается синапс, прочность которого больше установленного значения и бит информации, к которому он ведет, содержит 1.
  1. public void SOverlap() {
  2.     for(int i=0;i<xDimension*yDimension;i++) {
  3.         overlap[i] = 0.0;
  4.         for(Synapse synapse: connectedSynapses(i)) {
  5.             overlap[i] += input(time, synapse.c, synapse.i);
  6.         }
  7.         if (overlap[i] < minOverlap)
  8.             overlap[i] = 0.0;
  9.         else
  10.             overlap[i] *= boost[i];
  11.     }
  12. }

В фазе подавления вычисляется список активных колонок. Колонки с максимальным «охватом» подавляют своих соседей, количество активных колонок в регионе регулируется задаваемым пользователем параметром.
  1. public void SInhibition() {
  2.     activeColumns.add(new ArrayList<Integer>());
  3.     for(int i=0;i<xDimension*yDimension;i++) {
  4.         Double minLocalActivity = kthScore(neighbours(i), desiredLocalActivity);
  5.  
  6.         if (overlap[i] > 0.0 && overlap[i] >= minLocalActivity) {
  7.             activeColumns.get(time).add(i);
  8.         }
  9.     }
  10. }

В фазе обучения прочность активных синапсов проксимального дендритного сегмента каждой активной колонки повышается, неактивных, соответственно понижается. Затем применяется механизм, обеспечивающий регулярное срабатывание всех колонок в регионе. В общих словах, он состоит в том, что мы ведем историю активации каждой из колонок (в виде скользящего среднего) и усиливаем «охват» колонки в случае её долгого простоя.
  1. public void SLearning() {
  2.     for(Integer c: activeColumns.get(time)) {
  3.         for(Synapse s: potentialSynapses.get(c)) {
  4.             if (input(time, s.c, s.i) > 0) {
  5.                 s.permanence += permanenceInc;
  6.                 s.permanence = Math.min(s.permanence1.0);
  7.             } else {
  8.                 s.permanence -= permanenceDec;
  9.                 s.permanence = Math.max(s.permanence0.0);
  10.             }
  11.         }
  12.     }
  13.  
  14.     for(int i=0;i<xDimension*yDimension;i++) {
  15.         minDutyCycle[i] = 0.01 * maxDutyCycle(neighbours(i));
  16.         activeDutyCycle[i] = updateActiveDutyCycle(i);
  17.         boost[i] = boostFunction(activeDutyCycle[i], minDutyCycle[i]);
  18.         overlapDutyCycle[i] = updateOverlapDutyCycle(i);
  19.  
  20.         if (overlapDutyCycle[i] < minDutyCycle[i]) {
  21.             increasePermanences(i, 0.1*connectedPerm);
  22.         }
  23.     }
  24.  
  25.     inhibitionRadius = averageReceptiveFieldSize();
  26. }

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

Временной группировщик

Временной группировщик, как и пространственный, состоит из трех фаз: вычисления состояний активности (active) и обучения (learn) каждой из клеток, вычисления состояний предсказания (prediction) и фазы применения предпологаемых на предыдущих шагах изменений в структуре сети — добавления новых синапсов/дистальных дендритных сегментов.
В первой фазе для каждой активной колонки из списка, доставшегося от пространственного группировщика, вычисляется — была ли эта активность предсказана какой-либо из клеток колонки. В случае нахождения такой клетки, она одна становится активной, в противном — все клетки в колонке становятся активными. По определенному правилу выбирается клетка для обучения, при невыполнении правила обучается наиболее подходящая клетка из колонки.
В следущей фазе на основе активности сегментов вычисляются клетки в предсказывающем состоянии и усиливаются сегменты, активность которых привела к удачному предсказанию на прошлом временном шаге.
На последнем этапе для обучающихся клеток применяются все изменения, которые были предложены в двух предыдущих фазах. Добавляются новые сегменты или потенциальные синапсы к списку уже существующих для данного сегмента.
  1. public void TLearning() {
  2.     for(int c = 0; c < xDimension*yDimension; c++) {
  3.         for(int i = 0; i < cellsPerColumn; i++) {
  4.             if(learnState.get(time).get(c).get(i)) {
  5.                 adaptSegments(segmentUpdateList.get(c).get(i)true);
  6.                 // segmentUpdateList.get©.get(i).clear();
  7.             } else if (!predictiveState.get(time).get(c).get(i) && predictiveState.get(time-1 > 0 ? time-1 : 0).get(c).get(i)) {
  8.                 adaptSegments(segmentUpdateList.get(c).get(i)false);
  9.                 // segmentUpdateList.get©.get(i).clear();
  10.             }
  11.             segmentUpdateList.get(c).get(i).clear();
  12.         }
  13.     }
  14. }

Заключение

Будем считать, что общее представление об алгоритмах обучения, представленное в статье, достаточно для понимания базовых принципов. Всех интересующихся конкретной реализацией могу пригласить на github. Представленный там проект далек от идеала в плане соответствия архитектуре HTM, но, практически, в точности соответсвует представленным в нументовском пдф'е отрывкам псевдокода и описанию функций и данных.
Теги:
Хабы:
+13
Комментарии29

Публикации