論文
https://arxiv.org/abs/1703.10717
著者
David Berthelot, Thomas Schumm, Luke Metz
背景
GANはGeneratorとDiscriminatorの2つの関数から構成される、データの分類と生成を行うニューラルネットワークである。 GANは非常に精巧なな分布を生成できる一方で、解決されていない課題も多い。 特に、学習の安定性については非常に難しく、学習が正常に機能しないことが多々発生してしまい、正確にハイパーパラメータを設定することが求められる。
この問題には、GeneratorとDiscriminatorの学習のバランスが非常に重要になる。 一般に、学習の初期はDiscriminatorが早く学習され先に精度が高くなる。 これに起因してmodel collapseと呼ばれる、Generatorが単一の画像しか生成できなくなる現象が起こってしまう。
目的とアプローチ
本論文では、下記の特徴を持つBEGAN(Boundary Equilibrium Generative Adversarial Networks)を提案する。
- シンプルで頑丈なアーキテクチャ
- Generatorの学習率に応じてDiscriminatorの制御
- 画像の精度と多様性を両立
- 収束までの行程の見積りが可能
提案手法
BEGANの設計の概念図を下記に示す。
特徴を下記に列挙する。
- BEGANでは、Discriminatorとしてオートエンコーダを使用する
- 全ての畳み込み層はexponential linear units (ELUs)を活性化関数をとして使用する
- Down samplingはstride=2のsub samplingとする
- Up samplingは近傍点を取得することで実現する
- EncoderとDecoderの境界では、全結合層によってデータの受け渡しを行うものとする
- 通常のlossとは異なり、ワッサースタイン計量から算出したlossを使用する
BEGANのlossの算出式は以下の様になる。
ここで、
- 学習率 = 0.0001
- 畳み込み層のサイズは8×8
- h(全結合層の次元) = z(Generatorの入力次元) = 64
- 一番学習が大きなモデルで、n(チャンネル数) = 128
最大のモデルでGPUを使用して学習に2日半、小さめのモデルで数時間学習させた。
収束の測定
GANの学習が収束したことを判断することは、GeneratorとDiscriminatorのlossが相反するため、非常に難しいとされている。 GANが十分に学習した、あるいはModal Collapseに陥ったことを判定するために、下記の指標を用いる。
補足
ネットワーク全体の構成図は下のようになる。
エンコーダとデコーダを使用した画像分類器を使用したものをDiscriminatorとして使用している。
(参考:オートエンコーダ) deepage.net
(参考:Energy Based GAN)
https://arxiv.org/abs/1609.03126
評価
EBGAN(比較対象)で生成した画像とBEGANで生成した画像の比較を下記に示す。
EBGANでは画像が崩れてしまっているが、BEGANではきれいに生成されており、 安定した学習がされていることが確認できる。
また、画像変換を実行した結果を下記に示す。
比較対象と遜色ない精度で画像が生成できていることが確認できる。
lossと生成される画像を下記に示す。
かなり早い段階で高い精度の画像が生成できていることが確認でき、継続的にlossが減少していることが確認された。
結論
現状の未解決問題は多々ある。
- Discriminatorはオートエンコーダの機能を果たす必要があるか
- 画素レベルでのフィードバック制御は収束のために非常に効果的であるが、オートエンコーダはその再描画の必要があり、潜在層の最適なサイズは不明確
- 入力のノイズはどの程度が最適か、オートエンコーダは他のモデルを使用した方がよいのかなど、問題は山積みである。
本論文では、オートエンコーダをDiscriminatorとして使用することで、GeneratorとDiscriminatorが安定するアーキテクチャを提案した。 この手法によって、重みの動的制御が可能になり、他分野への応用にも貢献できると考えられる。 提案手法では、学習率の調整をしながら画像の解像度は落とさず、GANの課題に対する一つの解決策となっている。
実装
それっぽく書いてあります。細かいところ違っていたらごめんなさい。 論文で使用しているデータセットselebaは、画像サイズを整えるのがめんどくさかったので、今回はCIFAR-10を使用しました。
コードそのまんまはこちら。
https://github.com/nogawanogawa/BEGAN_tensorflow.git
実行結果
i = 0
始めはこんなもんです。なんで真っ黒なのか。。。
i = 2000 × 20
まだなんもわかりません。
i = 2000 × 40
このへんでとりあえずバラバラな画像が生成されていることが確認できたので一安心。
i = 2000 × 60
なんか後ろにいるのは確認できますが、何がなんだかはわかりません。
i = 2000 × 80
段々輪郭がはっきりしてきましたが、まだ何が写っているかわかりません。
i = 2000 × 100
ピントがあってない感じですね。
i = 2000 × 120
惜しいとこまできてるんですがもう少ししないと何が写ってるか判別が難しいです。
i = 2000 × 140
i = 2000 × 160
i = 2000 × 180
i = 2000 × 200
i = 2000 × 220
i = 2000 × 240
最終型
50epoch回してこれなんで、もうノートPCじゃ無理っす。。。 手応え的には、もうあと20epochくらいいけば判別はつくレベルになるかもしれないですね。
感想
書いてみてから気づいたんですが、tensorboardとかでlossを比較して見てみないと、学習がどう良くなったか判断できないですね。。。
なんかツールのバーションが噛み合って無くてtensorboardがうまく起動しないので、覚えてたらそのうちやります。