深層学習入門 (61) リカレント ニューラル ネットワーク - 長短期記憶ネットワーク LSTM
序文
核心的な内容はブログリンク1ブログリンク2からです作者をたくさん応援していただければ幸いです
この記事は忘れないための記録用です
リカレント ニューラル ネットワーク - 長短期記憶ネットワーク LSTM
コースウェア
長短期記憶ネットワーク
Forget Gate: 値を 0 に向けてデクリメントします。
Input Gate: 入力データを無視するかどうかを決定します。
Output Gate: 非表示状態を使用するかどうかを決定します。
ドア
候補メモリユニット
メモリユニット
隠れた状態
要約する
I t = σ ( X t W xi + H t − 1 W hi + bi ) 、F t = σ ( X t W xf + H t − 1 W hf + bf ) 、O t = σ ( X t W xo + H t − 1 W ho + bo ) , \begin{aligned}\begin{aligned} \mathbf{I}_t &= \sigma(\mathbf{X}_t \mathbf{W}_{xi} + \mathbf{ H}_{t-1} \mathbf{W}_{hi} + \mathbf{b}_i),\\\mathbf{F}_t &= \sigma(\mathbf{X}_t \mathbf{W} _{xf} + \mathbf{H}_{t-1} \mathbf{W}_{hf} + \mathbf{b}_f),\\ \mathbf{O}_t &= \sigma(\mathbf{ X}_t \mathbf{W}_{xo} + \mathbf{H}_{t-1} \mathbf{W}_{ho} + \mathbf{b}_o),\\ \end{aligned}\終わり{整列}私たFた○た=s ( XたW×私+Ht − 1Wこんにちは+b私は)、=s ( XたW× f+Ht − 1Wふふ_+bふ)、=s ( XたW× ○+Ht − 1Wほら_+bああ)、
C ~ t = Tanh ( X t W xc + H t − 1 W hc + bc ) 、 C t = F t ⊙ C t − 1 + I t ⊙ C ~ t 。H t = O t ⊙ Tanh ( C t ) 。\tilde{\mathbf{C}}_t = \text{tanh}(\mathbf{X}_t \mathbf{W}_{xc} + \mathbf{H}_{t-1} \mathbf{W}_ {hc} + \mathbf{b}_c),\\ \mathbf{C}_t = \mathbf{F}_t \odot \mathbf{C}_{t-1} + \mathbf{I}_t \odot \チルダ{\mathbf{C}}_t.\\ \mathbf{H}_t = \mathbf{O}_t \odot \tanh(\mathbf{C}_t)。C~た=怪しい( X .)たW× c+Ht − 1Whc _+bc)、Cた=Fた⊙Ct − 1+私た⊙C~た。Hた=○た⊙胡散臭い( _た)。
教科書
潜在変数モデルには長い間、長期的な情報の保存と短期的な入力の欠落という問題がありました。この問題に対する初期のアプローチの 1 つは長短期記憶 (LSTM) でした。これには、ゲート付き反復ユニットと同じ特性が多くあります。興味深いことに、長期短期記憶ネットワークの設計はゲート型リカレント ユニットよりもわずかに複雑ですが、ゲート型リカレント ユニットよりも 20 年近く早く誕生しました。
1 ゲート メモリ セル
長短期記憶ネットワークの設計は、コンピューターの論理ゲートからインスピレーションを得ていると言えます。長期短期記憶ネットワークが導入され记忆元(memory cell)
、または単に と呼ばれます单元(cell)
。一部の文献では、メモリ セルは特殊なタイプの隠れ状態であり、隠れ状態と同じ形状を持ち、その設計目的は追加情報を記録することであると考えられています。メモリセルを制御するには、多くのゲートが必要です。ゲートの 1 つは、セルからエントリを出力するために使用されます。これを と呼びます输出门(output gate)
。別のゲートは、いつデータをセルに読み込むかを決定するために使用されます。これを と呼びます输入门(input gate)
。また、セルの内容をリセットするメカニズムも必要です。これは、ゲート付きリカレント セルと同じ設計動機遗忘门(forget gate)
によって、専用のメカニズムを通じて隠し状態での入力をいつ記憶するか無視するかを決定できます。これが実際にどのように機能するかを見てみましょう。
1.1 入力ゲート、忘却ゲート、出力ゲート
ゲート付きリカレント ユニットと同様に、図に示すように、現在のタイム ステップの入力と前のタイム ステップの隠れ状態がデータとして LSTM ネットワークのゲートに入力されます。これらは、入力ゲート、忘却ゲート、および出力ゲートの値を計算するために、シグモイド活性化関数を備えた 3 つの完全に接続された層によって処理されます。したがって、3 つのゲートすべての値は(0, 1) (0, 1)になります。( 0 ,1 )範囲内であること。
長短期記憶ネットワークの数式を洗練させてみましょう。hhがあるとしますh隠れユニット、バッチ サイズnnn、入力番号はddd . したがって、入力はX t ∈ R n × d \mathbf{X}_t \in \mathbb{R}^{n \times d} となります。バツた∈Rn × d、前のタイム ステップの隠れ状態はH t − 1 ∈ R n × h \mathbf{H}_{t-1} \in \mathbb{R}^{n \times h}Ht − 1∈Rn × h。同様に、タイムステップtttのゲートは次のように定義されます。 入力ゲートはI t ∈ R n × h \mathbf{I}_t \in \mathbb{R}^{n \times h} です。私た∈Rn × h、忘却ゲートはF t ∈ R n × h \mathbf{F}_t \in \mathbb{R}^{n \times h}Fた∈Rn × h、出力ゲートはO t ∈ R n × h \mathbf{O}_t \in \mathbb{R}^{n \times h}○た∈Rn × hの場合、次の関数形式は次のとおりです。
I t = σ ( X t W xi + H t − 1 W hi + bi ) 、 F t = σ ( X t W xf + H t − 1 W hf + bf ) , . O t = σ ( X t W xo + H t − 1 W ho + bo ) , \begin{split}\begin{aligned} \mathbf{I}_t &= \sigma(\mathbf{X}_t \ mathbf{ W}_{xi} + \mathbf{H}_{t-1} \mathbf{W}_{hi} + \mathbf{b}_i),\\\mathbf{F}_t &= \sigma (\ mathbf{X}_t \mathbf{W}_{xf} + \mathbf{H}_{t-1} \mathbf{W}_{hf} + \mathbf{b}_f),\\ \mathbf {O }_t &= \sigma(\mathbf{X}_t \mathbf{W}_{xo} + \mathbf{H}_{t-1} \mathbf{W}_{ho} + \mathbf{b }_o )、\end{整列}\end{分割}私たFた○た=s ( XたW×私+Ht − 1Wこんにちは+b私は)、=s ( XたW× f+Ht − 1Wふふ_+bふ)、=s ( XたW× ○+Ht − 1Wほら_+bああ)、
その中W xi , W xf , W xo ∈ R d × h \mathbf{W}_{xi}, \mathbf{W}_{xf}, \mathbf{W}_{xo} \in \mathbb{R} ^{d \times}W×私、W× f、W× ○∈Rd × h和W hi , W hf , Who ∈ R h × h \mathbf{W}_{hi}, \mathbf{W}_{hf}, \mathbf{W}_{ho} \in \mathbb {R}^{h \times}Wこんにちは、Wふふ_、Wほら_∈Rh × h是权重パラメータ,bi , bf , bo ∈ R 1 × h \mathbf{b}_i, \mathbf{b}_f, \mathbf{b}_o \in \mathbb{R}^{1 \times h }b私は、bふ、bああ∈R1 × hはバイアスパラメータです。
1.2 候補メモリ要素
さまざまなゲートの動作が指定されていないため、まず候选记忆元(candidate memory cell)
C ~ t ∈ R n × h \tilde{\mathbf{C}}_t \in \mathbb{R}^{n \times h} を導入しましょう。C~た∈Rn × h。その計算は、上で説明した 3 つのゲートの計算と似ていますが、活性化関数として Tanh 関数を使用し、関数の値の範囲は (− 1 , 1 ) (-1, 1)( − 1 、1 )。以下はタイム ステップの方程式を導出します:
C ~ t = Tanh ( X t W xc + H t − 1 W hc + bc ) , \tilde{\mathbf{C}}_t = \text{tanh}(\mathbf{ X}_t \mathbf{W}_{xc} + \mathbf{H}_{t-1} \mathbf{W}_{hc} + \mathbf{b}_c)、C~た=怪しい( X .)たW× c+Ht − 1Whc _+bc) ,
其中W xc ∈ R d × h \mathbf{W}_{xc} \in \mathbb{R}^{d \times h}W× c∈Rd × h和W hc ∈ R h × h \mathbf{W}_{hc} \in \mathbb{R}^{h \times h}Whc _∈Rh × hは重みパラメータ、bc ∈ R 1 × h \mathbf{b}_c \in \mathbb{R}^{1 \times h}bc∈R1 × hはバイアスパラメータです。
候補となるメモリセルを図に示します。
1.3 思い出
ゲート型反復ユニットには、入力と忘却 (またはスキップ) を制御するメカニズムがあります。同様に、LSTM ネットワークにも、この目的のための 2 つのゲートがあります。 入力ゲートI t \mathbf{I}_t私たコントロールはC ~ t \tilde{\mathbf{C}}_tからどのくらいの量を取得しますかC~た新しいデータと忘却ゲートF t \mathbf{F}_tFた過去の記憶要素の数を制御C t − 1 ∈ R n × h \mathbf{C}_{t-1} \in \mathbb{R}^{n \times h}Ct − 1∈Rn × hの内容。要素ごとの乗算を使用すると、次のようになります:
C t = F t ⊙ C t − 1 + I t ⊙ C ~ t . \mathbf{C}_t = \mathbf{F}_t \odot \mathbf{C}_{t - 1} + \mathbf{I}_t \odot \tilde{\mathbf{C}}_t。Cた=Fた⊙Ct − 1+私た⊙C~た
忘却ゲートが常に 1 で、入力ゲートが常に 0 の場合、過去の記憶要素C t − 1 \mathbf{C}_{t-1}Ct − 1時間の経過とともに保存され、現在のタイム ステップに渡されます。この設計は、勾配消失の問題を軽減し、シーケンス内の長距離依存関係をより適切に捕捉するために導入されました。
このようにして、図に示すようなメモリ要素を計算するフローチャートが得られます。
1.4 隠し状態
最後に、隠れ状態H t ∈ R n × h \mathbf{H}_t \in \mathbb{R}^{n \times h} を計算する方法を定義する必要があります。Hた∈Rn × hであり、ここで出力ゲートが登場します。LSTM ネットワークでは、これは単にメモリ要素の正接のゲート バージョンです。これにより、H t \mathbf{H}_tHたの値は常に( − 1 , 1 ) (-1, 1)の範囲内にあります。( − 1 、1 )内:
H t = O t ⊙ Tanh ( C t ) 。\mathbf{H}_t = \mathbf{O}_t \odot \tanh(\mathbf{C}_t)。Hた=○た⊙胡散臭い( _た) .
出力ゲートが 1 に近い限り、すべてのメモリ情報を予測部分に効果的に渡すことができますが、出力ゲートが 0 に近い場合は、メモリ セル内のすべての情報を更新せずに保持するだけです。隠れた状態。
以下の図は、データ フローをグラフィカルに表現したものです。
2 ゼロからの実装
ここで、LSTM ネットワークを最初から実装します。まず、Time Machine データセットをロードします。
import torch
from torch import nn
from d2l import torch as d2l
batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)
2.1 モデルパラメータの初期化
次に、モデルパラメータを定義して初期化する必要があります。前述したように、ハイパーパラメータはnum_hiddens
隠れユニットの数を定義します。標準偏差 0.01 のガウス分布に従って重みを初期化し、バイアス項を 0 に設定します。
def get_lstm_params(vocab_size, num_hiddens, device):
num_inputs = num_outputs = vocab_size
def normal(shape):
return torch.randn(size=shape, device=device)*0.01
def three():
return (normal((num_inputs, num_hiddens)),
normal((num_hiddens, num_hiddens)),
torch.zeros(num_hiddens, device=device))
W_xi, W_hi, b_i = three() # 输入门参数
W_xf, W_hf, b_f = three() # 遗忘门参数
W_xo, W_ho, b_o = three() # 输出门参数
W_xc, W_hc, b_c = three() # 候选记忆元参数
# 输出层参数
W_hq = normal((num_hiddens, num_outputs))
b_q = torch.zeros(num_outputs, device=device)
# 附加梯度
params = [W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc,
b_c, W_hq, b_q]
for param in params:
param.requires_grad_(True)
return params
2.2 モデルの定義
初期化関数では、長期短期記憶ネットワークの隠れ状態は额外
、値が 0、形状が である記憶要素を返す必要があります(批量大小,隐藏单元数)
。したがって、次の状態の初期化が得られます。
def init_lstm_state(batch_size, num_hiddens, device):
return (torch.zeros((batch_size, num_hiddens), device=device),
torch.zeros((batch_size, num_hiddens), device=device))
実際のモデルの定義は前に説明したものと同じです。3 つのゲートと 1 つの追加のメモリ セルが提供されます。隠れ状態のみが出力層に渡され、メモリ要素C t \mathbf{C}_tが渡されることに注意してください。Cた出力の計算には直接関与しません。
def lstm(inputs, state, params):
[W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc, b_c,
W_hq, b_q] = params
(H, C) = state
outputs = []
for X in inputs:
I = torch.sigmoid((X @ W_xi) + (H @ W_hi) + b_i)
F = torch.sigmoid((X @ W_xf) + (H @ W_hf) + b_f)
O = torch.sigmoid((X @ W_xo) + (H @ W_ho) + b_o)
C_tilda = torch.tanh((X @ W_xc) + (H @ W_hc) + b_c)
C = F * C + I * C_tilda
H = O * torch.tanh(C)
Y = (H @ W_hq) + b_q
outputs.append(Y)
return torch.cat(outputs, dim=0), (H, C)
2.3 トレーニングと予測
GRU セクションで行ったのと同じように、 「RNN 実装」セクションで紹介されたクラスをインスタンス化して、 RNNModelScratch
LSTM ネットワークをトレーニングしましょう。
vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_lstm_params,
init_lstm_state, lstm)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)
出力
perplexity 1.4, 22462.5 tokens/sec on cuda:0
time traveller for the brow henint it aneles a overrecured aback
travellerifilby freenotin s dof nous be and the filing and
3 簡潔な実装
高レベル API を使用すると、LSTM モデルを直接インスタンス化できます。高レベル API は、上で説明したすべての構成の詳細をカプセル化します。このコードは、Python の代わりにコンパイルされた演算子を使用して、前に説明した詳細の多くを処理するため、はるかに高速に実行されます。
num_inputs = vocab_size
lstm_layer = nn.LSTM(num_inputs, num_hiddens)
model = d2l.RNNModel(lstm_layer, len(vocab))
model = model.to(device)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)
出力:
perplexity 1.1, 330289.2 tokens/sec on cuda:0
time travelleryou can show black is white by argument said filby
travelleryou can show black is white by argument said filby
長期短期記憶ネットワークは、重要な状態制御を備えた典型的な潜在変数自己回帰モデルです。多層、残留接続、さまざまな種類の正則化など、長年にわたってその多くの変形が提案されてきました。ただし、LSTM ネットワークやゲート反復ユニットなどの他のシーケンス モデルをトレーニングするコストは、シーケンスの長距離依存性により非常に高くなります。以下では、Transformer などのより高度な代替モデルについて説明します。
4 まとめ
-
LSTM ネットワークには、入力ゲート、フォーゲット ゲート、出力ゲートの 3 種類のゲートがあります。
-
LSTM ネットワークの隠れ層出力は、「隠れ状態」と「記憶要素」で構成されます。非表示状態のみが出力層に渡され、メモリは完全に内部情報です。
-
長期短期記憶ネットワークは、勾配の消失と勾配の爆発を軽減できます。
参考文献
[1] Hochreiter, S.、および Schmidhuber, J. (1997)。長期の短期記憶。ニューラル計算、9(8)、1735-1780。