Long Short-Term Memory (LSTM)
LSTMは、ゲート付きセル状態によって長い系列にわたって情報を保持する再帰型ネットワークです。ゲート、数式、GRUとの比較、コードを解説します。
長短期記憶(LSTM)は、単純なRNNの隠れ状態に加えて、セル状態と呼ばれるゲート付きメモリを導入した再帰型ニューラルネットワーク(RNN)アーキテクチャです。これにより、数百から数千のタイムステップにわたって情報を保持できます。Sepp HochreiterとJürgen Schmidhuberは、単純なRNNが長期的な依存関係を学習できない原因である勾配消失問題を解決するため、1997年にLSTMを発表しました。論文では、1,000ステップを超える時間差をつなぐことが報告されています。2010年代には、LSTMが音声認識、機械翻訳、手書き文字認識を支えましたが、その後、多くの言語タスクでトランスフォーマーに取って代わられました。状態のサイズが一定で、ステップごとのコストも一定であることが重要な時系列分析、センサーストリーム、オンデバイスモデルでは、現在も広く使われています。
LSTMセルの仕組み#
各タイムステップtで、LSTMは入力xₜと前の隠れ状態hₜ₋₁を読み込み、それぞれ固有の重みを持つ3つのゲートと1つの候補値を計算します。ゲートにはsigmoid関数を使うため、各要素は0から1の範囲になります。候補値にはtanhを使うため、−1から1の範囲になります。
- 忘却ゲート: fₜ = σ(W_f xₜ + U_f hₜ₋₁ + b_f)は、古いセル状態の各要素をどれだけ保持するかを決定します。
- 入力ゲート: iₜ = σ(W_i xₜ + U_i hₜ₋₁ + b_i)は、候補値をどれだけ書き込むかを決定します。
- 候補値: gₜ = tanh(W_g xₜ + U_g hₜ₋₁ + b_g)は、新しい内容を提案します。
- 出力ゲート: oₜ = σ(W_o xₜ + U_o hₜ₋₁ + b_o)は、セルの内容をどれだけ出力するかを決定します。
2つの状態は、cₜ = fₜ ⊙ cₜ₋₁ + iₜ ⊙ gₜおよびhₜ = oₜ ⊙ tanh(cₜ)として更新されます。ここで⊙は要素ごとの乗算です。セル状態は長期メモリであり、隠れ状態は次のレイヤーと次のステップに渡される短期的な出力です。
セルの更新は加算的です。cₜに対するcₜ₋₁の勾配は要素ごとにfₜとなるため、忘却ゲートが1に近い状態を保つと、誤差信号が逆方向に伝わり、元論文で定数誤差カルーセルと呼ばれた経路を通じて、多くのステップにわたりほとんど変化しません。1997年のLSTMには忘却ゲートがなく、セルは情報を蓄積することしかできませんでした。2000年、Felix Gers、Schmidhuber、Fred Cumminsが、セルをリセットできるよう忘却ゲートを追加しました。現在の標準的なLSTMにはすべて忘却ゲートがあります。Rafal Jozefowiczらが2015年に推奨したように、忘却ゲートのバイアスを1に初期化すると、学習の初期にゲートが開いた状態を保つことができ、ネットワークは情報を記憶する状態から学習を始めます。
PyTorchでのLSTM#
PyTorchのnn.LSTMは、セルをシーケンス全体にわたって実行し、各ステップの隠れ状態と、最終的な隠れ状態およびセル状態を返します。以下のコードは、各フレームから畳み込みニューラルネットワーク(CNN)などで抽出したフレームごとの特徴ベクトルを使い、短い動画クリップを分類します。
import torch
from torch import nn
# 8 video clips, 16 frames each, 512 features per frame: (batch, time, features)
clips = torch.randn(8, 16, 512)
# One LSTM layer with a 128-dim hidden state, and a classifier over 5 actions
lstm = nn.LSTM(input_size=512, hidden_size=128, batch_first=True)
classifier = nn.Linear(128, 5)
# output holds h at every step; h_n and c_n are the final hidden and cell states
output, (h_n, c_n) = lstm(clips)
logits = classifier(h_n[-1])
print(f"output {tuple(output.shape)}, h_n {tuple(h_n.shape)}, c_n {tuple(c_n.shape)}, logits {tuple(logits.shape)}")
# Each weight matrix stacks four blocks of 128 rows: input gate, forget gate, candidate, output gate
print(f"Input weights {tuple(lstm.weight_ih_l0.shape)}, recurrent weights {tuple(lstm.weight_hh_l0.shape)}")output (8, 16, 128), h_n (1, 8, 128), c_n (1, 8, 128), logits (8, 5)とInput weights (512, 512), recurrent weights (512, 128)が出力されます。最終的な隠れ状態は、16フレームの各クリップを5クラス分類器向けに要約します。PyTorchでは4つのゲートブロックを1つの行列に格納するため、各重み行列の行数は4 × 128 = 512です。
LSTMと関連アーキテクチャの比較#
- 単純なRNN: 各ステップでtanhレイヤー1つを使って状態全体を書き換えます。そのため、勾配はシーケンス長に応じて幾何級数的に小さくなったり大きくなったりし、長期的な依存関係を学習するのが困難です。
- GRU: セル状態と隠れ状態を統合し、3つではなく2つのゲートを使います。同じ幅の場合、重みブロックは4つではなく3つとなり、パラメーター数はLSTMの4分の3です。タスクによって一貫して優劣が決まるわけではありません。
- Transformer: 自己注意を使ってすべての位置を並列に処理するため、GPUでの学習が大幅に速く、離れたコンテキストにも直接アクセスできます。そのため、言語モデリングと翻訳ではトランスフォーマーがLSTMに取って代わりました。注意機構のコストはコンテキスト長に応じて増えますが、LSTMでは新しいステップごとに同じ計算量とメモリを使います。
- xLSTM: Hochreiterの研究グループが2024年に発表したxLSTMは、指数ゲーティングと、並列学習が可能な行列メモリを追加しています。xLSTM 7Bという70億パラメーターの言語モデルは、2025年のICMLで発表され、同規模のトランスフォーマーモデルと同等の性能と、より高速な推論を実現しました。
用途#
- 音声認識: Googleは2015年、コネクショニスト時間分類(CTC)で学習したLSTM音響モデルに音声検索を移行しました。また、オンデバイス音声認識器では長年、LSTMを積み重ねた構成が広く使われてきました。
- 機械翻訳: 2016年に提供が始まったGoogle Neural Machine Translationは、エンコーダーにLSTMレイヤーを8層、デコーダーにも8層積み重ねていました。
- 洪水予測: 2024年にNature誌で紹介された Googleの洪水予測システムは、LSTMネットワークを使って気象データから河川の流量を予測し、水位観測所のない流域でも最大5日前に大規模な洪水を予測します。
- 行動認識: CNNが各動画フレームをエンコードし、LSTMがフレーム特徴量のシーケンスを読み取ってクリップにラベルを付けます。これは上記のコードと同じ構成です。
- 軌跡予測: Social LSTMは、歩行者ごとにLSTMを実行し、近くにいる人々の隠れ状態を集約して、群衆の中での移動経路を予測します。YOLO26のトラックモードは、動画の各フレームで人物に一貫したIDを割り当てます。これにより、フレームごとの検出結果から、予測器が読み取る位置履歴を作成できます。










