cedro-blog

Keras で変分オートエンコーダ(VAE)をセレブの顔画像でやってみる

今回は、畳み込み変分オートエンコーダでセレブの顔画像を2次元マップにマッピングしてみます。

こんにちは cedro です。

最近、多様な画像を2次元マップに綺麗な分布で落とし込んでくれる変分オートエンコーダにはまってます。

先々回はMNISTで、先回はオリジナルデータセット(モノクロ28×28の顔画像)でやってみましたが、せっかくならセレブ顔画像でもやってみたくなりました。

Keras のサンプルプログラムには、精度の高い畳み込み変分オートエンコーダがありますので、今回はこれを改造して使ってみたいと思います。

というわけで、今回は、畳み込み変分オートエンコーダでセレブの顔画像を2次元マップにマッピングしてみます。

 

データセットを準備する

データセットは、6/21のブログ「NNabla PGGAN セレブの顔画像を生成する」でダウンロードした CelebAを利用します。

 

約20万枚あるCelebAデータセットの内7万枚分を、OpenCVで顔部分を切り抜きカラー64×64リサイズします。

 

サンプルプログラムを格納したフォルフダーに face フォルダーを作り、その下に0フォルダーを作り、7万枚の画像データは全てこの0フォルダーに格納します。

本当は、データセット属性リスト(性別、髪色、目色など)に従ってラベル分けしておくと、属性毎ドット分布も見ることが出来るんですが、面倒なので今回は省きます。

VAEは、教師なし学習で、ラベルを見ずに分布を作るため、画像2次元マップマッピングするだけなら、ラベル分けは不要です。

 

プログラムを改造します

kerasサンプルプログラムvariational_autoencoder_deconv.py)を改造します。

 

新たに必要なパッケージを追加でインポートします。

 

2次元マップドットで分布を表示する部分です。データは1種類だけなので、c=y_test は削除し、colorbar は表示させません。また、filenameもあえてディスプレイに表示させません(一端表示すると、表示中止ボタンを押すまで動作が中断して、使い勝手が悪いので)。

 

2次元マップ画像をマッピングする部分です。マップが30×30では顔画像が小さくなって見難くなるので、15×15に変更しています。そして、モノクロ28×28カラー64×64への変更に伴う修正をしています。

また、出力画像は後でGIF動画を作成するために、1枚づつ 0@0fig.png 〜 14@14fig.png まで225枚分(15×15=225)を保存する設定にしています。

 

データセットの読み込み部分です。MNISTの読み込み部分は、無効にします(削除でもOK)。

list_picture, load_img, img_to_arry を使ってデータを読み込んで必要な処理をした後に、train_test_split  で学習用80%・評価用20%に分割しています。

 

ネットワークを構築する部分です。モノクロ28×28 カラー64×64 の変更に伴う修正をしています。

そして、2箇所ある、for  i  in  rage (2) →  for  i  in range (3) に変更することで、エンコーダデコーダ畳み込みレイヤー2段から3段にパワーアップさせ、これに伴い fllters16→32に変更しています。

 

エンコーダーの構成図はこんな形(プログラムが出力する vae_cnn_encoder.png です)。畳み込みの部分は、カラー64×64の入力を32×32フィルター64枚で受けてから、8×8フィルター256枚まで次元圧縮(1/4 )しています。

 

デコーダの構成図はこんな形(プログラムが出力する vae_cnn_decoder.png です)。畳み込み部分は、エンコーダの逆です。

 

プログラムを動かしてみます

 

プログラムを格納したフォルダーで、上記コマンドを入力するとプログラムが起動します。学習時間は、GTX1060で1eopch 100sec 程度、50epoch で約80分でした。

これは、2次元マップドットで分布させたものです。データが1種類しかないので1色だけです。分布状態は、まずまずではないでしょうか。

 

これは、2次元マップ画像を分布させたものです。

それでは、2次元マップに分布した画像青矢印に拾って、GIF動画にしてみましょう。

 

先回のGIF動画は、顔の向きだけが分かる程度でしたが、今回は性別や顔の作りも多少区別ができ、表現力が向上しています。

VAEのポテンシャルの高さを改めて感じます。

では、また。