RNN(リカレントニューラルネットワーク)・LSTM・GRU

再帰型ニューラルネットワーク・系列データ処理・ゲート機構・長期依存の解決
🔰 初心者

RNNって何ですか?CNNとは何が違うんですか?

🎓 上級者

RNN(Recurrent Neural Network / リカレントニューラルネットワーク)は、「順番」や「流れ」があるデータを扱えるニューラルネットワークだよ。「再帰型」とも呼ばれるね。CNNは画像(縦x横の空間的な情報)が得意だけど、テキスト・音声・時系列データなど前後の文脈が大事なデータにはRNNを使うんだ。

🔄 CNNとRNNの違い

CNN

画像(縦x横の空間的な情報)が得意
位置関係や模様を認識

RNN

系列データ(時間的な順序)が得意
テキスト・音声・時系列を処理

🎓 上級者

「私は 猫が 好き」は意味が通るけど、「好き 猫が 私は」は意味が変わるよね。こういう時間的な順序(系列)があるデータを扱うのがRNNなんだ。

⚙️ RNNの仕組み
🔰 初心者

RNNは普通のニューラルネットワークとどう違うんですか?

🎓 上級者

普通のNNは「入力→出力」の一方通行で、毎回リセットされる。RNNは前のステップの情報を次のステップに引き継ぐんだ。小説を読むときに前のページの内容を覚えながら読み進めるようなイメージだね。

普通のNN vs RNN

普通のNN:入力 → [処理] → 出力(毎回リセット)

RNN:
入力1 → [処理] → 出力1
     ↓(記憶を引き継ぐ)
入力2 → [処理] → 出力2
     ↓(記憶を引き継ぐ)
入力3 → [処理] → 出力3

🧠 隠れ状態(Hidden State)
🎓 上級者

RNNが引き継ぐ情報を隠れ状態というんだ。「今までの文脈をまとめたメモ」の役割だよ。

隠れ状態の例

「私は」→ 隠れ状態:[主語は「私」]

「猫が」→ 隠れ状態:[主語は「私」、対象は「猫」]

「好き」→ 隠れ状態:[私は猫が好き] → 出力:ポジティブな文

RNNの構造(折りたたみ → 展開) 折りたたみ表現 RNN セル h_t x_t 入力 y_t 出力 展開 時間方向に展開した表現 x_{t-1} RNN t-1 y_{t-1} x_t RNN t y_t x_{t+1} RNN t+1 y_{t+1} x_{t+2} RNN t+2 y_{t+2} ... ... 隠れ状態 (h) 入力 RNNセル 出力 隠れ状態の伝搬
図1: RNNの折りたたみ表現と時間方向への展開 ─ 隠れ状態が各ステップに受け渡される
⚠️ RNNの弱点:長期依存の問題
🔰 初心者

RNNにも弱点があるんですか?

🎓 上級者

大きな弱点がある。文が長くなると、最初の方の情報を忘れてしまうんだ。伝言ゲームで10人に伝えるうちに最初の内容がどんどん変わってしまうのと同じ。これは勾配消失問題と同じ構造で、長い系列だと学習がうまくいかないんだ。

長期依存問題の例

「私は東京で生まれて、大阪で育って、京都の大学に通って、福岡で就職して、最近また ______ に引っ越した」

正解は文脈的に「東京」かもしれないが、RNNは文が長すぎて最初の「東京」を忘れている...

💥 重み衝突問題
🎓 上級者

RNNでは同じ重みを全ての時刻で共有しているため、場面ごとに求められる役割が矛盾してしまうんだ。ノートを取るのに太さ固定のペン1本しかない状態をイメージしてみて。

入力重み衝突問題

入力を記憶に取り込むときの重みに関する衝突。

・大事な情報が来たとき → 大きな重みで記憶にしっかり書き込みたい
・不要な情報が来たとき → 小さな重みで記憶を書き換えないようにしたい

→ 同じ重みでは両方を同時に満たせない。

出力重み衝突問題

記憶から情報を取り出すときの重みに関する衝突。

・記憶を出力すべきとき → 大きな重みで記憶の内容を出力したい
・まだ出力すべきでないとき → 小さな重みで記憶を内部に留めておきたい

→ 同じ重みでは両方を同時に満たせない。

🔐 LSTM(Long Short-Term Memory)
🔰 初心者

長期依存や重み衝突の問題はどうやって解決するんですか?

🎓 上級者

LSTMは3つのゲート(門)を持っていて、「覚える・忘れる・出力する」を場面に応じて動的に切り替えられるんだ。ノートの取り方が上手い人のイメージだね。

LSTMの3つのゲート

1. 忘却ゲート:いらない記憶を捨てる(古くて不要なメモを消す)
2. 入力ゲート:新しい情報を記憶する(新しい大事な情報を書き加える)
3. 出力ゲート:何を出力するか決める(今必要な情報だけ取り出す)

+ セル状態(長期記憶の通り道)

LSTMセルの内部構造 C_{t-1} C_t セル状態(長期記憶の高速道路) x 忘却ゲート (f_t) σ (sigmoid) + 入力ゲート (i_t) σ 候補値 tanh x 出力ゲート (o_t) σ tanh x h_t h_t (次のステップへ) 入力: [h_{t-1}, x_t] を結合 前の隠れ状態と現在の入力 h_{t-1} x_t 現在の入力 忘却ゲート 入力ゲート 出力ゲート セル状態 x 要素ごとの積 + 要素ごとの和
図2: LSTMセルの内部構造 ─ 3つのゲートがセル状態への情報の流れを制御する
🛡️ LSTMによる重み衝突の解決
RNNの問題LSTMの解決策
入力重み衝突入力ゲートが「入れる/入れない」を毎ステップ動的に切り替え
出力重み衝突出力ゲートが「出す/出さない」を毎ステップ動的に切り替え
記憶の上書き忘却ゲートが「覚える/忘れる」を毎ステップ動的に切り替え
🎓 上級者

RNNの「固定のペン1本」に対し、LSTMは「書く/書かない」「読む/読まない」「消す/消さない」の3つのスイッチを持ち、場面に応じて柔軟に切り替えられるんだ。

GRU(Gated Recurrent Unit)
🔰 初心者

GRUはLSTMとどう違うんですか?

🎓 上級者

LSTMの簡略版だよ。ゲートを2つ(リセットゲート・更新ゲート)に減らして計算を軽くした。精度はLSTMとほぼ同等で、学習が速いのがメリットなんだ。

LSTM

ゲート:3つ(忘却・入力・出力)
+ セル状態
精度が高い
計算がやや重い

GRU

ゲート:2つ(リセット・更新)
セル状態なし
精度はLSTMとほぼ同等
学習が速い

GRUセルの内部構造(LSTMの簡略版) 隠れ状態の流れ h_{t-1} h_t 更新ゲート (z_t) σ (sigmoid) 「古い情報 vs 新しい情報」のバランス リセットゲート (r_t) σ (sigmoid) 「過去の情報をどれだけ忘れるか」 候補状態 tanh 新しい隠れ状態の候補 混合 リセット後の h_{t-1}を使用 z_t で混合比率を制御 (1 - z_t) x h_{t-1} x_t 現在の入力 GRUの更新式 h_t = (1 - z_t) * h_{t-1}   + z_t * 候補状態 z_t が大きい → 新しい情報を重視 更新ゲート リセットゲート 隠れ状態 候補状態
図3: GRUセルの内部構造 ─ 2つのゲートでLSTMを簡略化
📊 RNNファミリーのまとめ
モデル正式名称解決方法
RNNRecurrent Neural Network隠れ状態で前の情報を引き継ぐ(長期記憶は苦手)
LSTMLong Short-Term Memoryゲート機構で「覚える・忘れる」を制御
GRUGated Recurrent UnitLSTMを簡略化、ゲートを2つに削減
🎯 RNNの主な用途
用途具体例
自然言語処理機械翻訳、文章生成、感情分析
音声認識音声→テキスト変換
時系列予測株価予測、天気予報、需要予測
音楽生成メロディの自動作曲
📐 BPTT(Backpropagation Through Time)
🔰 初心者

RNNってどうやって学習するんですか?普通の誤差逆伝播法とは違うんですか?

🎓 上級者

RNNの学習にはBPTT(Backpropagation Through Time)という手法を使うんだ。RNNを時間方向に展開して、通常の誤差逆伝播法(バックプロパゲーション)を適用するイメージだよ。展開すると普通のフィードフォワードネットワークと同じように勾配を計算できるんだ。

BPTTの仕組み

① RNNを時間方向に展開する
 t=1, t=2, ..., t=T の各ステップを「層」として並べる

② 展開したネットワークに通常の誤差逆伝播法を適用
 出力側(t=T)から入力側(t=1)に向かって勾配を伝播

③ 問題点:時間方向に長く展開するほど勾配消失/勾配爆発が起きやすい
 → これがLSTM・GRUのゲート機構が必要になる直接の理由

対策:Truncated BPTT
 全時刻を一度に展開せず、一定の長さで区切って逆伝播を行う手法。計算コストを抑えつつ学習を可能にする。

↔️ 双方向RNN(Bidirectional RNN)
🔰 初心者

RNNは前から後ろへ順番に処理しますよね。後ろの文脈も使いたい場合はどうするんですか?

🎓 上級者

双方向RNN(BiRNN)は、順方向RNN(前→後)と逆方向RNN(後→前)の2つを並列に走らせて、各時刻で両方の隠れ状態を結合(concatenate)するんだ。こうすることで、前後両方の文脈を考慮した表現が得られるよ。

🎓 上級者

例えば「彼は__を食べた」の空欄を埋めるとき、前の文脈「彼は」だけでなく後ろの「食べた」も使えば「りんご」のような食べ物だと推測しやすいよね。BiLSTM(双方向LSTM)は特に自然言語処理で広く使われ、ELMoなどの事前学習モデルの基盤になったんだ。

双方向RNNの構造

順方向RNN:x1 → x2 → x3 → ... → xT (前から後ろへ)
逆方向RNN:xT → ... → x3 → x2 → x1 (後ろから前へ)

各時刻の出力 = [順方向の隠れ状態 ; 逆方向の隠れ状態] を結合

BiLSTM = 双方向にLSTMを使用。ELMo等で広く採用

🔗 Seq2Seq(Encoder-Decoder)
🔰 初心者

機械翻訳みたいに「入力の長さと出力の長さが違う」場合はRNNをどう使うんですか?

🎓 上級者

Seq2Seq(Sequence-to-Sequence)モデルを使うんだ。エンコーダが入力系列を1つの文脈ベクトル(Context Vector)に圧縮し、デコーダがその文脈ベクトルから出力系列を1トークンずつ生成する。機械翻訳、要約、対話システムなど幅広く使われたよ。

🔰 初心者

弱点はないんですか?

🎓 上級者

大きな課題がある。入力がどれだけ長くても固定長の1つのベクトルに圧縮するから、長い文では情報が失われてしまうんだ(ボトルネック問題)。これを解決するために登場したのがAttention機構で、デコーダが出力を生成する際にエンコーダの各時刻の隠れ状態を直接参照できるようにしたんだ。

Seq2Seqの流れ

【エンコーダ】
入力系列 → RNN/LSTM → 文脈ベクトル(固定長)
例:「I love cats」→ [0.3, -0.8, 1.2, ...]

【デコーダ】
文脈ベクトル → RNN/LSTM → 出力系列を1トークンずつ生成
例:[0.3, -0.8, 1.2, ...] → 「私は猫が好き」

課題:長い入力 → 文脈ベクトルのボトルネックで情報が失われる
解決策:Attention機構(デコーダがエンコーダの各隠れ状態を直接参照)

🎯 G検定ポイント