KerasでVariational AutoEncoder

VAEのお話

さて、前回は軽いAutoEncoderを書きました。今回、メインはスライドとgithubにぶん投げてVariational AutoEncoderの解説をします。

Variational AutoEncoderは簡単に言うと生成モデルをディープラーニングでやったものです。簡単じゃない?言い方を変えると、元あるデータを元に意味のあるデータが集まっている概念を作り出す、みたいな感じでしょうか。

例えば数字の画像がいっぱいあってそこから「数字」という概念を学習します。例えば、見た目は似てても数字になってないものとかありますよね(例えば”1″と”I”とか)。でもこういったものを学習して、”I”ではなく”1″であるものの形状の概念みたいなものを捉えるわけです。

さて、でそれをどうやるのかというと「数字の概念」を確率分布として仮定してその分布を求めます。詳しくは以下のスライドにまとめました。

けっこう馴染みがないと難しいと思うので、意味が分かりずらかった人はベイズ統計の概念とか生成モデルとか勉強してみるといいと思います。

VAEの実装

さて、では実装。実は実装はkerasの大元に置いてあるんですよね…

ん、あれうまく動かない….?
実はこの実装間違ってます。何がおかしいのかと思ったらloss関数が違います。

問題はobjectives.binary_crossentropy(x, x_decoded_mean)の部分。これはKerasのobjectivesから関数を呼び出しているわけですが、objectivesの実装を見ると…

これ、実はK.meanで平均をとっています。本来、クロスエントロピーは各要素の和をとってバッチごとに平均をとるのが正しいので、平均をとるだけではうまくいきません。
正しく書き直すと以下のようになります。

これでやっとまともに動きます。個人的な嗜好でそれぞれにK.mean入れてますが、kerasはバッチごとの平均とってた気がするので本当はなくても大丈夫と思います(試してないですが…)。この辺のコード、詳しくは以下にまとめました。ConditionalなVersionも書いたので参考までにどうぞ。
ちなみにConditional版の実装のL2ノルムは趣味です。なくても全く問題ないです。

(追記)
今見てみたらkerasのサンプルがアップグレードしてました(昔のコードだとstd=0.01とかでやってましたがこれだとただのAutoEncoderと変わりません)。
https://github.com/fchollet/keras/blob/master/examples/variational_autoencoder.py

でもやっぱりloss関数部分はまだ完全に直ってないっぽいです(7/30時点)。実際コピペして実行してみるとこんな感じ。

ダウンロードダウンロード (1)

んー、案の定。そのうち改善されるでしょう。

KerasでAutoEncoder

前回に引き続き、KerasでAutoEncoderを書いてみました。

KerasでAutoEncoder

AutoEncoderのモデルは下記で定義してあります。ほぼほぼ全結合の時と一緒ですね。

で、実際に前半のEncoderの部分を使う場合はinputからencoderの部分をモデルとして宣言する必要があります。
この時は上のモデルでトレーニング済みなので特にfitみたいなことしなくて大丈夫です。

Denoising AutoEncoderも作りました。ノイズの作成方法としては、元画像に正規分布からとってきた乱数を加えてます。
np.clipで上限下限を定めて0~1の範囲に収まるように調整しています。

後はノイズ付き画像が入力、元画像が出力となるように調整すればOKです。

KerasでDeep Learning

最近オススメのDeepLearningライブラリKeras。TheanoかTensorflowをバックエンドにして動きます。ProgressBarによる実行状況の確認や入出力レイヤーのバイアスの枠組みとか自動で行ったり、非常に使いやすいです。

Kerasで全結合層
ここに簡単なコードを上げました。
実質10行くらいで書けます。超便利。

ここのInputで入力、Denseで各層を定義しています。引数で前の層を入れておけばOK
これだけで前後の層を勝手につないで重みとかもスケールしてくれるので大変ありがたいです。

ちなみに同じようなやり方で以下のような書き方もできます。

Sequential()定義をすると、層をaddという形でどんどん追加できます。こちらも分かりやすいですね。
ただ、この形だと単純な構造なら良いのですが層の間に色々挟んだりAutoEncoderみたいに学習器を切り離す場合とかは不便です。

巷ではChainerが流行っているみたいですが、こっちの方が楽だと思うんですよね。海外でディープラーニングベンチャー立ち上げた人も時代はKerasって言ってましたし、サポートも充実(?)しており、自動翻訳突っ込んだような日本語ドキュメントもあります笑

今からDeep Learningを始める人はKerasにしてはいかがでしょう?

参考文献

ttp://aidiary.hatenablog.com/entry/20160328/1459174455
ttp://keras.io/
ttp://rnn.classcat.com/2016/03/15/keras-deep-learning-library-for-tensorflow/