MLエンジニアへの道 #26 - LSTM

Last Edited: 10/12/2024

このブログ記事では、ディープラーニングにおけるLSTMについて紹介します。

ML

前回のRNNに関する記事では、RNNが逆伝播の際に不安定な勾配の問題に直面することが多いことを説明しましたが、 前向き伝播にも同様の問題があります。前の入力や活性化が重要であっても、乗算を繰り返すうちに簡単に忘れられてしまうことがあるのです。

例えば、RNNが「I confirmed the validity of the document, so I put a seal on it,」という文を処理するとき、 文脈が「document(書類)」に関連していることを簡単に忘れてしまう可能性があります。これは「seal」という単語の意味に非常に関係しています。 「seal」には、文脈によって動物や公的な印、スタンプなど複数の意味がありますが、理想的にはRNNは文脈を覚えておき、「seal」の意味をかわいい海洋動物ではなく、公的な印やスタンプと解釈すべきです。 この長期的な記憶を保持し、勾配消失問題を回避するために、 Long Short-Term Memory(LSTM) という新しいタイプの再帰型ニューラルネットワークが発明されました。

LSTM

LSTMは、主に4つのゲート(関連性ゲート、入力ゲート、忘却ゲート、出力ゲート)から構成されており、 それぞれが長期および短期記憶に関するタスクを担当しています。ゲートの役割は異なりますが、 すべてのゲートは専用の重みとバイアスを用いて次のような操作を行います。

Γ=σ(Wxxt+Waat1+b) \Gamma = \sigma(W_x x^t + W_a a^{t-1} +b)

関連性ゲート (Γr\Gamma_r) は、前のタイムステップからの短期記憶を考慮して、現在の入力が長期記憶にどれほど関連しているかを決定します。 入力ゲート (Γi\Gamma_i) は、現在のタイムステップでの入力とその関連性に基づいて、長期記憶をどの程度更新するかを決定します。 忘却ゲート (Γf\Gamma_f) は、過去の長期記憶をどの程度忘れるかを決定し、出力ゲート (Γo\Gamma_o) はセルの新しい短期記憶(出力)を決定します。 活性化関数は、すべてのゲートでシグモイド関数が使用されますが、関連性ゲートは負の値を表現するためにtanh関数を使用します。 以下は、LSTMのセルのアーキテクチャを示しています。

LSTM

これをさらに詳細に数式で表すと、次のようになります:

c~t=Γrct=Γfct1+Γic~tat=Γotanh(ct) \tilde{c}^t = \Gamma_r \\ c^t = \Gamma_f \odot c^{t-1} + \Gamma_i \odot \tilde{c}^t \\ a^t = \Gamma_o \odot tanh(c^t)

長期記憶は「セル状態」と呼ばれ、通常 ctc^t と表されます。また、短期記憶は活性化として ata^t で表現されます。 上記の \odot は要素ごとの乗算、すなわちアダマール積を意味します。この構造から、LSTMのセルが長期記憶を保持することを明確に意図して設計されていることがわかります。 実際に、LSTMは単純なRNNよりも長期記憶を保持できることが実証されています。

また、LSTMのアーキテクチャから、勾配が単純なRNNよりも高く保たれることがわかります。これは、長期記憶からの勾配の追加があり、 ローカル勾配の乗算が少ないためです。(LSTMは ct1c^{t-1} に対して、要素ごとの乗算を2回、tanh活性化を1回行うだけです。)したがって、 このモデルは勾配消失問題に対して耐性が高くなりますが、それでもなお不安定な勾配の問題(特に勾配爆発)に悩まされることがあります。

NOTE: LSTMレイヤーは、TensorFlowやPyTorchの両方で事前定義されており、前回の記事で使用したRNNレイヤーと同様に動作します。 興味があれば、RNNレイヤーをLSTMに置き換えて、以前のモデルと比較して改善があるかを確認してみてください。

他の解決策

LSTMに加えて、リカレントニューラルネットワークの性能を向上させるためのいくつかの方法があります。 LSTMに似たアプローチとして、GRUがあります。これは、4つのゲートではなく、2つのゲートを使用して長期的な記憶を保持しようとします。 ここでは詳細には触れませんが、GRUレイヤーもTensorFlowとPyTorchの両方に定義されているので、 興味があれば、前回の記事で作成したモデルのレイヤーを単に入れ替えるだけで試すことができます。

モデルのレイヤーを変更する以外にも、モデル全体のアーキテクチャを変更する別のアプローチがあります。 その一つが双方向RNNです。これは、過去と未来の両方の文脈を活用するために、入力を双方向に処理します。 この方法は、機械翻訳や音声認識のようなシーケンスtoシーケンスモデルに適しているかもしれません。 TensorFlowではtf.keras.layers.Bidirectionalを使用し、PyTorchではレイヤーのbidirectionalパラメータをTrueに設定することで簡単に実装できます。 また、複数のRNNレイヤーを積み重ねて、各レイヤーが異なるレベルの隠れた特徴を学習する「ディープRNN」を簡単に作成することもできます。

結論

この記事では、LSTMがどのようにして長期的な記憶保持を実現し、勾配消失問題を防ぐために発明されたか、 そしてLSTMがどのように機能するかを説明しました。また、GRU、双方向RNN、ディープRNNなど、モデルの性能を段階的に向上させることができる他の解決策についても簡単に触れました。 しかし、不安定な勾配の問題は依然として残っています。次の記事では、正規化を用いてこの問題にどのように対処できるかをさらに探っていきます。

リソース