にほんごのれんしゅう

日本語として伝えるための訓練を兼ねたテクログ

教師なしRNNによる連続した不完全情報(主にテキスト)の補完

教師なしRNNによる連続した不完全情報(主にテキスト)の補完

背景

Google(や、過去の私のブログの投稿)などで低解像度の映像を高解像度化する方法は、GANを使うことでわりとうまくいきました。
テキストにも同じような問題が適応できるのかって思うことがあります。RNNはすでに記述されている文字をヒントとして次の文字を予想することができます。
その特性を利用して、情報が失われたテキストから復元を試みる例を示します。

(また、戦時中の戦艦に乗っていた搭乗員の劣化した手記から情報を復元したいという思いがあります。手記の海水に沈み腐敗が進んでいたり、筆記が乱れていて解析が困難であったりという点を補完できれば良いと思います。彼らの思い、可能な限り現代に蘇らせたいと思います。)

先行研究

  • 今回は見当たらない(ほんとに存在しないんだったら、論文出したい)

手法

  • RNNで欠落した連続する情報を周辺の単語分布から、情報を復元しようとした場合、どの単語が尤もらしいかどうか予想するタスクに置き換える
  • 一般的なテキスト生成タスクでは、生成タスクの素性とするのは、それまでの系で、決定された文字列である。これを前方までに拡張する。なお、この時、欠落した情報を加工することなく、そのまま学習データとして利用するので、教師なし学習である。
  • 最も尤度が高い欠落情報から埋めていき、再帰的に尤度がたいところを探索することで、より確度の高い復元を試みる

f:id:catindog:20170305175458p:plain

図1. イメージ図

  • 数式も載せようと思いましたけど、Kerasからじゃ数式レベルの粒度で見えないから意味ないんだよね...[3]
  • キャラクタ数多すぎる問題が日本語では起きるので、fastTextでキャラクタを256次元に圧縮したものを用いてます。

実験

  • Keras(TensorFlowをバックエンドとする)
  • 日本の戦時中の手記[1]と、新約聖書[2]を利用する
  • 全体の10%、20%、30%をランダムに情報を欠損させた場合、未知の文章に対しての復元能力を定性的に確認する
  • 全体のドキュメントの8割を学習に、2割を評価に用いる
  • GRUを用いたRNNでunit数は1024
  • BatchNormalizationの論文の基づく、パラメータで導入
  • Dropoutを0.5のパラメータで導入
  • OptimizerにAdamを利用
  • 全結合層はsoftmaxで単語の素性数を出力
  • 目的関数にcategorial cross entropyを利用
  • epoch 160

評価

定性的な評価では概ね良好な結果を示した。
欠落する情報が50%を超えるとRNN特有の再帰構造があちこちに観測され、微妙にわからなくなってくるが、10%程度ならほぼ正しく、30%程度ならぎりぎり読めるようにみえる。


10%欠落した例1:聖書

驚き恐れて、この獣に従い、そればりか、こ■獣に■威を授けた竜を拝むようになっ■。彼らはま■獣をも拝■で、■これほど偉大な者を見たことがな■。だれ獣と戦■て■てる■ろうか」と言った。■の獣は高ぶり、神を汚す言■を吐き■ご■わずかな期間だけ活動■ることが許されで、その■は、神に対し■汚しごとを言い始■た。神とその御使いと、そこ■いる神の民をののしった。その■はクリスチャ戦い■挑んで打ち負かす力が与え■■、国民、部族、種族、■族を支配する力が与えられた。地上に生■ている人で、キリス命の書に、その名前が書き■されていない者は皆■彼を拝むようにな■。■■こと■何を意味しているのか考えてみなさい。クリスチャンは迫害によっ■■え■れて行く。そのことが自分の身に■った時にも■あわてずに心の備えを■ていなければ な。迫害する者がクリスチャンを殺して■、彼ら自身も■ず殺されることになる■だから、クリスチ■ンはす■てを■の御手にて耐え忍ぶことができる■私はまた■もう一頭の獣が地から■って来るのを見た。■■は、おそらく偽預言者のことであろうの獣には、子羊のような二本の角があって、■のように、すごみを■び■ものの言い方をした。この■は、先の獣が持っていらゆる権威を、その獣の前で行使し、地に■む人■に、無理矢理■致■的な傷の治った獣を拝ませた。また、人々■前で燃える火を天から降■せる■さらに、地上の人々を惑わし、致命的な傷を受けながらも■き■った先の獣■像を造るよ地上に住む■■に命じた。偽預言■は魔術的なやり方で、その■の像がものを言っているよ■に見せ■■、その獣の像を拝まを皆殺させた。ま■、あらゆる種類、あらゆる階層の人々の右の■■額に、印を■けさせた。その印の■■てい■い者は、だを■■たり売■たりできないようにし■■まった。その印■、その獣の名前であり、その名前はま■数字でも表された。その■こうと■るなら、天か■の知恵が必■で■る。■の数字の意味の解ける人は、解いてみるが■い。その数字は、■る特定のしており、六百六十六である。これは反キリストである	

10%補完した例1:聖書

驚き恐れて、この獣に従い、そればかりか、この獣に権威を授けた竜を拝むようになった。彼らはまた獣をも拝んで、、これほど偉大な者を見たことがない。だれがこの獣と戦っていてるだろうか」と言った。この獣は高ぶり、神を汚す言葉を吐き、ごさわずかな期間だけ活動することが許された。そこで、その人は、神に対して汚しごとを言い始めた。神とその御使いと、そこにいる神の民をののしった。その獣はクリスチャンに戦いを挑んで打ち負かす力が与えられ、国民、部族、種族、民族を支配する力が与えられた。地上に生きている人で、キリストの命の書に、その名前が書き記されていない者は皆、彼を拝むようになる。このことは何を意味しているのか、よく考えてみなさい。クリスチャンは迫害によって与えられて行く。そのことが自分の身になった時にも、あわてずに心の備えをしていなければならない。迫害する者がクリスチャンを殺しても、彼ら自身も必ず殺されることになる。だから、クリスチャンはすべてを神の御手にゆだねて耐え忍ぶことができる。私はまた、もう一頭の獣が地から帰って来るのを見た。それは、おそらく偽預言者のことであろう。この獣には、子羊のような二本の角があって、そのように、すごみを滅びるものの言い方をした。この男は、先の獣が持っているあらゆる権威を、その獣の前で行使し、地にやむ人々に、無理矢理の致命的な傷の治った先の獣を拝ませた。また、人々の前で燃える火を天から降らせる。さらに、地上の人々を惑わし、致命的な傷を受けながらもべきまった先の獣の像を造るように、地上に住むの中に命じた。偽預言者は魔術的なやり方で、その方の像がものを言っているように見せまし、その獣の像を拝まない者を皆殺させた。また、あらゆる種類、あらゆる階層の人々の右の手そ額に、印を付けさせた。その印の振っていない者は、だれも物を持ったり売ったりできないようにしてしまった。その印は、その獣の名前であり、その名前はまた数字でも表された。その数字をそこうとするなら、天からの知恵が必要である。その数字の意味の解ける人は、解いてみるがない。その数字は、ある特定の人間を指しており、六百六十六である。これは反キリストである

30%欠損した例2:ミッドウェー海戦手記

巨大な戦艦■らばこれら■■■を解決■■るので、■に■■司令・有賀大佐が移乗を強く■申したとも■え■れています。■嵐」■野■」か■「■■」へ■「萩風■■■風雲■から■■■」へ、「巻雲■から「■奥」■、そ■■「濱風」は■山城■へ、「磯風」は甲標■■艦「千代■■■■■艇による■乗■は■変苦労し■と言います■■谷風」が知る由もありません■し ■■闘はこの移乗■業を間接的に助け ■になっ■■評■■れ■いま■。もしドー■■レスが「谷風」を攻撃せずにそのまま■■して■■ら、主隊■■雲■動部隊■受け■いた可能■もあると言われているからです。

30%欠損を復元した例2:ミッドウェー海戦手記

巨大な戦艦ならばこれらの問題を解決でするので、特に四駆司令・有賀大佐が移乗を強く具申したとも伝えられています。「嵐」「野分」から「榛名」へ、「萩風」「舞風」から「長門」に「「風雲」から、「嵐」へ、「巻雲」から「浦奥」へ、そして「濱風」は「山城」へ、「磯風」は甲標上母艦「千代1時3。前日はうこりが大きく、6艇による移乗がは結変苦労したと言います。「谷風」が知る由もありませんでしたが、「谷風」の死闘はこの移乗作業を間接的に助けたことになったと評価されています。もしドーントレスが「谷風」を攻撃せずにそのまま、そしていたら、主隊に南雲機動部隊は移乗作業中に攻撃を受けていた可能性もあると言われているからです。

感想

  • 今回はヒエラルキカルなんとかベイズの理論の勉強中に思いついたので、実際にはベイズでもできるとは思う。実装難易度だったり他の人の感想を見てると、ディープラーニングのほうが簡単ではないかと思ったりした。
  • 多くの点でRNNとベイズとの類型が見られるので、何か興味深い習性があるのではないか

コード

コード全体はgithubにおいておきます。多分そのまま利用できるかと思います。
github.com

git cloneしてファイルを取得

$git clone https://github.com/GINK03/keras-unsupervised-rnn-negentropy.git

トレインの方法です。デフォルトで全体の8割を使用します。デフォルトではmidwayデータセットを用います。適宜コードを変えてください。

$python3 rnn_negentropy.py --train

評価の方法です。testcast.pyに必要な評価対象文章を追加してください。結果はresult.txtファイルへ出力されます。

$python3 rnn_negentropy.py --eval

今回も結構な分量になったので、モデルだけ。

def build_model(maxlen=None, feats=None):
  print('Build model...')
  situations  = 4
  vector_size = 256
  model_text = Sequential()
  model_text.add(Reshape( (maxlen, vector_size, ), input_shape=(maxlen, vector_size)))
  model_text.add(GRU(int(128*8)))
  model_text.add(BN(epsilon=0.001, mode=0, axis=-1, momentum=0.99, weights=None, beta_init='zero', gamma_init='one',
 gamma_regularizer=None, beta_regularizer=None) )
  model_text.add(Dropout(0.5))
  final_model = Sequential()
  final_model.add(model_text)
  final_model.add(Dense(len(feats)))
  final_model.add(Activation('softmax') )
  optimizer = Adam()
  final_model.compile(loss='categorical_crossentropy', optimizer=optimizer)
  return final_model

近況

なんとか生きています。進捗が発生させられないくてツライ。