双方向リカレントニューラルネットワーク
導入
リカレントニューラルネットワーク(RNN)は時系列のように順序のあるデータシーケンスを扱うために考案された。エンコーダが入力ベクトル$\mathbf{x}_{i}$と直前状態の隠れベクトル$\mathbf{h}_{i-1}$を隠れベクトル$\mathbf{h}_{i}$へエンコードし、デコーダが隠れベクトル$\mathbf{h}_{i}$を出力ベクトル$\mathbf{y}_{i}$へデコードするという仕方で動作する。すなわち$\mathbf{y}_{i}$は$t \le i$であるすべての$t$についてのみ入力ベクトルと隠れベクトルを参照する。つまりある関数$f$について、以下のように表される式である。
$$ \begin{align*} \mathbf{y}_{1} &= f(\mathbf{x}_{1}, \mathbf{h}_{1}) \\ \mathbf{y}_{2} &= f(\mathbf{x}_{2}, \mathbf{h}_{2}, \mathbf{x}_{1}, \mathbf{h}_{1}) \\ &\vdots \\ \mathbf{y}_{t} &= f(\mathbf{x}_{t}, \mathbf{h}_{t}, \dots, \mathbf{x}_{1}, \mathbf{h}_{1}) \\ \end{align*} $$
ところがある状況では$\mathbf{y}_{t}$がまだ入力として受け取っていないベクトル$\mathbf{x}_{t+s}$を参照しなければならないこともある。たとえば英語の文「I bought this book」を韓国語に翻訳する状況を考えてみよう。この文をトークン化すると、以下のような入力ベクトル列になる。
$$ (\mathbf{x}_{1}, \mathbf{x}_{2}, \mathbf{x}_{3}, \mathbf{x}_{4}) = (\text{I}, \text{bought}, \text{this}, \text{book}) $$
この文の自然な翻訳は「나는 이 책을 샀다」であり、同様にトークン化すると以下のような出力列になる。
$$ (\mathbf{y}_{1}, \mathbf{y}_{2}, \mathbf{y}_{3}, \mathbf{y}_{4}) = (\text{나는}, \text{이}, \text{책을}, \text{샀다}) $$
ところが三番目の出力トークン$\mathbf{y}_{3} = \text{책을}$は四番目の入力トークン$\mathbf{x}_{4} = \text{book}$に対応するため、これを正しく出すにはまだ読んでいない未来の入力$\mathbf{x}_{4}$を参照しなければならない。しかし先に見たようにRNNの隠れ状態$\mathbf{h}_{t}$は現在までに与えられた入力$\mathbf{x}_{1}, \dots, \mathbf{x}_{t}$のみに依存するため、このような参照は構造的に不可能である。すなわちこのような構造的限界により性能低下を避けられない。この限界を克服するために提案されたのが双方向リカレントニューラルネットワークで、入力ベクトル列を順方向と逆方向の両方に走査し、各時点の出力が過去だけでなく未来の入力までも参照できるようにしたニューラルネットワークである。
定義1 2
活性化関数$\sigma$を入力ベクトルの成分ごとに適用させる関数を$\overline{\sigma}$としよう。すなわち、スカラー関数$\sigma : \mathbb{R} \to \mathbb{R}$について、次のように定義されたベクトル関数である。
$$ \overline{\sigma}(\mathbf{z}) = \begin{bmatrix} \sigma(z_{1}) \\ \sigma(z_{2}) \\ \vdots \\ \sigma(z_{m}) \end{bmatrix} \qquad \text{where } \mathbf{z} = \begin{bmatrix} z_{1} \\ z_{2} \\ \vdots \\ z_{m} \end{bmatrix} $$
入力ベクトルの数列$(\mathbf{x}_{1}, \mathbf{x}_{2}, \dots, \mathbf{x}_{T})$ $(\mathbf{x}_{t} \in \mathbb{R}^{n})$が与えられたとしよう。$\mathbf{W}^{f}, \mathbf{W}^{b} \in M^{m \times m}$、$\mathbf{U}^{f}, \mathbf{U}^{b} \in M^{m \times n}$を重み、$\mathbf{b}^{f}, \mathbf{b}^{b} \in \mathbb{R}^{m}$をバイアスとしよう。順方向forward隠れ状態$\mathbf{h}_{t}^{f} \in \mathbb{R}^{m}$と逆方向backward隠れ状態$\mathbf{h}_{t}^{b} \in \mathbb{R}^{m}$を次の二つの漸化式で定義する。
$$ \begin{align*} \mathbf{h}_{t}^{f} &= \overline{\sigma}\left( \mathbf{W}^{f} \mathbf{h}_{t-1}^{f} + \mathbf{U}^{f} \mathbf{x}_{t} + \mathbf{b}^{f} \right), \qquad \mathbf{h}_{0}^{f} = \mathbf{0} \\ \mathbf{h}_{t}^{b} &= \overline{\sigma}\left( \mathbf{W}^{b} \mathbf{h}_{t+1}^{b} + \mathbf{U}^{b} \mathbf{x}_{t} + \mathbf{b}^{b} \right), \qquad \mathbf{h}_{T+1}^{b} = \mathbf{0} \end{align*} $$
順方向隠れ状態$\mathbf{h}_{t}^{f}$は$t = 1$から$T$へと時点を増やしながら計算し、逆方向隠れ状態$\mathbf{h}_{t}^{b}$は$t = T$から$1$へと時点を減らしながら計算する。
各時点$t$の出力$\mathbf{y}_{t} \in \mathbb{R}^{p}$は、両方向の隠れ状態をそれぞれ全結合層に通して足したものである。$\mathbf{V}^{f}, \mathbf{V}^{b} \in M^{p \times m}$を重み、$\mathbf{c} \in \mathbb{R}^{p}$をバイアスとすると、出力を次のように定義するニューラルネットワークを双方向リカレントニューラルネットワークbidirectional recurrent neural network, BRNNという。
$$ \mathbf{y}_{t} = \mathbf{V}^{f} \mathbf{h}_{t}^{f} + \mathbf{V}^{b} \mathbf{h}_{t}^{b} + \mathbf{c} $$

- 定義で示した出力式$\mathbf{y}_{t} = \mathbf{V}^{f} \mathbf{h}_{t}^{f} + \mathbf{V}^{b} \mathbf{h}_{t}^{b} + \mathbf{c}$は、両方向の隠れ状態を結合するさまざまな方式のうちの一つの例示にすぎない。 たとえば分類問題では出力が確率として解釈できるようにソフトマックスをかけたり、回帰問題では恒等関数や非線形活性化関数を通したりすることもできる。結局、両方向の隠れ状態をどのように結合して出力を出すかということは分野・用途・実装の選択の問題である。本定義の線形式はそのうち最も単純な代表形だと理解すればよい。
説明
簡単に言えば、二つのRNNにそれぞれベクトル列$\left\{ \mathbf{x}_{1}, \mathbf{x}_{2}, \dots, \mathbf{x}_{T} \right\}$と$\left\{ \mathbf{x}_{T}, \mathbf{x}_{T-1}, \dots, \mathbf{x}_{1} \right\}$を通して得た隠れ状態を予測に用いるということである。
基本形のリカレントニューラルネットワークでは、時点$t$の出力$\mathbf{y}_{t}$は隠れ状態$\mathbf{h}_{t}$を通じて現在までの入力$\mathbf{x}_{1}, \dots, \mathbf{x}_{t}$のみに依存する。一方、双方向リカレントニューラルネットワークは互いに独立な二つのリカレントニューラルネットワークを置き、一つは入力ベクトル列を$t$が増加する方向$(t = 1 \to T)$へ情報を圧縮し、もう一つは$t$が減少する方向$(t = T \to 1)$へ情報を圧縮する。前者が作り出す隠れ状態が順方向隠れ状態$\mathbf{h}_{t}^{f}$であり、後者が作り出す隠れ状態が逆方向隠れ状態$\mathbf{h}_{t}^{b}$である。
このとき$\mathbf{h}_{t}^{f}$は過去の入力$\mathbf{x}_{1}, \dots, \mathbf{x}_{t}$を、$\mathbf{h}_{t}^{b}$は未来の入力$\mathbf{x}_{t}, \dots, \mathbf{x}_{T}$をそれぞれ要約して収める。出力$\mathbf{y}_{t}$がこの二つをともに参照するため、結局各時点の出力は入力ベクトル列全体を見て計算されることになる。導入で見た翻訳の例のように$\mathbf{y}_{t}$がまだ読んでいない後方のトークン$\mathbf{x}_{t+s}$を参照しなければならない状況でも、RNNと違って逆方向隠れ状態がその情報を圧縮して伝えることができる。
RNNの一部の欠点を克服はしたものの、BRNN固有の欠点も依然として存在する。両方向のパラメータを別々に置くため学習すべきパラメータの数がおよそ二倍になり、何より逆方向隠れ状態を計算するには入力ベクトル列全体があらかじめ与えられていなければならない。 したがって双方向リカレントニューラルネットワークは、入力をリアルタイムで受け取ってただちに出力を出さなければならない問題や、前の出力を見て次の入力を生成する自己回帰的生成には使えない。逆に機械翻訳のエンコーダ、品詞タギング、固有表現抽出、音声認識のように入力ベクトル列全体を一度に得られる課題では、双方向構造が利点を発揮できる。
