Перейти к основному содержимому

Модели LSTM и GRU

Модели LSTM и GRU представляют собой усложнённые версии классической рекуррентной сети и были специально разработаны, чтобы обрабатывать длинные последовательности и лучше помнить историю из ранее виденных наблюдений.

Эти модели преобразуют входную последовательность x1x2...xTx_1x_2...x_T в последовательность состояний h1h2...hTh_1h_2...h_T, использующихся внешними моделями (такими как многослойный персептрон), строящими уже итоговые прогнозы.

И входы и внутренние состояния являются векторами вещественных чисел.

Гейты в нейронных сетях

Улучшенная память моделей LSTM и GRU достигается заменой многократных перемножений матриц при учёте истории наблюдений операциями взвешенной суммы, где веса суммирования рассчитываются специальными функциями, называемых гейтами (gates). В русскоязычной литературе их также называют вентилями.

Гейты представляют собой вектора чисел, принимающих значения в отрезке [0,1] и управляют потоками данных, проходящих через нейросеть. Для этого вектора данных поэлементно домножаются на вектора гейтов.

  • Когда значение гейта равно 0, гейт закрыт и информацию не пропускает.

  • Когда значение гейта равно 1, гейт открыт, и информация свободно проходит.

Рассмотрим пример, когда нам нужно обновить состояние hth_t по входным данным xtx_t и известному прошлому состоянию ht1h_{t-1} при следующих значениях:

xt=(1234),ht1=(10203040)x_t=\left(\begin{array}{c} 1\\ 2\\ 3\\ 4 \end{array}\right),\quad h_{t-1}=\left(\begin{array}{c} 10\\ 20\\ 30\\ 40 \end{array}\right)

Мы могли бы это сделать, пропустив xtx_t и ht1h_{t-1} через линейное преобразование, как сделано в простейшей рекуррентной сети Элмана. Однако оно предполагает умножение на матрицу, которое будет производиться многократно при обработке последовательности и настройке сети методом truncated BPTT. Это, в свою очередь, будет приводить к численной неустойчивости, сводящейся либо к тому, что сеть будет экспоненциально быстро забывать историю, либо вклад исторических наблюдений наоборот будет экспоненциально быстро возрастать.

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

Пусть, для примера, мы хотим обновить состояние hth_t на нечётных позициях из входа xtx_t, а на чётных позициях оставить значения предыдущего состояния ht1h_{t-1}.

Это легко реализовать с помощью следующего гейта gtg_t:

gt=(1010),1gt=(0101)g_t=\left(\begin{array}{c} 1\\ 0\\ 1\\ 0 \end{array}\right),\quad1-g_t=\left(\begin{array}{c} 0\\ 1\\ 0\\ 1 \end{array}\right)

и операции

ht=gtxt+(1gt)ht1,h_t=g_t\odot x_t + (1-g_t)\odot h_{t-1},

где \odot обозначает поэлементное перемножение векторов.

В итоге получим требуемый результат:

ht=(120340)h_t = \left(\begin{array}{c} 1\\ 20\\ 3\\ 40 \end{array}\right)

Таким образом, открытые элемента вектора гейта приводят к обновлению информации, а закрытые - к её сохранению.

Если информация действительно важна, то её можно сохранять очень долго, что позволяет сети, основанной на гейтах, эффективно учитывать долгосрочные зависимости в данных!

Гейты реализуются линейными слоями с сигмоидной функцией активации σ()\sigma(\cdot) в выходном слое.

GRU

Модель GRU была предложена в [1]. Формула пересчёта состояния hth_t по входу xtx_t и предыдущему состоянию ht1h_{t-1} модели GRU приведена ниже:

rt=σ(Wrxt+Urht1+br)reset gatezt=σ(Wzxt+Uzht1+bz)update gateh~t=tanh(Whxt+Uh(rtht1)+bh)proposalht=(1zt)ht1+zth~tstate\begin{align*} {\color{green}\mathbf{r_{t}}} &=\sigma\left(W_{r}\mathbf{x_{t}}+U_{r}\mathbf{h_{t-1}}+\mathbf{b_{r}}\right) &\text{reset gate} \\ \mathbf{{\color{brown}z}_{{\color{brown}t}}} &=\sigma\left(W_{z}\mathbf{x_{t}}+U_{z}\mathbf{h_{t-1}}+\mathbf{b_{z}}\right) &\text{update gate} \\ \tilde{\mathbf{h}}_t &= \text{tanh}\left(W_{h}\mathbf{x_{t}}+U_{h}\left(\mathbf{{\color{green}r_{t}}\odot h_{t-1}}\right)+\mathbf{b_{h}}\right) &\text{proposal} \\ \mathbf{h}_{t} &= \left(1-\mathbf{{\color{brown}z}_{{\color{brown}t}}}\right)\odot\mathbf{h_{t-1}}+\mathbf{{\color{brown}z_{t}}}\odot \tilde{\mathbf{h}}_t &\text{state} \\ \end{align*}

В модели используются два гейта - гейт перезапуска rt\mathbf{r}_t и гейт обновления zt\mathbf{z}_t. В формуле пересчёта они выделены цветом.

Параметры модели:

  • матрицы Wz,Uz,Wr,Ur,Wh,UhW_z, U_z, W_r, U_r, W_h, U_h;

  • векторы bz,br,bh\mathbf{b}_{z}, \mathbf{b}_{r}, \mathbf{b}_{h}.

LSTM

Модель LSTM была предложена в [2]. Формула пересчёта состояния hth_t по входу xtx_t и предыдущему состоянию ht1h_{t-1} модели LSTM приведена ниже:

ft=σ(Wfxt+Ufht1+bf)forget gateit=σ(Wixt+Uiht1+bi)input gateot=σ(Woxt+Uoht1+b0)output gatec~t=tanh(Wcxt+Ucht1+bc)proposalct=ftct1+itc~tmemory cellht=ottanh(ct) state\begin{align*} {\color{green}\mathbf{f_{t}}} &=\sigma\left(W_{f}\mathbf{x_{t}}+U_{f}\mathbf{h_{t-1}}+\mathbf{b_{f}}\right) &\text{forget gate}\\ \mathbf{{\color{magenta}i}_{{\color{magenta}t}}} &=\sigma\left(W_{i}\mathbf{x_{t}}+U_{i}\mathbf{h_{t-1}}+\mathbf{b_{i}}\right) &\text{input gate} \\ \mathbf{{\color{brown}o}_{{\color{brown}t}}} &=\sigma\left(W_{o}\mathbf{x_{t}}+U_{o}\mathbf{h_{t-1}}+\mathbf{b_{0}}\right) &\text{output gate}\\ \tilde{\mathbf{c}}_t &= \text{tanh}\left(W_{c}\mathbf{x_{t}}+U_{c}\mathbf{h_{t-1}}+\mathbf{b_{c}}\right) &\text{proposal} \\ \mathbf{\mathbf{c}_{t}} &=\mathbf{{\color{green}f_{t}}}\odot\mathbf{c_{t-1}}+{\color{magenta}\mathbf{i_{t}}}\odot \tilde{\mathbf{c}}_t &\text{memory cell}\\ \mathbf{h_{t}} &={\color{brown}\mathbf{o_{t}}}\odot \text{tanh}\left(\mathbf{c_{t}}\right) &\text{ state} \end{align*}

В сети используются 3 гейта, выделенных цветом:

  • гейт забывания ft\mathbf{f}_t;

  • входной гейт it\mathbf{i}_t;

  • выходной гейт ot\mathbf{o}_t.

Дополнительно используется вектор памяти (memory cell) ct\mathbf{c}_t для внутренних вычислений. Выходом сети служит состояние ht\mathbf{h}_t.

Не совсем forget...

Как видно из формул пересчёта, открытый forget-гейт будет приводить не к забыванию памяти ct1\mathbf{c}_{t-1}, а наоборот к сохранению. Правильнее было бы его назвать "remember gate".

Параметры модели:

  • матрицы Wf,Uf,Wi,Ui,Wo,Uo,Wc,UcW_f, U_f, W_i, U_i, W_o, U_o, W_c, U_c;

  • векторы bf,bi,bo,bc\mathbf{b}_{f}, \mathbf{b}_{i}, \mathbf{b}_{o}, \mathbf{b}_{c}.

Как видим, у LSTM больше параметров, чем у GRU. Тем не менее, GRU способна моделировать те же особенности поведения, что и LSTM. Итоговый выбор между моделями нужно делать на основе качества работы каждой модели на данных.

Рекомендация по инициализации

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

Интересно, что модель LSTM, будучи значительно сложнее GRU, была предложена на 17 лет раньше!

Преимущества

Используя гейты, сети GRU и LSTM могут производить следующие действия при обработке текстов (как последовательностей слов):

  1. запоминать информацию, которая была очень давно, например, в начале предложения;

  2. игнорировать часть входной информации, которая не релевантна решаемой задаче (например, комментарии или html-тэги);

  3. перезапускаться "с чистого листа" по достижении логического разрыва в тексте (например, начала новой главы).

Эти же возможности доступны, если применять модели LSTM и GRU к последовательностям других типов данных.

Задача

Подумайте, какие гейты должны быть открыты/закрыты, чтобы GRU и LSTM реализовывали каждый из сценариев 1,2,3.

Как и обычные рекуррентные сети, модели GRU и LSTM могут эффективно применяться в режимах many-to-one, one-to-many и many-to-many, а для большей выразительной силы над ними можно производить те же усложнения (наслаивание, проброс связей, двунаправленность, гиперсеть и т.д.).

Примеры генерации текстов

Сети LSTM и GRU в задаче языкового моделирования способны генерировать довольно реалистичные тексты.

Например, если обучить LSTM на произведениях Шекспира, то можем получить следующий результат [3]:

А если обучать LSTM на исходном коде Linux, то сеть будет генерировать новые реалистичные программы [3]:

Альтернативные более простые подходы

Хотя LSTM и GRU представляют собой стандартные усложнения рекуррентных сетей для лучшего запоминания и учёта исторических наблюдений, для полноты обзора отметим и менее популярные, зато более простые подходы по модификации рекуррентной сети Элмана для решения той же задачи.

В [4] предложено инициализировать матрицу пересчета старого состояния по новому WhhW_{hh} единичной матрицей, а вектор bh\mathbf{b}_h - нулевыми значениями. Во время оптимизации эти параметры могут свободно меняться, однако благодаря подобной инициализации вначале сеть умеет помнить всю историю, аккумулируя старые состояния.

В [5] предложено разделить внутреннее состояние ht\mathbf{h}_t на два подвектора:

  • быстро меняющаяся компонента

  • и медленно меняющаяся компонента.

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

Литература

  1. Cho K. et al. Learning phrase representations using RNN encoder-decoder for statistical machine translation //arXiv preprint arXiv:1406.1078. – 2014.
  2. Hochreiter S. Long Short-term Memory //Neural Computation MIT-Press. – 1997.
  3. http://karpathy.github.io/2015/05/21/rnn-effectiveness/
  4. Le Q. V., Jaitly N., Hinton G. E. A simple way to initialize recurrent networks of rectified linear units //arXiv preprint arXiv:1504.00941. – 2015.
  5. Mikolov T. et al. Learning longer memory in recurrent neural networks //arXiv preprint arXiv:1412.7753. – 2014.