CycleGANで普通の木を満開の桜にする

はじめに

定期的に生成系のタスクで遊びたくなる. 今回はCycle GANを使って、普通の木を満開の桜に変換してみることにした。

Cycle GAN

論文はこれ. 中身についてはたくさん解説記事があるので、そちらを参考。

Cycle GANでは2つのドメインの間の写像を学習する。 普通のGANとは異なり、画像を入力してもう1方の画像を出力するGeneratorがある。 また、普通のGANの誤差関数だけでなく、1度Generatorに通した後、もう一方のGeneratorに通して再構成誤差を計算し誤差関数に加える。

pix2pixなどでは対になる画像を用意しないと学習ができないが、CycleGANではそういうのがいらないという利点がある。

実験

ImageNetから桜の画像3000枚と普通の木の画像2500枚をダウンロードした. 画像をざっと見た感じ,桜は木全体だけでなく花だけアップの写真が多くて少し気になった. また,桜と富士山が写っている画像も結構多い.

著者の実装githubで公開されているので,それにダウンロードしたデータを食わせる. gtx780tiで2日ぐらい学習させた. 古いGPUGPUメモリが全然足りないので,オプションで色々設定した。(そろそろ買いたい)

$ python train.py --dataroot ./datasets/tree2sakura --name tree2sakura --model cycle_gan --no_dropout --pool_size 50 --loadSize 128 --fineSize 128

結果

1エポック後

元画像 生成画像 再構成画像
f:id:ksknw:20170827212704p:plain f:id:ksknw:20170827212731p:plain f:id:ksknw:20170827212752p:plain
f:id:ksknw:20170827212712p:plain f:id:ksknw:20170827212723p:plain f:id:ksknw:20170827212800p:plain

50エポック後

元画像 生成画像 再構成画像
f:id:ksknw:20170827212240p:plain f:id:ksknw:20170827212326p:plain f:id:ksknw:20170827212256p:plain
f:id:ksknw:20170827212233p:plain f:id:ksknw:20170827212315p:plain f:id:ksknw:20170827212248p:plain

100エポック後

元画像 生成画像 再構成画像
f:id:ksknw:20170827202729p:plain f:id:ksknw:20170827202725p:plain f:id:ksknw:20170827212050p:plain
f:id:ksknw:20170827202852p:plain f:id:ksknw:20170827202846p:plain f:id:ksknw:20170827212103p:plain

100エポックのネットワークで普通の木を桜に変換したもの

白と黒を変換しがちなのが少し気になるけど,なかなかうまくできたと思う.

良さそうなもの

 元画像 生成画像
f:id:ksknw:20170828195918p:plain f:id:ksknw:20170828195929p:plain
f:id:ksknw:20170828200024p:plain f:id:ksknw:20170828200034p:plain

よくなさそうなもの

 元画像 生成画像
f:id:ksknw:20170828200231p:plain f:id:ksknw:20170828200238p:plain
f:id:ksknw:20170828200318p:plain f:id:ksknw:20170828200326p:plain

空が白っぽいとその部分を黒で塗りつぶす傾向がある。なぜかはわからない。

おわりに

既存のコードを動かしただけだけど、思ったよりもうまく動いた。 が、空が異常に暗くなるなど、できてないやつも多い。体感では半々ぐらい。

せっかく対応する画像がなくても学習できるので、こちらでやられている犬猫変換のように、それなりに離れたドメイン間でやると面白そう。

生成系の研究はレッドオーシャンな感じで自分でやるのは大変そうだけど, 公開されているもので遊ぶのは楽しいので、ちょいちょいやっていきたい.

参考