前回の記事でconditional GANを導入し、構造の説明と実装をおこないました。
今さら聞けないGAN(6) conditional GANの実装
生成した画像を見ていきましょう。
生成画像
z_dim = 100の時の生成画像です。
各行、0から9までの画像が生成されています。これは乱数で発生させた潜在変数zを固定して(共通にして)、生成させる数値のラベルだけを0から9まで変化させたものになります。
同じ書体を保ったまま数字を書き分けているのがわかりますね!
また、各行で潜在変数zの値を変えているのですが、それぞれ字体が違って10人がそれぞれ書いている様にみえますね。
これで、conditional GANで期待していた動作(数値は別に指定して、潜在変数により字体を変える)が実現できました。
潜在変数の次元
潜在変数の次元について見ていきましょう。上でz_dim=100をみたので次はz_dim=50
問題なく生成できていますね。z_dim=100の時より、バリエーションに欠ける気もしますが、epochごとのばらつきもありますので、なんとも言えません。
z_dim=10
このあたりからはちょっと心許ないですね。0や8を生成できていません。それと同じような画像が多くモード崩壊気味ですね。
z_dim=5
完全にモード崩壊を起こしています。表現力不足ですね。数値情報を潜在変数から切り離したので、その分dcganの時よりも少ない次元数でもいけるかな、と期待したのですがそんなことはありませんでした。
クリアで良いですが、100の時よりも明らかに良いかと言われるとそこまででもないような気がします。10000, 100000と上げましたが同様でした。
generatorを混乱させる
ここでは、すこしgeneratorにイジワルをしてみます。画像を生成させるときには潜在変数ノイズとともにラベル情報をone-hotで指定します。たとえば3なら
[0,0,0,1,0,0,0,0,0,0]のようにします。
傾向も見るために、試しに別のノイズzから100個生成させてみます。
ここからイジワルをします。one-hotベクトルに複数のフラグをたてます。たとえば3,7に
[0,0,0,1,0,0,0,1,0,0]のようにするとどんな画像になるでしょうか。学習時にはこんなケースは当然出てきません。
うーん、3のような7のような画像を生成してますね。迷っています笑
2と6でもやってみましょう
微妙なものがでてきました。
次はフラグを立てない、オール0です。
[0,0,0,0,0,0,0,0,0,0]
潜在変数zとone-hotラベルは直接結合され、さらに全結合層に通されます。one-hotが0だからといって特定の層に0が出力されることはないです。
ですのでフラグ情報を立てなかったからといっても画像が生成されないわけではないようです。
ただ、ノイズを毎回変えているにもかかわらず、よく出る数字と出ない数字が偏っていますね。ここは興味深いです。
次はオール1
オール1の場合、全ての数字の重ね合わせになるわけではないですね。
次はフラグを0-1の一様乱数から生成させてみます。
潜在変数の乱数は常に異なります。フラグの乱数は固定です。
[0.24, 0.35, 0.74, ....](←イメージ)
4,8,9のように見えますね。
最後にone-hotオール0の状態から”3”のフラグだけを徐々に増加させて1にします。
3フラグがニョキニョキと伸びていくイメージですね
ループの切り替わりがわかりにくいですが、段々と3のみになっています。
まとめ
generatorで画像を生成して遊びました。
generatorの構造と絡めてもう少し深堀が必要かもしれません。