ディープラーニングブログ

Mine is deeper than yours!

論文解説 Convolutional Sequence to Sequence Learning (ConvS2S)

声に出して読みたい英語.

RNN は死んでいない.自己回帰 CNN と注意 (の再帰的構造) は RNN だから.それらの状態は (内部状態ではなく) 出力にある.

こんにちは Ryobot (りょぼっと) です.

ConvS2S は脱 RNN による系列方向の並列化という風潮を決定づけたニューラル機械翻訳の手法です.GNMT より高性能かつ訓練も 5 倍高速です.従来の意味で RNN は死にましたが,冒頭の意味で RNN は生まれ変わりました.

WMT'14 の BLEU スコアは英仏: 40.51, 英独: 25.16 で第 4 位 (登場時 2 位)

f:id:Ryobot:20171221145207p:plain:w700

LSTM は前タイムステップの隠れ状態を現タイムステップの隠れ状態に使うので層内の並列化が困難であった (LSTM 内の重みを行列分解する Factorization Trick を用いた並列化は可能だが限度がある).

ConvS2S (Convolutional Sequence to Sequence) は単語列の処理を LSTM から CNN に置き換えることでタイムステップ方向の並列化を可能にしたモデルである.LSTM はゲーティングが重要なので,この部分を抜き出した Gated Linear Unit も併用する.

ConvS2S の詳細に入る前に,Gated Linear Unit について説明したい.

Gated Linear Unit

GCNN (Gated Convolutional Neural Network) は [畳み込み層, GLU 層] のブロックを L 層スタックしたモデルであり,タイムステップ方向の並列化が可能である.また,LSTM のゲーティングを取り入れた GLU (Gated Linear Unit) によって高い性能を獲得し,WikiText-103 データセットを用いた言語モデルで SOTA を達成した.LSTM より約 20 倍訓練が高速である.

1 ブロック内では,入力 {X} を 2 つに分岐 (コピー) し,それぞれ畳み込み層 {A = X*W+b}{B = X*V+c} で長期依存を捉え,GLU 層 {H = A \otimes \sigma(B)}ゲーティング (上層へ送る情報を制御) する.また,ブロックの入力から出力を残差接続 (Residual Connection) する.

f:id:Ryobot:20171220171616p:plain:w700

パッチサイズ (patch size, カーネルサイズ) {k} の畳み込みを {n} 層スタックしたモジュールは各出力位置が {n (k-1)+1} 個の入力位置の情報を集約できる.またGLU 層のゲーティングは広範囲の情報を得るか少数の情報に集中するか制御できる.

{l} ブロック目の出力 {h_l(X)} は次式によって表される.

f:id:Ryobot:20171220171632p:plain:w360

ここで,{X \in \mathbb{R}^{N \times m}} は入力 (単語列の埋め込みないし前層の出力),{W, \, V  \in \mathbb{R}^{k \times m \times n}} はそれぞれ畳み込み層のカーネル{b \in \mathbb{R}^{n}} はバイアス,{\sigma}シグモイド関数{\otimes} は要素ごとの積 (アダマール積) である.

また,{N} は単語数,{m, \, n} はそれぞれ入力と出力の特徴マップの数,{k} はパッチサイズである.

畳み込み層がやや分かりづらいが下図のとおり.

f:id:Ryobot:20171220171542p:plain:w700

注意点として,タスクは言語モデル (次の単語を予測) なので,畳み込み層は予測すべき未来の単語が予測前のモデルにリークしないようにする必要がある.よってカーネルが未来を参照しないように畳み込み層の入力 {X} を後方へシフトし,入力 {X} の先頭を {k-1} の長さだけ 0 埋めする.

ConvS2S

f:id:Ryobot:20171220171708p:plain:w700

本手法ではエンコーダとデコーダに [畳み込み層, GLU 層] のブロックを 15 層スタックしたものを使用する.デコーダは畳み込み層の入力 {X} を後方へシフトし,カーネルが未来を参照しないようにする.

f:id:Ryobot:20171220171556p:plain:w700

青色の三角形が畳み込み層,{\oslash, \, \otimes} が GLU 層を表す.

デコーダ訓練時に自己回帰せず,全ターゲット単語を同時に入力し,注意も同時に計算し,全単語を同時に出力する.これは訓練を高速する理由の 1 つである.

ConvS2S では単語列の語順 (絶対的な位置) の情報をモデルに与えるために位置埋め込みを使用する.

位置埋め込み (Position Embedding) [Henaff, 2016; Gehring, 2017] は位置ごとに異なる変数 (学習パラメータ) を加算する.

エンコーダとデコーダそれぞれの単語列の埋め込み行列 {W = (w_1, \, \ldots \, w_m)}, {where \, w_j \in \mathbb{R}^{f}} に対して位置の埋め込み行列 {P = (p_1, \, \ldots \, p_m)}, {where \, p_j \in \mathbb{R}^{f}} を加算し,{E = (w_1 + p_1, \, \ldots \, w_m + p_m)} とする.

類似したアイデアである位置エンコーディング (Position Encoding) [Sukhbaatar, 2015; Kaiser, 2017] は位置ごとに異なる定数 (二次方程式や正弦波) を加算する.

複数ステップの注意

注意はクエリに関連する情報を文脈 (Context) として取り出す機構である.

ConvS2S ではデコーダのすべての層で注意を個別に計算する.

{l} 層目のエンコーダの出力を {Z^l = (z_1^l, \, \ldots, \, z_m^l)}{l} 層目のデコーダの出力を {H^l = (h_1^l, \, \ldots, \, h_m^l)} として,{l} 層目のデコーダ{i} 系列目をクエリ {d_i^l} とする注意を考えたい.

クエリ {d_i^l} は次式によって表される.

f:id:Ryobot:20171220171701p:plain:w200

ここで {h_i^l}デコーダの出力,{g_i} は前回の予測単語の埋め込みベクトルであり,学習パラメータ {W_d^l} は重み行列,{b_d^l} はバイアスベクトルである.

注意の重み (Attention Weight) {a_{ij}^l} は次式によって表される.

f:id:Ryobot:20171220171653p:plain:w230

ここでクエリ {d_i^l} は前述のとおりで,キー {z_j^u} はエンコーダの最終層 {u} の出力の {j} 系列目である.注意の重みは {u} からどの情報をどの程度取り出すかを加重和で決めるための重みである.

文脈 (Context) {c_i^l} は次式によって表される.

f:id:Ryobot:20171220171704p:plain:w200

ここで {e_j} は位置埋め込みの出力であり,文脈 {c_i^l}{h_i^l} に加算される.注意によってバリュー {z_j^u + e_j} から適度に文脈情報を取り出している.

f:id:Ryobot:20171220171531p:plain:w700

ここまでの説明は注意を個別に計算したが,すべてのクエリが同時に得られるとき注意をまとめて計算できる.

注意は一般的に次式によって表される.

{Context = Softmax(Query \cdot Key^T) \cdot Value}

ConvS2S では {l} 層目のデコーダの注意は Query 行列 {D^l},Key 行列 {Z^u}Value 行列 {Z^u + E} を用いて次式によって表される.

{C^l = Softmax(D^l \cdot {Z^u}^T) \cdot (Z^u + E)}

注意を実装する際はこちらの式に従い,バッチのテンソルを演算する (決して for 文を使用すべからず).

従来の NMT ではデコーダの 1 系列の生成に 1 度のみ注意を計算する (GNMT も各層は同じ文脈を使用する).

ConvS2S は層ごとに注意を再計算する複数ステップの注意 (Multi-step Attention) を使用する.これは End-To-End Memory Network [Sukhbaatar, 2015] で用いられた複数ホップの注意から着想を得て,その後 Transformer [Kaiser, 2017] 等に採用されることになる.複数ステップの注意によって,ある層のある時刻の注意は下層や過去の注意履歴を参照できる.

正規化と初期化

ConvS2S ではネットワーク全体で活性化の分散が急激に変化しないように,ネットワークの一部 (eg, 残差ブロック, 注意) の出力をスケーリング (ie, 正規化) して学習を安定させる.

  • 残差ブロックの入出力の分散は等しいと仮定し,入出力の和に {\sqrt{0.5}} を掛けて和の分散を半分にする
  • 注意の出力は {m} 個のベクトルの加重和なので,{m \sqrt{1/m}} を掛けて分散の変化を打ち消す ({m} の乗算は入力をオリジナルのサイズにスケールするため).
  • エンコーダの各層の勾配は使用した注意機構の数だけスケールする.

また順/逆伝播の活性化の分散するために,慎重に重みの初期化を行う.

  • すべての埋め込み層の重みは {N(0, 0.01)} (平均 {0} 標準偏差 {0.1}正規分布) に従い初期化する.
  • 上層が GLU 層ではない層の重みは {N(0, \sqrt{1/n_l})} ({n_l} は入力の次元数) に従い初期化 (ie, Xavier Initialization) し,正規分布に従った入力の分散を維持する.
  • 上層が GLU 層である層の重みは {N(0, \sqrt{4/n_l})} に従い初期化する.これは GLU 層への入力が平均 {0} で十分に小さい分散をもつとき,GLU 層は出力の分散を入力の分散の {1/4} に近似できるので,GLU 層への入力の分散が {4} 倍になるように重みを初期化している.
  • バイアスは一律に {0} で初期化する.

入力が確率 {p} で保持されるドロップアウトを複数の層に適応する場合,これは確率 {p}{1} (それ以外は {0}) をとるベルヌーイ確率変数を乗算と見做すことができる.ドロップアウトを適応すると分散が {1/p} にスケールされるので,各層を大きな重みで初期化し分散を保持する必要がある.よって上層が GLU 層である層の重みは {N(0, \sqrt{4p/n_l})} に従い初期化し,それ以外は {N(0, \sqrt{p/n_l})} に従い初期化する.

実験と結果

データセットは WMT'14 の英仏 (35.5M 対訳文) と英独 (4.5M 対訳文) を使用する.
ソース言語とターゲット言語で語彙を共有した Byte-Pair Encoding (BPE) ベースの 40000 サブワードを使用する.

モデルは [畳み込み層, GLU 層] のブロックを 15 層スタックし,それぞれの隠れ層サイズは最初の 10 層が 512,次の 3 層が 768,最後の 2 層が 2048 (英独の場合) である.

学習は 8 枚の M40 GPU による同期型データ並列 (勾配の和は Nvidia NCCL で計算) を行った.最適化は係数 0.99 のモーメンタム (ie, Nesterov の加速勾配降下法) を使用し,学習率は 0.25 から始め,検証セットのパープレキシティが下げ止まったら学習率を半減させる.

評価はビーム幅 5 のビーム探索を使用する.初期値のみ異なる 3 個のモデルを訓練して評価結果を平均した値を掲示する.

シングルモデルを学習した結果は次のとおり.

f:id:Ryobot:20171220171637p:plain:w450

BLEU スコアは MoE [Shazeer, 2017] にはやや及ばないものの,英独・英仏ともに GNMT [Wu, 2016] より 0.5 ポイント高いスコアを達成した.

8 モデルのアンサンブルを学習した結果は次のとおり.

f:id:Ryobot:20171220171607p:plain:w700

アンサンブル学習は英独・英仏ともに SOTA を達成した (英仏は現時点でも SOTA である).

その他

ConvS2S は GNMT に比べて単語列の生成速度が早く,CPU・GPU ともに約 10 倍速である (図は省略).

左下図はデコーダに 5 層のブロックを用いた ConvS2S に対して,複数ステップの注意を適応する層を変えた場合の PPL と BLEU の変化であり,右下図はエンコーダとデコーダの層数を変えた場合の BLEU の変化である.

f:id:Ryobot:20171220171523p:plain:w700

注意は下層ほど重要度が高く,全層に注意を適応する場合が最も性能が高い.またエンコーダの層数は深いほど性能が高く,デコーダは 5 層付近が良い.

畳み込み層のカーネルサイズと,エンコーダとデコーダの層数を変えた場合の BLEU の変化は次図のとおりである.

f:id:Ryobot:20171220171625p:plain:w700

カーネルサイズは小さい方が性能が高く,エンコーダは 13 層,デコーダは 5 層が良い.