条件指定可能なRNN
date: 2017-04-03 excerpt: 一般向け資料、再現性が結構厳しいので、できますよっていうぐらいのレベル
RNNのアテンション以外でのアプローチでの条件指定
はじめに
Recurrent Neural Networkを私はよく利用するのですが、アテンション以外での方法で条件指定ができずに苦しむことがよくありました。
RNNでの表現力は強力で、Encoder-Decoderモデルで発揮されますが、EncoderでRNNの状態を作っても、近視的な視点しか獲得できないことは、各種研究も示しているところです[1]
Encoder-Decoderの入力の粒度が例えば単語という粒度であれば、状態を初期化するのに同一の粒度を用いるしかなく、任意の連続系が作れない(漠然とした感情など)という評価を見かけることがありました。
かなり長い間試行錯誤していたモデルがそれなりに上手く行ったので、記録として残していきたいと思います。
先行研究
ググり方が下手なのでよくわかってないですが、私の今回やることはVAE(Variational AutoEncoder)の亜種だとは思います
ベイズの定理が成立しているということを前提としています。
p(shita|D) = p(D|shita)p(shita)/p(D) D:データ点集合 θ:パラメータ
GANなどでもよく見る表記ですが、これを視覚的なイメージに置き換えると、
z -> x(図で置き換え) となり、Zが生成元のデータとなるので、RNNやGANではZの設計がかなり重要です。
GANでは評価関数がカルバックライブラー情報量を使うので意識せずとも、p(y|z)を最大化できます。
提案
RNNではEncoderで入力されたデータxがzを生成していると考えることができそうです。このときややこしいのですが、RNNでは出力した結果を再帰的に自分の次の予想の素性にすることができるので、n-1ステップ時点でのp(y|z)がnの時点においてq(z|x)になっており、無理に式に起こすとこのように解釈できそうです。
p_n(p_n-1( p_n-2( p_n-3(.....)))
このような無限の入れ子になっており、以前の文脈から次の文字が決定する文字の生成タスクは非常に相性がよいです。
この無限に続きそうな式の最初のパラメータはEncoderの出力q_0なのですが、なんどもこの再帰構造を続けていくと、q_0で指定した値をだんだん忘却してくと感覚的に理解できます(そして実際に忘れていってしまいます)
なんとか全体の流れをコントロールできないかとあれやこれややってみたのですが、なかなかうまくいかないです。積みタスクから何度か外そうかと考えていましたが、二週間に一回ぐらいはいじっては玉砕していたのでした。
そこで、もう一段写像関数rを導入します。zの他にもう一つzと同じ働きをするzzというものを定義します。
p_n(y_n | z_n)にrを導入すると以下の式のようになる
p_n(y_n | zz_n)
r_n(zz_n| z_n)
q_n(z_n | x_n)
p_n(r_n(p_n-1( r_n-1(p_n-2( r_n-2(p_n-3(.....))))
もう一回層コントローラブルな写像関数rを用意することで、意図的にpの出力をコントロールしようというアプローチです。
問題はrの設計なのですが、適応する連続系のドメインで色々とやり方が変わりそうですが、今回はfasttextの分散表現に変換すること、分散表現のベクトルの足し算引き算ができるという、性質を利用して、任意の分散表現の変換を行うことで、意図した文脈を作るアプローチです。
意味と変換先が対応することで、特定の意味の方向に意識的に意味を近づけることができそう
実験方針
KerasでRNNを用いた文字列の作成を行います。
通常ですと、ワンホットベクトルを利用するか、KerasのEmbeddingを利用しますが、Kerasの標準のEmbeddingは使用しないようにして、代わりに、twitterの400万の投稿をchar levelでfasttextでembeddingを256次元で行います。
これでは別段新規性がなさそうなネットワークなのですが、上記で記した写像関数rの役目をfasttextが担っています。これを更に状況を説明しているベクトルを追加します。
絵文字による直感的な文脈の変更の説明
図のような構成になっており、ノーテションを行うことで文脈を変化させることが可能。ガラス細工的な不安定さも兼ね備えているので、もともとかなり不安定なネットワークであった。
実験結果
twitterのツイートを絵文字が含まれているものを、絵文字を取り除いて学習する。この際、文章のベクトル化には、二種類のベクトル化を合成した。
☺をconditional vectorとして文章を生成する場合 *(アスタリスクはパディング文字なので意味はありません) この文章生成ではマルコフ過程の探索に該当する作業をしていなく、argmaxを利用しています
*****おはようございます!
💧をconditional vectorとして文章を生成する場合
*****ごめんなさい!
☆をconditional vectorとして文章を生成する場合
*****【定期】
意図して条件を切り替えるのは、結構難しかったが、なんとか結果を得ることができた。
Code
初めてgistを使うなどをしてみた。
-
char levelのfasttextのベクタライズをする様子である
-
term_vector.pklから任意の文字列をRNN入力用のベクタに変換する
-
modelと、学習部分