9.4. 再帰型ニューラルネットワーク¶
9.3 章 では、言語モデリングのためのマルコフモデルと \(n\)-gram を説明した。そこでは、時刻 \(t\) におけるトークン \(x_t\) の条件付き確率は、直前の \(n-1\) 個のトークンのみに依存する。 時刻 \(t-(n-1)\) より前のトークンが \(x_t\) に及ぼしうる影響を取り込みたい場合は、 \(n\) を大きくする必要がある。 しかし、その場合、モデルパラメータの数もそれに伴って指数的に増加する。というのも、語彙集合 \(\mathcal{V}\) に対して \(|\mathcal{V}|^n\) 個の数を保持しなければならないからである。 したがって、\(P(x_t \mid x_{t-1}, \ldots, x_{1})\) を直接モデル化するよりも、潜在変数モデルを用いる方が望ましい。
ここで \(h_{t-1}\) は、時刻 \(t-1\) までの系列情報を保持する 隠れ状態 である。 一般に、 任意の時刻 \(t\) における隠れ状態は、現在の入力 \(x_{t}\) と前の隠れ状態 \(h_{t-1}\) の両方に基づいて計算できる。
(9.4.2) において十分に強力な関数 \(f\) を用いれば、この潜在変数モデルは近似ではない。結局のところ、\(h_t\) はこれまでに観測したすべてのデータを単に保持していてもよいからである。 しかし、その場合、計算と記憶の両方が高コストになる可能性がある。
5 章 で、隠れユニットを持つ隠れ層について説明したことを思い出してほしい。 ここで重要なのは、 隠れ層と隠れ状態は、まったく異なる概念だということである。 隠れ層は、説明したように、入力から出力へ至る経路の途中で外から見えない層である。 一方、隠れ状態は技術的には、ある時点で行う処理に対する 入力 であり、 それは過去の時刻のデータを見て初めて計算できる。
再帰型ニューラルネットワーク(RNN)は、隠れ状態を持つニューラルネットワークである。RNN モデルを導入する前に、まず 5.1 章 で導入した MLP モデルを振り返ろう。
%load_ext d2lbook.tab
tab.interact_select('mxnet', 'pytorch', 'tensorflow', 'jax')
from d2l import torch as d2l
import torch
from d2l import mxnet as d2l
from mxnet import np, npx
npx.set_np()
from d2l import jax as d2l
import jax
from jax import numpy as jnp
from d2l import tensorflow as d2l
import tensorflow as tf
9.4.1. 隠れ状態を持たないニューラルネットワーク¶
単一の隠れ層を持つ MLP を見てみよう。 隠れ層の活性化関数を \(\phi\) とする。 バッチサイズが \(n\)、入力次元が \(d\) のミニバッチの例 \(\mathbf{X} \in \mathbb{R}^{n \times d}\) が与えられたとき、隠れ層の出力 \(\mathbf{H} \in \mathbb{R}^{n \times h}\) は次のように計算される。
(9.4.3) では、隠れ層に対して重みパラメータ \(\mathbf{W}_{\textrm{xh}} \in \mathbb{R}^{d \times h}\)、バイアスパラメータ \(\mathbf{b}_\textrm{h} \in \mathbb{R}^{1 \times h}\)、および隠れユニット数 \(h\) を用いている。 このため、加算の際にはブロードキャスト(2.1.4 章 を参照)を適用する。 次に、隠れ層の出力 \(\mathbf{H}\) を出力層の入力として用いる。出力層は次式で与えられる。
ここで \(\mathbf{O} \in \mathbb{R}^{n \times q}\) は出力変数、\(\mathbf{W}_{\textrm{hq}} \in \mathbb{R}^{h \times q}\) は重みパラメータ、\(\mathbf{b}_\textrm{q} \in \mathbb{R}^{1 \times q}\) は出力層のバイアスパラメータである。分類問題であれば、\(\mathrm{softmax}(\mathbf{O})\) を用いて出力カテゴリの確率分布を計算できる。
これは 9.1 章 で以前に解いた回帰問題と完全に同様なので、詳細は省略する。 要するに、特徴とラベルのペアをランダムに取り出し、自動微分と確率的勾配降下法によってネットワークのパラメータを学習できるということである。
9.4.3. RNN に基づく文字レベル言語モデル¶
9.3 章 での言語モデリングでは、 現在および過去のトークンに基づいて 次のトークンを予測することを目指した。 そのため、元の系列を 1 トークンずらしたものを目標(ラベル)として用いる。 Bengio et al. (2003) は、言語モデリングにニューラルネットワークを用いることを最初に提案した。 以下では、RNN を用いて言語モデルを構築する方法を示す。 ミニバッチサイズを 1 とし、テキスト系列を “machine” とする。 後続の節での学習を簡単にするため、 テキストを単語ではなく文字にトークン化し、 文字レベル言語モデル を考える。 図 9.4.2 は、文字レベル言語モデリングのために RNN を通じて現在および過去の文字に基づいて次の文字を予測する方法を示している。
図 9.4.2 RNN に基づく文字レベル言語モデル。入力系列と目標系列はそれぞれ “machin” と “achine” である。¶
学習過程では、 各時刻の出力層からの出力に対して softmax 演算を行い、その後、交差エントロピー損失を用いてモデル出力と目標との誤差を計算する。 隠れ層における隠れ状態の再帰的計算のため、 図 9.4.2 の時刻 3 における出力 \(\mathbf{O}_3\) は、テキスト系列 “m”, “a”, “c” によって決まる。系列の次の文字は学習データ中では “h” なので、時刻 3 の損失は、特徴系列 “m”, “a”, “c” に基づいて生成された次の文字の確率分布と、この時刻の目標 “h” に依存する。
実際には、各トークンは \(d\) 次元ベクトルで表され、バッチサイズ \(n>1\) を用いる。したがって、時刻 \(t\) における入力 \(\mathbf X_t\) は \(n\times d\) 行列となり、これは 9.4.2 章 で説明した内容と同じである。
以下の節では、文字レベル言語モデルのための RNN を実装する。
9.4.4. まとめ¶
隠れ状態に対して再帰的計算を用いるニューラルネットワークを、再帰型ニューラルネットワーク(RNN)と呼ぶ。 RNN の隠れ状態は、現在の時刻までの系列の履歴情報を捉えることができる。再帰的計算を用いることで、RNN のモデルパラメータ数は時刻数が増えても増加しない。応用として、RNN は文字レベル言語モデルの構築に利用できる。
9.4.5. 演習¶
RNN を用いてテキスト系列中の次の文字を予測する場合、任意の出力に必要な次元はどれくらいか。
なぜ RNN は、テキスト系列中のある時刻におけるトークンの条件付き確率を、それ以前のすべてのトークンに基づいて表現できるのか。
長い系列を逆伝播すると、勾配はどうなるか。
この節で説明した言語モデルに関連する問題にはどのようなものがあるか。