機械学習で美少女化 ~ あるいはNEW GAME! の世界 ~

| NEW GAME! フィルタを通した著者 |
|:-----------:|
|![myface2d_new.gif](https://qiita-image-store.s3.amazonaws.com/0/28934/5a61444b-f39c-138b-7500-dabe4738e5ff.gif)|


| NEW GAME! フィルタを通したドワンゴの風景 |
|:-----------:|
|![test.png](https://qiita-image-store.s3.amazonaws.com/0/28934/671b83f7-3edb-4f0a-e38f-347831c4168b.png)|


[NEW GAME!](http://newgame-anime.com/) というアニメはご存知でしょうか。女の子たちがワイワイとゲーム会社で働く日常を描いた作品で、非常に良い作品なのですが、一方でこんなキラキラした会社ねーよと言われた挙句、実はあそこにいるのは皆中年男性で、働きすぎて周りが皆美少女に見える幻覚が見えているのではないかという説まであったりします。ドワンゴのslackには、バーチャル彼女生成系チャンネル#kanojo_createや、美少女変身願望チャンネル#become_bishoujoというものが存在するので、現実を捻じ曲げてしまう異もあながちあり得ない話ではないのではないかとも思ってしまいます。

私もそんな一人であり、そんな美しい幻覚なら喜んで受け入れよう、ということで作ったのがこのリアルタイムNEW GAME!フィルタです

似顔絵データが存在しない = 転移学習
====================================

さて、ここでやりたいのは、**実写画像を入力として、その実写画像に似てはいるが、二次元美少女に見える画像を機械学習で生成する**ことです。

まさにそのものズバリ、という研究はないのですが、シンプルに考えるなら、この問題は以下のようなネットワークで実現できることがわかります。

|最終的に作りたいネットワーク|
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/622f2e5c-1a56-1f56-b6e2-257eb0821bfa.png)|

しかし、このアイデアには問題があり、**入力(実写)と出力(似顔絵)の対応付けられたデータセットが必要だが、それは手に入らない**のです。自分には絵を描くスキルがないのに、絵を描かないと学習ができないというのは辛い問題です。

ここで、問題をいくつかのステップに分割することでどうにかこうにかやりくりして学習することを考えます。このように、そのものずばりのデータがない、などの理由でバシッと解けない問題を、複数の部分問題を順番に解いていくことで何とか解決する学習方法を転移学習と言います。

似顔絵ネットワークの学習は、次の3STEPに沿って進んでいきます。

| Step | 内容 | ネットワーク |
|:-----------|:------------|:------------|
|1|とりあえずなんらかの美少女が生成できるネットワーク| ![image](https://qiita-image-store.s3.amazonaws.com/0/28934/7232746d-e9a3-f8c9-3f9e-71783a95b1cb.png)|
|2|入力のイラストに似せた美少女を複製できるネットワーク|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/dfdc7e35-ed25-961c-efec-dc7d4c03354c.png)|
|3|実写を入力として、それに近い美少女を生成できるネットワーク|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/3828894e-247e-b82f-31ef-9a36e8f26772.png)|

アーキテクチャの全体図は以下のようになり、青のGeneratorをどんどん強くする形になっています。

|転移学習アーキテクチャ|
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/936031f9-cf47-c59d-34dd-c7bb83d78eed.png)|

STEP1: Generator = ランダムイラストネットワーク
==============================================

| STEP1でやりたいこと |
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/7232746d-e9a3-f8c9-3f9e-71783a95b1cb.png)|

似顔絵生成の問題の第一歩として、まずは、様々なイラストを描くことができるネットワーク、を作ります。これは2016年に非常に盛り上がった手法で、沢山の先行研究があります

* [Chainerで顔イラストの自動生成
](http://qiita.com/mattya/items/e5bfe5e04b9d2f0bbd47)
* [Chainerを使ってコンピュータにイラストを描かせる
](http://qiita.com/rezoolab/items/5cc96b6d31153e0c86bc)
* [TensorFlowによるDCGANでアイドルの顔画像生成](http://memo.sugyan.com/entry/20160516/1463359395)

ここでも、これらの例に漏れず、まずはGeneratorについて、DCGANを用いた学習を行います。ここでは、まだ実写のことは考えずに、イラストのデータだけを使って学習することができます。イラストは、[nico-illustデータセット](https://nico-opendata.jp/ja/index.html)から20万件ほどを用いて学習しました。

| Generatorの学習 |
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/cb37a92b-35cf-6e4c-bee3-068ce826bfa7.png)|

詳細については前述のブログに任せますが、新しく、入力が実在のイラストか生成画像かを判別する赤色の _Discriminator_ を導入し、これを騙すように青色の _Generator_ をトレーニングすることで、Generatorが様々なイラストを描ける能力を獲得するものです。

| 結果1: Generatorによって創作されたイラストたち |
|:-----------:|
|![generator_model_3010000.png](https://qiita-image-store.s3.amazonaws.com/0/28934/11245f59-a85b-1a0c-a542-54141f41616c.png)|

このトレーニングによって獲得した、イラストを描く能力、の結果はこちら⬆︎。それなりに納得のいくイラストができました。ただし、この段階では、**こうこうこういうイラストを描いてくださいという注文をすることはできません**

STEP2: 入力のイラストに似せたイラストを複製
==========================================

では、自分好みのイラストを描いてもらうにはどうしたらいいでしょうか。
こちらに関しても、文章などで何らかの注文(条件)を追加する先行研究があります。
今回は最終的に実写->イラストとしたいため、画像を条件として入力し、なるべくそれに近い画像を生成するように学習します。

| STEP2でやりたいこと |
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/dfdc7e35-ed25-961c-efec-dc7d4c03354c.png)|

上図のように、STEP1で学習したVectorizerに加えて、Vectorizerというあらたなネットワークを導入し、これによって、 **入力画像を復元できるGeneratorの入力パラメータを見つけます**

| Vectorizerの学習 |
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/8aeba268-8b9b-59df-fe08-fe8a6ea18a6e.png)|

学習の方法は上図の通りで、STEP1で学習したGeneratorをつかえば、ランダムなパラメータと、それをGeneratorに入れたときにできた画像を無限に用意できるので、それらを学習データとして、逆にもとのパラメータを復元するようにVectorizerを学習するのみです。

このSTEPが終わると、**Generatorによって生成された画像であれば、ほぼ完璧に復元でき、一般のイラストもある程度再現できるようになります**。ただし、このネットワークはイラストしか見たことがないので、**実写画像については、まだ似顔絵を描くことはできません**

STEP3: 実写画像を入力として似顔絵を生成
==========================================

|STEP3でやりたいこと|
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/622f2e5c-1a56-1f56-b6e2-257eb0821bfa.png)|

さて、機械学習を専門とする人にはここが一番面白いところかと思います。いままで、イラストしか学習してこなかったネットワークにどうやって実写画像からの似顔絵生成を行わせるか。

まず、前提として、Generatorは何を入力してもイラストにしてくれるので、STEP2までのVectorizer->Generatorでも、何らかの顔イラストは生成することはできます。ここでやりたいのは、"入力実写画像の特徴を保った出力イラストを作る"という制約をどうやって学習させるか、です。たとえば、安直に、もとの入力と画像的に近いイラストを出力するように、と考えてしまうと、これは似顔絵ではなく実写画像そのままを作ってしまいます。

この問題を解決するためには、**実写画像と似顔絵では共通しているべき特徴のみを保存する**という方法が必要です。

| 実写画像Vectorizerの学習 |
|:-----------:|
|![image](https://qiita-image-store.s3.amazonaws.com/0/28934/3828894e-247e-b82f-31ef-9a36e8f26772.png)|
|実写画像 -> Vectorizer -> Generator -> (似顔絵) -> Classifier -> 元の顔の特徴|

上図のように、新たにClassifierを導入し、一旦STEP2のVectorizer->Generatorを経由して、似顔絵を無理やり作り、その似顔絵から、 **元の画像の特徴(若い、丸顔、くまがある etc...)を識別できるように、Classifier、Generator、Vectorizerをまとめて学習し直します**。顔の特徴のタグがつけられてるデータセットとして、[Large-scale CelebFaces Attributes (CelebA) Dataset
](http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html) を利用しました。

なお、Vectorizer、Generator、Classiferともに5層のニューラルネットワークで構成しているので、STEP3まで至ると、まとめて15層の(ディープ)ニューラルネットワークとして扱っていることになります。

実験結果
===========================================

ここまでで、すべてのステップの学習が終わりました。以下に、実際に実写画像を美少女に変換した結果を数枚載せます。

| なぜか我々が放り込まれている世界 | ほんとうの世界(美少女) |
|:-----------:|:-----------:|
|![img_q1.jpg](https://qiita-image-store.s3.amazonaws.com/0/28934/57f71b9b-216e-8ec9-c141-1d54627c2612.jpeg)![img_q4.jpg](https://qiita-image-store.s3.amazonaws.com/0/28934/75be7964-c584-3c5a-2d53-cd0c0ecb023e.jpeg)[ドワンゴ採用ページ](http://dwango.co.jp/saiyo/people/field1.html)|![test.png](https://qiita-image-store.s3.amazonaws.com/0/28934/671b83f7-3edb-4f0a-e38f-347831c4168b.png)![test.png](https://qiita-image-store.s3.amazonaws.com/0/28934/9911b1f1-4820-bcde-fdd9-4daa6f255f22.png)|
|![YUKA0I9A7452_TP_V.jpg](https://qiita-image-store.s3.amazonaws.com/0/28934/3af7db9c-c56a-cb6b-6033-35b44367910f.jpeg)https://www.pakutaso.com/|![test.png](https://qiita-image-store.s3.amazonaws.com/0/28934/ea175e46-031e-b1b8-ef3a-d836b3bf2eae.png)|

これらの実験結果から、髪型や顔向きについて保持しつつ、実写画像をいい感じに美少女画像に変換成功していることがわかります。また、眼鏡もギリギリ再現できているのですが、これはSTEP3の学習が進むことによって成功するようになりました。

多少重たい処理なのですが、手元のMacBookPro環境でも、webカメラから入力した画像を使ってほぼリアルタイムで動かすことができます。頑張ればすべての人間を美少女に変換するゴーグルも作れそうな気がします。Hololensが、ほしい！！

なお、コードと学習済みモデルは https://github.com/Hi-king/kawaii_creator で公開しているので、ぜひお試しください。

まとめ
===========================================

* 実写とイラストの対応データセットがなくても、なんとか似顔絵ネットワークを学習することはできる
* 実写とイラストという、異なるドメインの学習を行うには、それぞれの問題を同一のネットワークを利用して順番に学習していく、転移学習が有効。

参考文献
===========

* GAN
    * 論文: https://arxiv.org/abs/1511.06434
        * その実装:  https://github.com/mattya/chainer-DCGAN
    * 文章 -> 画像生成
        * 論文: https://arxiv.org/abs/1605.05396
        * 解説記事: http://www.slideshare.net/mmisono/generative-adversarial-text-to-image-synthesis 
        * 解説記事: http://niconare.nicovideo.jp/watch/kn1626

* 顔認識
    * 論文: [From Facial Parts Responses to Face Detection: A Deep Learning Approach](https://arxiv.org/abs/1509.06451)
    * データセット: [Large-scale CelebFaces Attributes (CelebA) Dataset
](http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html)

* クロスドメインの学習
    * 論文: https://www.eecs.qmul.ac.uk/~qian/Project_cvpr16.html