LSTM - долгая краткосрочная память

Рассмотренная простейшая рекуррентная НС – это не самая лучшая архитектура. Основным ее недостатком является быстрое «забывание» прошлого контекста. А иногда он важен. Например, такой текст:

Я очень люблю программировать, …, поэтому в будущем хочу стать программистом.

Смотрите, здесь вначале упоминается любовь к программированию, а затем идут какие-то отвлеченные слова. И только в конце снова появляется слово «программистом», связанное по смыслу с программированием. Так вот, чтобы сеть имела возможность спрогнозировать это слово, исходя из контекста, она должна четко схватывать нужный прошлый контекст и не обращать внимания на второстепенный. Простейшая архитектура RNN плохо учитывает такие моменты. Она, как правило, все смешивает в одну кучу и то, что встречалось вначале быстро теряется. Хотя, исследователи говорят, что это скорее недостаток алгоритма обучения, а не архитектуры. Было показано на простых задачах, что теоретически веса можно настроить так, чтобы сеть корректно учитывала даже длинный и сложный контекст. Но на практике этого достичь не удается. Поэтому в 1997 году Зеппом Хохрайтер и Юргеном Шмидхубером (Jürgen Schmidhuber) была предложена другая архитектура известная под названием «долгая краткосрочная память»:

LSTM (Long short-term memory)

которая при обучении способна схватывать существенные детали прошлого контекста и сохранять их, пока они актуальны. Эта архитектура была основной «рабочей лошадкой» рекуррентных сетей вплоть до 2017 года. И сегодня остается весьма востребованной во многих прикладных задачах. Давайте с ней познакомимся поближе.

В базовом исполнении рекуррентный блок LSTM выглядит следующим образом (эти блоки еще называют ячейками):

Давайте теперь разберем принцип работы этой ячейки. Отличительной чертой архитектуры LSTM является наличие вот этой верхней трубы, по которой, как бы движется вектор контекста:

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

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

Здесь  - весовые коэффициенты этого слоя;  - объединенный вектор из двух векторов;  - смещение (биас);  - сигмоидальная функция (на выходе дает диапазон [0; 1]). В результате, вектор  будет состоять из чисел от 0 до 1 и иметь ту же размерность, что и вектор контекста :

И при поэлементном умножении из вектора  будут убираться незначимые, с точки зрения блока LSTM, величины. Но все-таки, откуда сеть может знать: что оставить, а что нет? Как раз это определяется в процессе ее обучения, то есть, подбором весовых коэффициентов . Правильно обученная сеть будет, в среднем, корректно ослаблять ненужные величины вектора долгосрочного контекста . Вот такая «магия» нейронных сетей.

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

а, затем, они поэлементно умножаются:

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

Так в блоке LSTM меняется долгосрочный контекст от итерации к итерации.

Наконец, последний этап работы блока – это формирование выходного скрытого состояния :

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

Далее, вектор долгосрочного контекста (памяти)  нормируется, проходя поэлементно через функцию tanh – гиперболический тангенс. На выходе получим значения в диапазоне [-1; 1]. Затем, эти нормированные величины поэлементно умножаются на оценочный вектор и формируется вектор скрытого состояния текущей итерации:

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

Я очень люблю программировать, программирование – это круто, поэтому в будущем хочу стать программистом.

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

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

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

Мы рассмотрели с вами лишь базовую (простейшую) архитектуру LSTM-блока. На практике применяют разные их разновидности. Но все они работают по похожему принципу. На следующем занятии мы продолжим эту тему и рассмотрим решение задачи сентимент-анализа коротких текстовых сообщений с помощью архитектуры LSTM.

Видео по теме