Исследуем LSTM-сети. Часть 1

LSTM-сети являются относительно несложным развитием концепции традиционных нейронных сетей. Среди заслуг данного типа сетей можно назвать многие удивительные достижения глубокого обучения за последние несколько лет. Я постараюсь интуитивно объяснить концепцию LSTM-сетей, чтобы читателю было легче разобраться в сути.

Для начала давайте посмотрим на рисунок:

Разве LSTM-сеть не прекрасна? Итак, приступим.

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

Нейронная сеть

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

Как мы можем это реализовать?

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

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

Описанную выше концепцию реализует глубокая нейронная сеть (deep neural network). Она принимает на входе изображение и возвращает тип активности. Такая сеть в процессе обучения формирует в своих скрытых слоях представления различных уровней. Этот процесс можно сравнить с тем, как люди обнаруживают закономерности в поведении щенка, ничего не зная о собаках (увидев достаточное количество корги, мы выделяем общие базовые характеристики, такие как большие уши и короткие лапы; затем мы обнаруживаем более сложные особенности, такие как любимые позы и т.д.).

Математическая формулировка

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

  • Нейронная сеть с одним скрытым слоем (hidden layer) принимает на входе вектор x, который мы можем рассматривать, как набор нейронов.
  •  Каждый входной нейрон соединен со скрытым слоем посредством набора весов, вычисленных в процессе обучения.
  •  j-й скрытый нейрон дает на выходе величину [latex] h_j = \phi(\sum_i w_{ij} x_i) [/latex], где [latex] \phi [/latex] – функция активации.
  •  Скрытый слой связан с выходным слоем, и j-й выходной нейрон дает на выходе величину y_j = \sum_i v_{ij} h_i . Если нам нужны вероятности, мы можем преобразовать выходной слой с помощью функции софтмакс (softmax).

В матричной форме описанные выше уравнения имеют следующий вид:

[latex] h = \phi(Wx) [/latex] 

[latex] y = Vh [/latex] 

где

  •  x – входной вектор;
  •  W – это матрица весов, соединяющая входной слой и скрытый слой;
  •  V – это матрица весов, соединяющая скрытый слой и выходной слой;
  •  Распространенными вариантами функции активации [latex] \phi [/latex] являются:
  •  Сигмоида (sigmoid), [latex] \sigma(x) [/latex]. Дает значения в интервале (0, 1).
  •  Гиперболический тангенс (hyperbolic tangent), tanh(x). Дает значения в интервале (-1, 1).
  •  ReLU, [latex] ReLU(x) = max(0, x) [/latex].

Ниже представлена диаграмма сети:

Обратите внимание, чтобы не усложнять нотацию, я подразумеваю, что векторы x и h содержат в качестве свободного члена дополнительный нейрон (bias neuron), значение которого фиксировано и равно 1.

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

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

Таким образом, мы хотим, чтобы наша модель умела отслеживать состояние мира:

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

Описанную концепцию реализует рекуррентная нейронная сеть (РНС, recurrent neural network, RNN). Вместо того чтобы просто обрабатывать каждое изображение независимо от других, РНС формирует внутреннюю память о мире (веса, присвоенные различным элементам информации), которая помогает выполнять более точную классификацию.

Математическая формулировка

Итак, давайте добавим в наши уравнения внутренние знания (internal knowledge), которые мы можем рассматривать, как элементы информации, хранимые сетью.

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

[latex] h_t = \phi(Wx_t + Uh_{t-1}) [/latex] 

[latex] y_t = Vh_t [/latex] 

Скрытое состояние, вычисленное в момент времени [latex] t [/latex] ([latex] h_t [/latex], то есть наши внутренние знания), подается в сеть в следующий момент времени. Обратите внимание, такие термины, как скрытое состояние (hidden state), внутренние знания (internal knowledge), память (memory), убеждения (beliefs) являются эквивалентными и обозначают [latex] h_t [/latex].

LSTM-сеть

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

Этот хаос говорит о том, что информация быстро трансформируется и исчезает, то есть модель не имеет возможности реализовать долговременную память (long-term memory). Следовательно, мы хотим, чтобы сеть могла обучаться тому, как обновлять свои знания более интеллектуальным образом. В частности, сцены без участия Боба не должны изменять информацию, связанную с Бобом, а сцены с участием Эллис, должны стимулировать сбор дополнительной информации об Эллис.

Чтобы реализовать это, нам потребуются специальные механизмы:

  1. Вентиль остаточной памяти (remember gate), также называемый вентилем забывании (forget gate). Например, если данная сцена завершилась, модель должна забыть текущее местоположение, время суток и сбросить всю информацию, связанную с данной сценой. Однако, если в данной сцене погибает персонаж, сеть должна помнить о том, что он мертв. Следовательно, мы хотим, чтобы модель в процессе обучения сформировала специальный механизм забывания: когда приходит новая входная информация, модель должна знать, какие знания следует продолжать помнить, а какие следует забыть.
  2. Вентиль добавления (save gate), также называемый входным вентилем (input gate). Когда модель видит новое изображение, она должна определить, несет ли данное изображение какую-либо полезную информацию, которую стоит добавить в долговременную память. Может вам прислали статью о Кардашянах, но кому это интересно? Таким образом, при поступлении новых входных данных модель сначала забывает всю долговременную информацию, которая, по ее мнению, больше не понадобится. Затем она определяет, какие элементы входной информации могут быть полезны, и добавляет их в долговременную память.
  3. Вентиль фокусировки (focus gate), также называемый вентилем внимания (attention gate) или выходным вентилем (output gate). Наконец, модель должна определить, какие элементы долговременной памяти могут пригодиться в самое ближайшее время. Например, возраст Боба является полезной информацией, которую имеет смысл хранить в долговременной памяти (дети вероятнее ползают, взрослые вероятнее работают), но если Боба нет в данной сцене, эта информация, скорее всего, не пригодится. Поэтому, вместо того, чтобы всегда использовать всю долговременную память, сеть обучается фокусировать внимание на определенных ее элементах.

Описанную концепцию реализует LSTM-сеть (long short-term memory network). В то время как РНС обновляет свою память в каждый момент времени достаточно неконтролируемым образом, LSTM-сеть оперирует своей памятью интеллектуально. С помощью описанных выше механизмов обучения, она определяет, какие элементы информации необходимо забыть, какие добавить, а на каких необходимо сфокусировать внимание. Такой подход позволяет отслеживать информацию в течение более длительных интервалов времени.

Математическая формулировка

В момент времени t сеть получает новые входные данные  x_t. Долговременная память [latex] ltm_{t-1} [/latex] и рабочая память [latex] wm_{t-1} [/latex] (обе представлены в виде n-мерных векторов) поступают с предыдущего момента времени. Обе памяти должны быть обновлены.

Мы начинаем с долговременной памяти. Во-первых, сеть должна выяснить, какие элементы долговременной памяти (long-term memory) необходимо забыть, а какие продолжать помнить. Она использует входные данные и рабочую память (working memory) для того, чтобы вычислить вентиль остаточной памяти (remember gate). Этот вентиль представляет собой вектор, содержащий n чисел в интервале от 0 до 1, каждое из которых определяет, какую долю данного элемента долговременной памяти следует продолжать помнить. В частности, 1 означает продолжать полностью помнить элемент, 0 означает полностью забыть его.

Мы можем использовать маленькую нейронную сеть, чтобы вычислить вентиль остаточной памяти:

[latex] remember_t = \sigma(W_r x_t + U_r wm_{t-1}) [/latex] 

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

Далее, необходимо вычислить информацию, которую мы можем извлечь из [latex] x_t [/latex], и которая будет кандидатом на добавление в долговременную память:

[latex] ltm’_t = \phi(W_l x_t + U_l wm_{t-1}) [/latex] 

где [latex] \phi [/latex] – это функция активации, обычно [latex] tanh [/latex].

Однако прежде чем добавить кандидата в долговременную память, необходимо определить, какие его элементы действительно могут быть полезныДля этого необходимо вычислить вентиль добавления (save gate):

[latex] save_t = \sigma(W_s x_t + U_s wm_{t-1}) [/latex] 

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

[latex] ltm_t = remember_t \circ ltm_{t-1} + save_t \circ ltm’_t [/latex] 

где [latex] \circ [/latex] обозначает поэлементное умножение.

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

[latex] focus_t = \sigma(W_f x_t + U_f wm_{t-1}) [/latex] 

Вычисляем рабочую память:

[latex] wm_t = focus_t \circ \phi(ltm_t) [/latex] 

То есть мы уделяем максимальное внимание тем элементам, для которых фокус равен 1, и игнорируем элементы, для которых фокус равен 0.

Готово! Надеюсь, вы добавили эту информацию в вашу собственную долговременную память.

Подведем итог. Обычная РНС использует одно уравнение, для обновления своего скрытого состояния (памяти):

[latex] h_t = \phi(Wx_t + Uh_{t-1}) [/latex] 

LSTM-сеть использует для этого несколько уравнений:

[latex] ltm_t = remember_t \circ ltm_{t-1} + save_t \circ ltm’_t [/latex] 

[latex] wm_t = focus_t \circ tanh(ltm_t) [/latex] 

где

 remember_t = \sigma(W_r x_t + U_r wm_{t-1}) 

save_t = \sigma(W_s x_t + U_s wm_{t-1})

focus_t = \sigma(W_f x_t + U_f wm_{t-1})

ltm’_t = tanh(W_l x_t + U_l wm_{t-1})

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

  • Долговременная память (long-term memory), [latex] ltm_t [/latex], обычно называется состоянием ячейки (cell state) и обозначается [latex] c_t [/latex].
  • Рабочая память (working memory), [latex] wm_t [/latex], обычно называется скрытым состоянием (hidden state) и обозначается [latex] h_t [/latex]. Это аналог скрытого состояния обычной РНС.
  • Вентиль остаточной памяти (remember gate), вектор remember_t , обычно называется вентилем забывания (forget gate) (несмотря на тот факт, что 1 по-прежнему означает продолжать помнить элемент памяти, а 0 означает забыть) и обозначается [latex] f_t [/latex].
  • Вентиль добавления (save gate), вектор save_t , обычно называется входным вентилем (input gate) (поскольку он определяет, какую часть входной информации следует пропустить в состояние ячейки) и обозначается [latex] i_t [/latex].
  • Вентиль фокусировки (focus gate), вектор [latex] focus_t [/latex], обычно называется выходным вентилем (output gate) и обозначается [latex] o_t [/latex].

Снорлакс

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

Нейронная сеть

P(Снорлакс купается) = 0.6

P(Снорлакс пьет воду) = 0.3

P(Снорлакс атакован) = 0.1

Нейронная сеть

Я вижу Снорлакса и воду.

Вероятно, он купается.

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

P(Покемон атакует) = 0.85

P(Покемон купается) = 0.1

P(Покемон пускает пузыри) = 0.05

 

P(Снорлакс атакован) = 0.6

P(Снорлакс купается) = 0.3

P(Снорлакс пьет воду) = 0.1

Скрытое состояние (память)

 

Сцена битвы началась

РНС

 

Я знаю, что идет битва, и я вижу воду, летящую изо рта покемона. Вероятно, он атакует.

Скрытое состояние (память)

 

Продолжается битва.

Противник начал атаку.

Противник – водный покемон.

 

РНС

 

Я помню, что продолжается битва.

Я вижу Снорлакса и воду. Вероятно, он атакован.

 

Скрытое состояние (память)

 

Продолжается битва.

Снорлакс атакован водой.

Противник – водный покемон.

LSTM-сеть

P(Снорлакс атакован) = 0.9

P(Снорлакс купается) = 0.05

P(Снорлакс пьет воду) = 0.05

Долговременная память

 

Снорлакс любит бамбук.

Битва длится 1 минуту.

Противник в центре кадра.

 

Рабочая память

 

Битва длится 1 минуту.

Противник в центре кадра.

LSTM-сеть

 

Что нужно забыть?

Положение противника в кадре.

 

Какую новую информацию нужно добавить?

Выражение боли на лице Снорлакса.

 

Что нужно проигнорировать?

Пищевые предпочтения Снорлакса.

 

 

Долговременная память

 

Снорлакс любит бамбук.

Битва длится 2 минуты.

Снорлакс атакован водой.

Снорлаксу больно.

 

Рабочая память

 

Битва длится 2 минуты.

Снорлакс атакован водой.

Снорлаксу больно.

 

Продолжение следует…

Источник

Перевод Станислава Петренко

1 комментарий

  1. Аноним:

    очень классно!!

Добавить комментарий

Ваш адрес email не будет опубликован.

закрыть

Поделиться

Отправить на почту
закрыть

Вход

закрыть

Регистрация

+ =