ChainerでDCGANを実装しMNIST風の画像を生成する

2017/09/21

DeepLearning, Python

タイトルの通りですが、ChainerでDCGANを実装しMNIST風の画像を生成してみました。

今回使用したコードはこちらに置いております。
https://github.com/rystylee/chainer-dcgan-mnist

DCGAN(Deep Convolutional Generative Adversarial Network)は、2015年にAlec Radfordらによって提案された画像生成の深層学習モデルです。(元論文
DCGANはGANの発展形であり、GANのネットワーク構造に工夫を加えることで質の高い画像を生成できるようになったモデルです。

GANやDCGANの詳しい解説に関しては、以下のサイトがとても丁寧で分かりやすいと思います。
はじめてのGAN
できるだけ丁寧にGANとDCGANを理解する

今回は、このGANを最新版のChainerを用いてモダンな書き方で記述しました。実装の際には、以下のサイトを参考にさせて頂きました。
Chainerを使ってコンピュータにイラストを描かせる
Chainerで顔イラストの自動生成
DCGANをChainerで実装

これらのサイトのコードは、Chainerのバージョンが古くそのままでは最新版のChainerでは動きません。
そのため、Chainer関連のコードを書き換えMNISTを対象とするようネットワーク構造にも変更を加えました。

以下、実装になります。
スクリプトファイルの構成はChainerの公式サンプルを参考にさせて頂きました。

まず、net_mnist.pyです。画像を生成するGeneratorと、Generatorが生成した画像が本物であるかどうか判別するDiscriminatorを構成します。

DCGANでは、Generatorにはfractionally-strided convolution、Discriminatorにはstrided convolutionを用いてアップサンプリングとダウンサンプリングを行います。Batch Normalizationを用いるのがポイントです。
また、元論文ではGeneratorの出力層の活性化関数にtanhを用いていますがここではsigmoidを用いています。(tanh用のコードもコメントアウトして記述しています。使う場合はvisualize.pyの中のsigmoid版のコードをtanh版に変更する必要があります。)
参考にさせていただいたコードでは畳みこみ層の数やハイパーパラメータ等がChainerのサンプルとは異なるものが多かったので、なるべくサンプルに近い形で実装しています。(ですがサンプルのパラメータそのままでは生成される画像が全てほぼ同じ画像になってしまったので、隠れ層の数やカーネルサイズ等には変更を加えています。)

次に学習を行うtrain_dcgan.pyです。

このコードの中で、エポック数やミニバッチのサイズ等の設定を行い、Trainerを使って学習ループを回します。
自分で学習ループを記述することもできますが、ここではTrainerを使って楽をしています。

このコードを実行して得られた結果が以下になります。

今回は100 epochで学習を回してみました。学習はGTX-1070を用いて1時間ちょっとで終わりました。結構早いですね。
しかしPCの熱と音がハンパないです。横に置いていたアイスコーヒーが気が付けばただのコーヒーになっていました。

1 epoch後

2 epoch後

3 epoch後

10 epoch後

50 epoch後

100 epoch後

1 ~ 100 epochまでのGIF

結構早い段階で数字っぽいのが生成できてますね。今回用いたMNISTは1チャンネルでうまく特徴を抽出しやすかったようです。
他にも、アニメのキャラクターやポケモンもどきなど高次元の画像も生成に成功した例があります。色々と試してみると面白いですね。