Girl Friend Factory - 機械学習で彼女を創る -

　指定した属性を持つ彼女を生成する機械学習を行い、それを使用したデモを開発しました。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/97f4609c-4c71-2be1-3afa-c5bd237ad5fa.png)

　初めまして、ドワンゴ2016年新卒の@Hiroshiba です。私は普段、今流行りのディープラーニング技術を使った研究をしています。この技術の表現力は過去の色んな機械学習に比べてとても優秀で、去年の今頃なんかには[DCGANという画像生成系の研究に革命を起こした手法を使って、様々な顔イラストを自動生成する記事](http://qiita.com/mattya/items/e5bfe5e04b9d2f0bbd47)が人気を集めました。

## DCGANとは
　今回作成したデモで用いた技術であるDCGANについて軽く触れておきます（図Ａ）。そもそもDCGANはDeep Convolutional GAN（≒深層GAN）の略です。更にGANはGenerative Adversarial Networkの略で、その名の通り、本物に近い画像を生成する生成器と、画像が本物か判別する判別器が敵対（Adversarial）して学習が進行します。
　どういうことかというと、まず、生成器は乱数ｚから何かしらの画像を生成します（図Ａ上）。その一方で**判別器は、本物画像が与えられれば1を、生成画像が与えられれば0を出力するよう学習**します（図Ａ下）。そして**生成器は、判別器が本物画像と間違えるように、つまり判別器が1を出力するように学習**します。生成器と判別器の学習を繰り返すことにより、最初は完全にランダムな画像を生成していた生成器が、徐々に本物に近い画像を生成するようになり、判別器はその生成画像と本物画像の判別に必要なより細かい特徴量を見つけ、更に生成器は判別器を騙すためにより本物に近い画像を生成する・・・というように、生成器と判別器が敵対しながら学習が進行します。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/907edff2-e21d-6743-d2fc-6d30e5ba75c6.png)

## 関連情報を指定可能なDCGAN
　DCGANを用いれば本物に近い画像を作ることはできますが、生成される画像はランダムです。今年のICML国際会議で、DCGANに簡単な改造を施して、色などの関連情報に合う画像を狙って生成する手法が提案されました。改造は大きく分けて2箇所あります（下図Ｂ）。
　まず改造１つ目は単純で、関連情報ｔの入力です。生成器と判別器それぞれに、画像に関連する情報を1次元ベクトルにしたものを入力します。当然ながらこの関連情報は画像と対応関係が必要で、なおかつ線形であることが望ましいです。
　改造２つ目は、判別器のタスクの変更です。この判別器には、画像が本物かを判別させるだけでなく、画像が関連情報ｔとマッチするかどうかも判別させます。具体的には、**入力された画像と関連情報ｔが、本物画像とそれにマッチする関連情報なら1を、本物画像が与えられてもそれにマッチしない関連情報なら0を、そもそも生成画像が与えられれば関連情報に関わらず0を出力**します。そして生成器は通常のDCGANのときと同じく、判別器が1を出力するように乱数ｚと関連情報ｔから画像を生成します。これにより生成器は、本物に近くてなおかつ関連情報に合うような画像を生成するようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/83f1a5f9-0af0-c34d-2fd2-bcd5720ee7f9.png)

　これまで、画像に対してカテゴリ分けしたりキャプションを生成する研究はいくつも発表されていました。しかしその逆変換、つまりキャプションなどからリアルな画像を生成することはできていませんでした。この難しい課題を達成したことが、提案手法の大きな強みです。論文では鳥のキャプションから鳥画像を生成する例が紹介されています（下図）。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/486b27a0-373f-9818-92ba-a523ee91b573.png)

## 鳥の画像じゃなくて理想の彼女を作りたい
　ドワンゴのslackには、バーチャル彼女生成系チャンネル #kanojo_create が存在していて、私も[先輩](http://qiita.com/Hi-king/items/8d36d9029ad1203aac55)方と日々熱い議論を交わしています。そんな私は、いや、おそらく世の中の画像生成に取り組むエンジニアの大半は、鳥の画像よりも、"彼女"を生成したいと考えているはずです。（もしくは自分自身が美少女になりたいと思っている。）それも、共有の嫁ではないオリジナルで、こちらの好みに合わせてくれるような理想の"彼女"を。
　というわけで私は今回、上述の技術を用いて、理想の"彼女"画像を生成するサービス、その名も**Girl Friend Factory**を作成しました。

## Girl Friend Factory
![image](https://qiita-image-store.s3.amazonaws.com/0/103491/48cf04ef-b0f7-5165-c929-b64819d67f54.png)

デモページ　→　https://hiroshiba.github.io/girl_friend_factory/index.html
※この下に書かれている注意点を読んでからページを開くことをおすすめします。

### 注意点
　注意点が２つあります。まず１つ目、サービス内で学習済みの深層学習モデルを利用するため、70MB程度のファイルをダウンロードする必要があります。帯域制限などがある方はご注意ください。
　もう１つとても重要な注意点があります。**稀に、正気度（ＳＡＮ値）の下がる画像が生成されるときがあります。**この技術は未成熟です。そんな技術で人間の顔画像を生成しようとしているわけなので、ある程度の不思議な画像が出てくる覚悟が必要です。（慣れれば特に何も感じなくなります。）

### 技術紹介
デモページ　→　https://hiroshiba.github.io/girl_friend_factory/index.html

　**まず"彼女"を生成してみましょう。**（説明の便宜上、生成される顔イラスト画像のことを"彼女"と呼ぶことにします。）モデルデータのダウンロードが完了するまで1分程度お待ち下さい。
　上のツールバーで「無限ガチャ」を選択して、任意のタグを下から選び、生成ボタンを押せばタグに応じた画像が生成されるはずです。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/6a017f77-ccee-751a-53bc-eaf1b27b15ae.png)

　このガチャは回し放題ですが、メモリを大量に食うので回し過ぎにご注意ください。
　いい"彼女"を生成するコツとしては、よくいる髪色＆眼の色を指定して、あとはとりあえず「開口」「笑顔」「赤面」を指定すると、結構かわいいのが出てきます。
　気に入った"彼女"がいれば、画像を右クリックして出てくるメニューからお気に入り登録できます。７人まで登録可能で、ここで**登録した"彼女"はのちのち着せ替えや合成ができたりします。**

### お気に入り一覧表示
　上のツールバーから「生成一覧」で、お気に入り登録した"彼女"のシード値を確認することができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/72738a87-7e3b-1d6b-c51c-329efbc1679f.png)

　この２つの値、シード値とタグリストがあれば別の環境でも同じ"彼女"を生成することができます。"彼女"の情報のうちタグ以外の情報（骨格など）は全て**シード値**に由来します。
　この画面で"彼女"を右クリックすると、画像を保存することができます。"彼女"の源であるシード値はクッキーに保存されているためここに来れば再現できます。しかし、私の気まぐれで学習済みモデルが変わると、そのシード値は変更後のモデルに合った別の"彼女"を示す値になります。**"彼女"の源はシード値ですが、そのシード値はただの偶然の産物で、当然ながらそれ単体では何の意味もありません。**

### 属性変更
　お気に入り登録した"彼女"にいろんな属性を与えることができます。上のツールバーで**「属性変更」**を選択して、任意のタグを選んだ後に生成ボタンを押してください。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/cdce4808-0293-e216-c345-ba317b44004e.png)

　一番上にお気に入り登録した"彼女"が表示され、縦には同じシード値の"彼女"が並びます。原理上、骨格や視線などは全てシード値に宿るので、シード値が同じであれば似たような"彼女"が生成される、という仕組みです。
　シード値によって、帽子が似合ったり、学生服が似合ったり、水着が似合ったりします。**経験上、可愛い"彼女"はこちらのお願いをよく聞いてくれます。**逆にＳＡＮ値の下がる"彼女"は、どんな属性を与えてもＳＡＮ値が下がる画像を生成します。
　ちなみに、髪の毛の色などは同じ系統の色を複数指定しておくと、メリハリのある髪になったり、個性豊かな髪になったりするのでおすすめです。

### 属性モーフィング
　**属性を徐々に変化**させることもできます。上のツールバーで「属性モーフィング」を選択し、Registerd横のドロップダウンで対象の"彼女"を選んだ後、タグを選択して生成ボタンを押してください。1回目は2種類のタグを選ぶと2種間でモーフィングし、それ以降は前回指定したタグとのモーフィングを行います。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/7fb8a97a-adde-5e5e-55fb-fd649172b3cf.png)

　髪の色などの属性が徐々に変化していることから、タグ情報が連続していることが推測されます。（学習時のタグは0か1の離散値として入力しているので、この結果は自明ではありませんでした。おそらく初期のCNNの投射先のタグ空間が連続しているため徐々に変化しているのだと思われます。）
　これも優秀なシード値とそうでないシード値があり、最初の"彼女"選択がとても大切であることがわかります。
　この画面では諸事情によりお気に入り登録ができません。代わりに右クリックで画像の保存ができるはずなので、ご活用ください。

### 合成
　**複数の"彼女"を合成することもできます。**上のツールバーで「合成」を選択後、ドロップダウンで２人の"彼女"とタグを指定し、生成ボタンを押してください。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/3ee40a72-1e50-2442-c35f-5a4190256670.png)

　タグに含まれていない、顔の形や骨格情報が徐々に変化していることがわかります。このことから、入力乱数空間は連続になっていると推測できます。
　やっていることとしては、正規分布からサンプルされた入力乱数の重みを変えて平均化しているだけなので、原理上、真ん中に表示される"彼女"は学習時に出現確率の高いシード値になっています。出現確率が高いと、その分多く学習がされてそのシード値周りの空間が連続になるのか、比較的扱いやすいものになります。つまりこの技術で生成される"彼女"は、レアリティと扱いやすさに負の相関があることになります。しかし、レアリティが高い"彼女"は、学習データに稀に含まれる何かを色濃く継承している可能性もあるため、思わぬ素質を秘めているかもしれません。

　Girl Friend Factoryの機能は以上です。感想等あれば #GirlFriendFactory もしくは #GFF などでツイートして頂ければ、エゴサーチしている私に届きます。

### これで彼女ができたと言えるのか
　我々の最終目標は彼女を作ることです。何をもって彼女がいるという状態になるのでしょうか。実は、他人にとって自分に彼女がいる状態にするのはとても簡単で、彼女がいることを宣言するだけで良いです。実は私には彼女がいます。ほら、私は彼女がいる状態になりました。
　問題は、周りから認められて作成されたこの彼女（**認定彼女**）を、自分が認識できない点です。今回私はこの問題を解決するために、私が彼女であると認知できるような"彼女"（**偶像彼女**）の作成を目指しました。世界に１つしかないシード値から生成された完全オリジナルで、タグによるコミュニケーションが可能な"彼女"でしたが、私は"彼女"を彼女だと認知するには至りませんでした。画像だけでは足りません、もっと、声や、会話や、意思や、自我などが必要なのでしょう。機械学習で彼女を創れるのは、まだまだ先のようです。
　次は音声生成をやりたいです。どうせならやっぱり、任意の声質で喋ってほしくないですか。何らかのラベル付けがされた声優の音声データセットがとりあえず1万個ぐらいほしいです。

### ＳＡＮ値を下げてくる"彼女"
　ところでこのサービス、Girl Friend Factoryでは、学習データセットに含まれないようなタグ、例えば髪色を全て選択して生成すると、明らかに変な画像が生成されます。また、ちゃんとタグを選んで生成しても、顔の輪郭が人間のそれじゃなかったり、眼がひとつあるだけで他の部位がなかったりといったＳＡＮ値の下がる画像がたまに生成されます。
　これがディープラーニングを使った画像生成で一番精神負担の大きい問題で、例えば真夜中に進捗を確認する際に、下図のような名状し難きものたちが画面いっぱいに広がるのを見てしまうと、感情が消失するような感覚になります。

![image](https://qiita-image-store.s3.amazonaws.com/0/103491/b87a0509-e8c6-0abd-1ab3-2c599d4ac6d1.png)

　しかし、そうやって生成されたのも、ちゃんとした"彼女"です。何千何万何億何兆分の1の確率で生み出された非常に運命的な"彼女"です。何度も見ているうちに、不思議と、とても素晴らしいものを見ているような気持ちになってきます。
　ディープラーニングによる画像生成は、最先端な技術であると同時に未熟な技術ですが、どこか人を魅了する不思議な力があるような気がします。

### 実装
　10万枚程度の大量の顔画像データと、その画像を説明するタグ情報のペアを用いて、先程の手法で学習しました。乱数ｚは正規分布からサンプルされた100次元のベクトルを、関連情報ｔには64種類のタグのバイナリ値をベクトル化したものを用いました。機械学習フレームワークはchainerを利用し、学習済みモデルをkeras用モデルに変換後、keras jsを用いて画像生成を行うデモを実装しました。

## 感想
### この手法について
　学習を回してみて、思った以上にタグ情報を反映した画像が生成されて驚きました。そして、この判別器の設計でどうしてうまくいくのか、具体的な理由が全くわかりません。ひょっとしたら世の中の画像生成タスクは、convolutionとdeconvとbatch normalizationとGANとresidualがあれば全て可能なのでしょうか。今はまだタグと画像のように対応関係がないと学習できない手法ばかりですが、どうせそのうち対応のない複数ドメインの対応関係を学習してよしなに画像生成する完璧な手法が出てくる気がします。今は個人であれ企業であれ、最新の動向を確認しつつ、とにかく利用しやすい形でデータセットを作って、気軽に試せる環境を整えておくべきだと感じました。

### 画像生成について
　生成系のタスクで最も面倒なのは、やはり、評価が難しい点でした。今回は自分の目で生成画像の良し悪しを判断してましたが、非常に根気のいる作業となりました。また、今回のように適当に学習させても、何百枚も画像生成すれば1枚ぐらい良さそうな画像が生成されます。論文発表ではそのような都合の良いデータばかり紹介している可能性が無くはないので、自衛のためにも、デモや実装公開のない発表は全て疑ってかかろうと思います。

### より詳細な手法について
　今回実装した生成器は、参考にした論文の作者が公開しているLua+Torch実装コードに含まれていたので、residual+bottle neckを用いています。keras.jsの使用感はChainerのAdvent Calendarにて書くつもりです。他の詳細な手法やコツや実装コードに関しては・・・機会があれば文章にするつもりです。

## 参考文献
- DCGAN解説記事
  - [Chainerで顔イラストの自動生成](http://qiita.com/mattya/items/e5bfe5e04b9d2f0bbd47)
  - [Chainerを使ってコンピュータにイラストを描かせる](http://qiita.com/rezoolab/items/5cc96b6d31153e0c86bc)
- 関連情報から画像生成
 - 論文 [Generative Adversarial Text to Image Synthesis](http://www-personal.umich.edu/~reedscot/files/icml2016.pdf)
 - 著者らの実装 https://github.com/reedscot/icml2016
 - 解説スライド: http://niconare.nicovideo.jp/watch/kn1626
- #kanojo_create
 - [機械学習で美少女化 ~ あるいはNEW GAME! の世界 ~](http://qiita.com/Hi-king/items/8d36d9029ad1203aac55)