終末 A.I.

データいじりや機械学習するエンジニアのブログ

GoogleのAIはどうやって「詩」を生成するのか

一ヶ月ほど前ですが、Google人工知能が「詩」を創りだしたという話が話題になりました。

wired.jp

この話の元ネタは、[1511.06349] Generating Sentences from a Continuous Spaceで発表されている論文になります。この論文では、ベイズとDeep Learningを組み合わせた生成モデルを使用して、文章のコンテキスト情報から文章を生成する手法を提案しています。この提案手法は2つの文章の間の文章を生成することも可能で、記事で紹介されている「詩」はそのようにして生成されたものの一つになります。

この記事では、上記の論文で提案されているアルゴリズムの導入から、それを利用してどのように「詩」を生成するかを解説していきたいと思います。

この論文の肝は、VAE(Variational Autoencoder:変分オートエンコーダ)を利用して、文章のオートエンコーダーをモデル化しているところです。エンコーダーでは文章のコンテキスト情報を潜在変数として出力し、デコーダーではこの潜在変数をもとに文章を生成するというモデルとなっています。

VAEは、観測変数から潜在変数を推論するモデルと、その逆の潜在変数から観測変数を生成するモデルを、別々に等しくなるように学習する確率モデルとなります。この確率モデルのパラメーターの決定は、ニューラルネット等により行うことも可能で、この論文でもニューラルネットを使用して学習しています。

VAEの基礎は変分ベイズ法で、潜在変数から観測変数を生成するモデル{p_{\theta}(z)p_{\theta}(x|z)}とその事後分布{p_{\theta}(z|x)}を変分近似する{q_{\phi}(z|x)}を考えます。データに対して逐次学習を行い、周辺尤度の変分下界を最大化することを目標に、適当なパラメーター{\theta}{\phi}が得られるようにニューラルネットを学習していきます。

VAEの学習手順は、(私の理解が正しければ)下記のとおりです。

  1. 観測変数{x_i}を用いて、ニューラルネットでパラメーター{\phi}を求める
  2. パラメーター{\phi}を用いて、{q_{\phi}(z|x)}から{z_i}をサンプリングする。
  3. 観測変数{z_i}を用いて、ニューラルネットでパラメーター{\theta}を求める
  4. 周辺尤度{p_{\theta}(x)}の変分下界をもとに{\theta}{\phi}の勾配を求める
  5. パラメーターの勾配を元にニューラルネットワークの更新を行う
  6. 飽きるまで繰り返す

※ サンプリングの方法とか勾配の計算方法の詳細は、元論文著者のPPTを参照ください。

あとはVAEを使って計算するだけかとおもいきや、シーケンシャルなデータを扱う手前そういうわけにはいきません。 論文では、VAEの前と後ろにRNNを配置するVRAE(Variational Recurrent Autoencoder)と類似のモデルを使用しています。VRAEでは、エンコーダーの最終出力を用いて、確率分布のパラメーターを推定し、そのパラメーターを使用して確率分布から潜在変数をサンプリングします。サンプリングされた潜在変数は、デコーダーの一回目の入力として使用されます。

VRAEの学習手順は、(こちらも私の理解が正しければ)下記のとおりです。

  1. エンコーダーに系列データを入力し{x_i}を求める
  2. {x_i}からVAEの方法にそって{z_i}を求める
  3. デコーダーに{z_i}を一回目の入力とし、誤差を求めつつ順次系列データを入力する
  4. 誤差からデコーダーのRNNを更新する
  5. VAEのニューラルネットのパラメーターをVAEの手順にそって更新する
  6. {z_i}を用いて{q_{\phi}(z|x)}から{x_i^{'}}を求める
  7. エンコーダーのRNNを更新する
  8. 飽きるまで繰り返す

提案されているモデルでは、VRAEとは異なり、エンコーダーにもデコーダーにも一層のLSTMを使用したRNNを用いています。また確率分布としては、生成モデルにも推論モデルにも正規分布を使用しています。さらに、学習時にはKLダイバージェンスの項にパラメーターを導入したり、潜在変数を用いたデコードを強化し不完全な文章に強くするため、わざとデコーダーに入力する文章を歯抜けにするなどの工夫を行っています。

上記の記事で紹介されている詩は、文1をエンコードして得られた潜在変数{z_1}と文2をエンコードして得られた潜在変数{z_2}から求めた{ z(t) = z_1 \ast (1-t) + z_2 \ast t}をデコードすることにより生成します。式からわかるように、{z(t)}{z_1}{z_2}を結ぶ線分上に存在するいずれかの点になります。

下の記事で紹介されている例を見ると分かりやすいですが、この{z(t)}を用いてデコードした文章は、文章構造やトピックが2つの文章に類似したものとなります。一方、このモデルで得られる潜在変数が獲得している情報は、あくまで一つの文章内での文章構造や単語の使われ方のみのため、文意にそって総合的な文を生成するということまでは残念ながらできていまいません。

www.gizmodo.jp

ここまで読んでいただければおわかりかと思いますが、このモデルは詩を生み出そうとして作られたものではなく、トピックや文章構造に焦点を当てて文章を生成するモデルを学習した結果、生成される文章群の特徴上「詩」のような文章が生成されるという結果となっています。(論文には詩という言葉は一言も出てきません。)

一方、論文の成果を利用する立場から見ると、ベクトルの演算により2つの文章の中間っぽい表現が得られることは、分散表現を用いて処理を行う上では使い勝手が良く興味深い結果ではないかなと思います。このモデルにより得られたベクトルをさらに違うモデルにくわせることにより、文意を組んだ文章全体を生成するようなモデルを学習することもできるのではないか、期待してみていきたいところです。

参考