まっそのせかい

やった事のメモとか

CycleGANで推しキャラを相互に変換してみた

はじめに

カードキャプターさくらクリアカード編が終わってしまい絶望したので、GANを使ってさくらちゃんの生成を試みようと思いました。
GANにはいろいろなものが提案されていますが、調査をしているとCycleGAN(論文)という面白そうなGANがある事を知りました。CycleGANでは2種類の画像A,Bを互いに変換する事ができるそうです。そこで今回はCycleGANを使って推しキャラであるさくらちゃん(カードキャプターさくら)と島村卯月(アイドルマスターシンデレラガールズ)の2名を相互に変換する事を試みます。
単にさくらちゃんを生成するだけなら他のGANでも良いと思われますが、単純にCycleGANを試してみたいというのもあり、何より推し2名を相互に変換するという罪深さ(?)に魅入られました。
(両陣営からボコボコにされそう)

今回試した結果、以下のような画像が得られました。

  • 卯月→さくら

f:id:massoumen:20180701191305p:plainf:id:massoumen:20180701191319p:plain

  • さくら→卯月

f:id:massoumen:20180701191645p:plainf:id:massoumen:20180701191648p:plain

良さげなものを載せましたが、全部ここまで綺麗という訳ではないですね…
実際は細部が崩れてたり、見るのがつらいものも多々…(

CycleGANとは

基本的なGANではGenerator(生成器)とDiscriminator(判別器)を1つずつ用意しますが、CycleGANでは2種類のデータA,Bに対しGeneratorとDiscriminatorを2つずつ用意します。 (ここではAがさくらちゃんの顔画像、Bが卯月の顔画像となります)

各GeneratorとDiscriminatorは以下の処理を行います。

  • G_{A→B}:Aを入力しBを生成
  • G_{B→A}:Bを入力しAを生成
  • D_A:本物のAとG_{B→A}で生成されたA(偽物)を分類
  • D_B:本物のBとG_{A→B}で生成されたB(偽物)を分類

CycleGANでは各{G,D}に対し基本的なGANで用いるAdversarial Loss({L_{GAN}})だけでなく、Cycle Consistency Loss({L_{cyc}})という損失を用いているのが大きな特徴になります。
L_{cyc}ではG_{A→B}にAを入力して得られた出力BをG_{B→A}に入れ、最終的に得られた出力A'が元の入力Aとどのくらい近いか(画素値の差)を求めます。Bについても同様です。
L_{cyc}を用いる事で各Generatorに元の入力に戻しやすいような変換をGeneratorに行わせる事ができます。ここではキャラの顔画像を用いるので、顔の向きなどを保った変換を期待できます。

従来提案されているような画像の変換(pix2pixなど)では変換前と変換後のペアを用意して学習する必要があったのが、L_{cyc}を導入する事によりペアである必要がなくなるというのがCycleGANの大きな利点です。今回行うようなキャラクターの変換をpix2pixなどで行う場合、さくらちゃんと卯月の画像のペアが同じ位置や向きをしている必要がありデータを用意する事が難しいです。一方CycleGANでは画像のペアを用意する必要が無く、単にさくらちゃんと卯月の画像がある程度確保できれば学習する事ができます。

L_{cyc}ではA→B→Aと変換した時に元に戻る事ができれば良いので、必ずしも同じ顔の向きで変換が行われる保証は無いと思われます。(直感的には同じ向きや表情で変換する方が戻しやすいとは思いますが…)
この辺りが少し怪しくはありますが、少なくとも論文の画像や今回試した結果を見る感じでは割と上手くいってるので良いという事にします。

今回、コードはここを参考にしました。
Generatorではストライド2の畳み込みでサイズを小さくした後Residual Block(入力を最後に足す事で残差を学習する奴)を用い、最後に転置畳み込みでサイズを元に戻し出力します。
また、Discriminatorでは通常のCNNを利用します。
(論文だとPatchGANを利用していると書いてあった気がしますが、どうなんでしょうね…)

顔画像に関しては以前卯月識別器を作った時のように、アニメをキャプチャしたものから顔部分を切り取って利用しました。
枚数は卯月、さくらちゃん共に約700枚くらいです。

おわりに

変換結果をざっと見た感じ、ある程度は変換できていますがどれも高品質とは言い難かったです。
モデルの改良とかパラメータ調整とかしたらいい感じになるんですかね…
(学習に時間がかかるのであまりパラメータ変化による出力の変化などを見れてません)
とは言うものの、機械学習での変換には普通1対1対応の画像を用意する必要があるので、その必要が無いというのはすごいなと思いました。
CycleGANを多対多にしたStarGANという変換モデルも提案されているそうなので、そのあたりも試してみたいですね。