#1.はじめに
前回、「ProgressiveGAN の潜在空間に、新垣結衣は住んでいるのか?」というテーマについて 調べてみた結果、残念ながら住んでいないことが分かりました。
今回は、最新の StyleGAN2 を使って同じテーマに取り組んでみたいと思います。なお、コードは Google Colab で作成し Github に上げてありますので、自分でやってみたい方は、この「リンク」をクリックし表示されたシートの先頭にある**「Colab on Web」**ボタンをクリックすると動かせます。
#2.StyleGAN2とは?
まず、StyleGANについて説明します。
これは、(a)今までのGAN(ProgressiveGAN) と(b) StyleGANのネットワーク構造を比較した図です。StyleGANは今までとは構造をがらりと変えて、Mapping network とSynthesis network の2つで構成されています。
Mapping network は8層の全結合層から成り、入力の潜在変数z (1,512)を中間出力である潜在変数w (18,512)にマッピングします。
Synthesis networkは9層から成り、入力は4×4×512の定数で、そこへ潜在変数w(A)とノイズ(B)が各層に入力されます。潜在変数wは各層の入力が2つのため、9層×2=18個あります。
潜在変数wはスタイルと呼ばれ主な画像生成(顔の形、肌の色、髪の毛の色、性別など)をコントロールし、ノイズは細部の特徴(髪質や髪の流れ、ヒゲ、そばかす、肌質など)をコントロールします。Synthesis networkの解像度は4×4から順次アップサンプリングし、最終的には1024×1024になります。
このStyleGANは2018年にNVIDIAから発表されました。そして、StyleGAN2はStyleGANの改良版(AdaINの代わりにCNNのWeightを正規化など)として2019年にNVIDIAから発表されたました。
潜在変数z(1×512)より、潜在変数w(18×512)の方が明らかに表現力が豊なので、潜在変数wの探索を行います。
アルゴリズムは、Synthesis networkの9個ある各層において、潜在変数wを適当に初期化して inital image を出力し、target image (新垣結衣の画像)との差をロスとして、ロスが出来るだけ小さくなるように潜在変数wを最適化するものです。
そのために、target image は9種類の解像度の画像(4×4〜1024×1024)で用意しておく必要があります。また、顔画像の切り取り位置が適切でないと今まで学習した内容が生かしきれず、上手く画像生成が出来ないことに注意が必要です。
それでは、実際にやってみましょう。
#4.手順
1)顔画像の切り取り
普通はOpenCVでやるわけですが、StyleGAN2が学習したFFHQデータセットは、dlibを使いalign(顔が直立するように回転させる)して独自の設定の範囲を切り取って作成されているので、自分でオリジナル画像を使う場合も同様な処理を行います。
そして、切り出した顔画像(target image)は、1024×1024の大きさにリサイズします。
2)マルチ解像度データの作成
切り取った顔画像を9種類の解像度の画像に変換します。dataset_tool.py
を使って、Tensorflowの仕様であるマルチ解像度の画像TFRecordを作成します。
3)潜在変数wの探索
マルチ解像度の画像を元に、各層でロスを最小化して、潜在変数wを探索します。結果をターゲット画像は「target」、探索した潜在変数wを元に生成した画像は「generate」としてまとめてみると、こんな感じ。
割と出来が良かったものを選んでいますが、まずまずの出来ではないでしょうか。後一味足らないのが残念で70点くらいかな。
4)潜在変数wによるアニメーション
2つ画像の潜在変数wの差を等分して少しづつ変化させて画像を生成すると、いわゆるアニメーションが作成できます。
オリジナルは1024×1024サイズですが、それではQiitaにアップロード出来ないので、その1/16である256×256サイズで表示しています。さすがに高品質です。
※ このブログで表示している画像は探索試行回数1000回のものですが、Google Colab での探索試行回数は300に設定してあります。探索試行回数を変更したい場合は、projector.py の num_steps の値を変更して下さい。
#5.結論
結論は、「StyleGAN2の潜在空間には、かなり新垣結衣似の人が住んでいました」(笑)です。