Курс по нейронным сетям: https://stepik.org/a/227582
Рассмотренная
простейшая рекуррентная НС – это не самая лучшая архитектура. Основным ее
недостатком является быстрое «забывание» прошлого контекста. А иногда он важен.
Например, такой текст:
Я
очень люблю программировать, …, поэтому в будущем хочу стать программистом.
Смотрите, здесь
вначале упоминается любовь к программированию, а затем идут какие-то
отвлеченные слова. И только в конце снова появляется слово «программистом»,
связанное по смыслу с программированием. Так вот, чтобы сеть имела возможность
спрогнозировать это слово, исходя из контекста, она должна четко схватывать
нужный прошлый контекст и не обращать внимания на второстепенный. Простейшая
архитектура 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.
Курс по нейронным сетям: https://stepik.org/a/227582