[1906.02443] Robust Neural Machine Translation with Doubly Adversarial Inputs [paper-reading]
yoheikikuta opened this issue · 12 comments
論文リンク
https://arxiv.org/abs/1906.02443
公開日(yyyy/mm/dd)
2019/07
概要
encoder への入力と decode への入力の両方で adversarial training を適用して機械翻訳の性能を高めたという論文。
単語置き換えをベースに adversarial training のための adversarial examples を作るが、そこで言語モデルを使って候補の単語を絞り元の意味を変えないようにしつつ翻訳がうまくいかないようなデータを作ることに成功している。さらに、decoder の入力にも同様の手法で adversarial examples を作ることでより一層汎化性能を高めることができるということを発見した。
従来の adversarial training や data augmentation の手法と比較しても、機械翻訳において提案手法が汎化性能を高めたり noisy inputs に対しても強いことを実験的に示した。
NLP における adversarial examples を調べてみようシリーズ第三弾で、機械翻訳の性能向上に adversarial training を使いましたという論文。
目的が汎化性能を高めるための adversarial training で、自分が興味あるのは adversarial examples をどう作るとかそこから得られる示唆とかでちょっとズレがあるのだが、この論文ではかなり adversarial training 用に adversarial examples を入力に使うという点に重きを置いているっぽいので読んでみることにした。
機械翻訳は色々なところで使われているので、vulnerability は研究上のお題目というレベルよりももっと実用上も重要になっているものである。
例としては以下のようなものを挙げている。he -> she の置き換えだけのはずがなぜか複数系になってしまったというものらしい。ちなみにこれは google translation で試してみると問題なく翻訳される。
機械翻訳における adversarial attack への頑健性は、先行研究はまだ中身を調べてはないのだが、この論文曰く adversarial examples を作るのに事前知識が必要だったり、 downstream の機械翻訳モデルを無視するものだったり、character level しかなかったりして、まだまだ調べられていないという感じらしい。
ということでこの論文では adversarial examples に対して robust な機械翻訳モデルを作ることを目的としている。貢献としては以下らしい。
- white box で機械翻訳の adversarial examples を作る手法を提案。
- doubly adversarial inputs という encoder と decoder の入力それぞれに adversarial examples を使う新たな手法を提案。
- 従来の SoTA Transformer model よりも高い性能を発揮(この論文では Transformer model のみを対象にしている。性能がいいから)。
ざっくりと記法の整理。機械翻訳なので source の文章と target の文章があることに注意。
- x = x_1, ..., x_I : source の文章(I 個の単語列で encoder の入力になる)
- e(x) = e(x_1), ..., e_(x_I) : embedding(embedding それぞれはもちろんベクトル)
- h : encoder から得られる hidden representation
- y = y_1, ..., y_J : target の文章(J 個の単語列)
- z = z_1, ..., z_J : decoder への入力(なので学習で使うときは z = , y_1, ..., y_{J-1} となる)
- θ_{mt} : モデルのパラメタ
decoder が y を出力する確率は以下のように書ける。
学習の損失関数は正しい target を出力する確率の負の対数 (negative log translation probability) を使う。
ここまでは adversarial examples とか関係ない機械翻訳の話である。
adversarial examples をどう作っていくか。
まずはいくぶん抽象的な定式化で。J(・) を入力データの adversarial 度合いを測る関数(高いほどモデルが間違いやすい)、R(x', x) を摂動による変更の知覚可能度合いを測る関数(高いほど元の文章との違いが大きいと知覚できる)、とすると以下のように定式化できる。
よくある adversarial examples の話で、摂動はあまり元を変えないような小さいものに保ちつつ、モデルの間違いやすさは最大化するようにする、というものになっている。
J は例えば分類問題なら他のクラスへの誤認識で与えることができるが、R の方は知覚といってもなかなか定式化できないので難しさがある。画像ならば $ l_2 $ とか $ l_∞ $ とかが使われる。
この論文では「理想的なモデルならば摂動を加えても似たような結果が出力されるはず」という仮定の元に、AdvGen という手法を提案して、encoder への入力に摂動を加え、そして decoder への入力にも摂動を加える、ということをやっていく。
入力文を adversarial examples にする方法を見ていく。
機械翻訳なのでパラレルコーパス $ (x,y) $ がセットで与えられているという状況。
まず、先ほどの adversarial 度合いを測る関数 $ J $ は素直に negative log translation probability に置き換える。
$ R $ の方は言った通り難しいので、こんな感じで定式化しておきながら、置き換える単語の割合を調整してできる限り小さくするというだけである。
negative log translation probability の最大化を解析的には求められないので、greedy approach を採用する。具体的には、embedding space のベクトルを基準にした単語の置き換えを、できるだけモデルが間違いやすい方向に沿って実施していくというものである。
sim は cosine similarity で、$ V_x $ は source 文章の言語の語彙である。ある単語 $ x_i $ を置き換えるときには、その単語(の embedding)で微分した最急降下の方向を模すように、語彙の中から良さそうなものをピックアップする、ということだ。
他の NLP adversarial examples のものと同じように、やはりこの $ V_x $ を全て探索するのは効率が悪い。そこで、置き換え候補として良さそうな単語度合いを測る関数 $ Q(x_i, x) $ を導入して、その top_n を取得してそこだけを探索するという手法を採用する。
bi-directional な言語モデル $ P_{lm} $ を導入し、$ Q $ を以下のように定義する。この辺も他の論文と同じ戦略ですね。
言語モデルを導入する利点として下記三点を挙げている。
- 置き換えの単語候補を絞ることができる。
- 言語モデルを介在することで置き換え前の単語と意味的に近しいものを抜き出せるので、直接的な数値としては現れないが知覚可能度合い R の制限を取り入れてくれていると期待できる。
- 単語の表現の変性を防げる。ちょっと何を言ってるか分からない、単語を単純に置き換えると context を変化させるが、言語モデルに基づくことでその変化は小さいものに抑えられるという話っぽい。
これで準備はオッケーで、実際のアルゴリズムは以下の通り。置き換えの割合として γ を導入している以外は、これまで見てきた要素を組み合わせているに過ぎない。ただし以降の decoder 側の拡張を考えて、$ D_{\text{pos}} $ という置き換えの単語をどういう分布に従ってサンプルするかが含まれている。今の場合はこれは uniform distribution である。
$ x \rightarrow x' $ を作ったので、新たな学習データは $ (x',y) $ というペアになった。
この x' で decoder の prediction は大きな影響を受けて翻訳がうまくいかなくなってしまうが、adversarial training によって robust になることが期待できる。
robustness をさらに高めるため、decoder の input に関しても同じように AdvGen を適用する。$ z' $ を作るのは $ x' $ のデータから作っていることに注意。
$ Q_{\text{trg}} $ は機械翻訳のモデルと target 言語の言語モデルを組み合わせて以下のように定義する。
第一項は source のものと同じで言語モデルだけ target 言語のものに変えたものである(なので $ P_{lm} $ と書いて欲しいが)。
第二項は翻訳モデルの出力で、$ i $ 番目の前までの target 言語の入力と、$ x' $ を encoder に食わせて得られた hidden representation を使って次が $ z $ と出力される確率である。
第一項だけだとモデル情報が切り離されてしまっているので、第二項も入れてバランスを取っている感じだろう。
$ D_{\text{trg}} $ は uniform distribution だった encoder 側と違って、以下の確率に従ってサンプルするように変更する。$ M $ は直近のミニバッチで得られた機械翻訳モデルの attention matrix で、$ δ $ は $ x_i ≠ x'_i $ のとき 1 でそれ以外は 0 となる。
これの意味を考えてみる。
まず、スタート地点を思い出すと、decoder への入力の成分 (j = 1, ..., J) のどの位置を置き換えるかを決めたい(なので $ P(j) $ という j が引数の確率)。
分子を考えると、いま考えている j 番目の要素との attention score で、単語を置き換えたことによる影響度合いを測りたいと思っている。なので、置き換えた単語そのものの場所は単語が変わって情報が変化しているので無視して、それ以外の要素は和を取ることで、置き換えた単語が周りに与えている影響を測っているという感じになっている。
分母は単なる規格化。
実験の設定を確認しておく。
データは Chinese-English と English-German の翻訳。
前者は LDC の 1.2M sentence pairs で学習し、validation は NIST2006 を使い、テストは NIST2002,3,4,5,8 を使う。NIST のページ
後者は WMT'14 の 4.5M sentence pairs で学習し、newstest2013 で validation して、newstest2014 でテスト。newstest は知らないが、Stanford のページ にまとめてある。
単語に関しては、それぞれの場合で source と target を合わせて BPE して sub-word を使っている。
なので、単語の置き換えとこれまで言ってきたのは sub-word の置き換えということになる。
Chinese-English の場合は同じ BPE のコードを使って Chinese は 46K で English は 30K の sub-word の辞書を作っている。こっちは source と target を合わせてるわけじゃないと思うのだが...
English-German の場合は一緒くたにして 32K sub-word の辞書を作っている。
評価指標は BLEU を使う。
AdvGen で使われる言語モデルは left-to-right と right-to-left の Transformer 二つ使って、最後の表現のところでそれぞれの表現を combine して softmax につなげるというモデルを使っている。
ハイパーパラメタは validation set 使って tune し、最終的には λ = 0.5, top_n は 10 個, (γ_src, γ_trg) は (0.25, 0.50) を使用することになったとのこと。この辺は細かいのでちょっと端折っている。
メインの結果は以下。Trans.-Base は hidden が 512 で Trans.-Big は hidden が 1024 dim のもの。
比較は adversarial training を使わない Transformer の結果。少なくともモデルを揃えればどちらを見ても確かに機能しているのは見て取れる。
従来までの adversarial training と比べてより汎化性能を高める効果がある、ということを示したのが以下の結果。上から、普通の Transformer、embedding に perturbation を加えるもの、word dropout で data augmentation、source と target で random に単語を置き換える data augmentation、adversarial training (詳細は調べてない)、back translation 使うもの、というのが比較手法。
結構盛りだくさんだが、確かに提案手法は従来の adversarial training や data augmentation よりもうまく機能しているように見える。
次に noisy input に対する性能を調べる。
ここでの noisy input は adversarial examples ということではなく、test set においてランダムに単語を選んで word embedding の意味で近いものに置き換えるということをやる。
これを 0.0 ~ 1.0 の割合で置き換えるということをするが、各 sentence で 100 個の noisy sentence を作って、bi-directional language model で評価して最も確率が高いものを noisy input として採用している。
そうやって作ったものは元々の文章とは意味的にはほぼ変わってないはずなので、target の方は original のまま使っている。やや危うい感じもするが。
その結果が以下。提案手法が置き換えをしても正しく元の意味を保持できていることが示されている。
具体的な例は以下。単体でやや評価も難しいが、生の Transformer よりは良さそうだ。
ということで、読んだ。
adversarial examples 的にデータを準備して学習することで汎化性能を高められることが示された。
ただしやはり汎化性能を高めるのが目的なので、例えば入力を adversarial examples にした場合の例などが載ってないのは自分としてはやや残念(サブワード単位だと変なのも出てきそう)。
やっぱり全体的に NLP では data augmentation とかと比較されるような形で adversarial training が登場していて、adversarial examples を作ることそのもの自体にはあまり重きが置かれてない印象は受ける。