ちょっと前に「猫の線画を書くと自動着色できる」というWeb上のデモが話題になりました。
- Image-to-Image Demo – Affine Layer (web)
- [1611.07004] Image-to-Image Translation with Conditional Adversarial Networks (元論文)
- phillipi/pix2pix: Image-to-image translation with conditional adversarial nets (著者によるTorch実装)
- affinelayer/pix2pix-tensorflow: Tensorflow port of Image-to-Image Translation with Conditional Adversarial Nets
- 他複数のフレームワークによる実装あり
- ニュース記事
著者は、このデモに関するデータセットをいくつか公開してくれていますが、この妙に話題になった「猫画像の変換」に必要なデータセットのみ配布をしていません。
なんとか自分でも再現したいと思い、いろいろとトライしてようやく結果を出せそうなところまできました。
データ収集
まず猫画像の収集をやりました。最初はWikipediaからの取得を考えていたのですが、現在Wikipediaが用意しているダンプに画像ファイルは含まれておらず、そもそも画像に関してはWikipedia標準のライセンスであるとは限らないと公式に書かれていました。
しかたなく、Google画像検索でライセンスを「商用を含めた二次利用許可」に絞って探していたら、やたらPixabayというサイトの画像が出てくるのでよくよく調べてみると、なんとこのサイトはすべてCC0(public domain)ということなので、ここから画像を集めました。画像URLのリストをgithubで公開しています。
データ分類
Pixabayの検索結果には実際には猫ではない画像も割と混じっているので、ChainerCVの事前学習モデルを使ってある程度自動分類してから、手動でpix2pixに使えそうな画像を選別しました。
猫部分の抽出
集めた画像には背景が含まれています。これを除去する作業を最初はgimpやAndroidアプリを使って手動でやっていたのですが、なかなか大変なので自動で行うアプローチを模索し、セマンティックセグメンテーションを用いておおよそ望みの結果が得られました。
線画変換
まだこの結果を手で調整するということまではやっていないのですが、これだけでもそこそこ行けそうなので、画像を線画に変換する処理をやりました。
ここまでの内容を一通りQiitaに書いてきましたが、一番技術的には大したことのない(他もそんなに大したことないですが…)猫画像の前景抽出が一番多くいいねがついています。わかりやすい結果の出る内容だと耳目を集めやすいんだなあという感想を持ちました。
今後
あとは実際にpix2pixにデータを与えて訓練するだけです。近いうちに処理用のGPUを買う予定です。さすがにこの量のデータをCPUでやろうとすると月単位の時間がかかると予測されるので、遺憾ながらNVIDIAのproprietary driver/libraryのお世話になろうと思っています。GPUなら1日あればいける程度にまで処理時間が短縮されますからね。
満足ゆく結果が出れば、公開しようと思っています。
Image to Image(pix2pix)について
一応論文は読みました。あるドメインの画像を別のドメインに変換する、ということを一般化して行うことを目的とした手法となっています。セマンティックセグメンテーション、白黒画像のカラー化、ゴッホ風などのスタイル変換といったいろんな処理は、従来それぞれタスクごとにネットワーク構造と目的関数を設計して学習を行う、ということがやられてきましたが、それを一つの同じ手法で行うなかなかすごい手法です。
論文を読むと損失関数を勝手に学習する、という感じのことがabstructに書いてあるのですが、実際のところはEncoder-Decoderモデルで目的の入出力ペアがうまく出てくるよう、中間層をうまいこと学習してくれるという感じに読めました。
Encoder-Decoderには同じ階層の中間層動詞を繋げるU-Netという構造を使っています。これによって高周波成分、画像の細部をうまく学習できるそうです。
また条件付きGANの一種であり、Discriminatorを用いた敵対的な学習も行っています。このおかげで、割と少ないデータ量でもそれなりの性能を出すことができるようです。
DiscriminatorにはPatchGANで使われているテクニックを用いています。単純な1枚画像に対する真贋判定を行うのではなく、小さいブロック(TensorFlow実装では30×30)に区切った領域それぞれに対して判断を行うようにしています。これも高周波成分の学習に寄与しているようです。
画像のドメイン間変換には他にも1対1でない画像群から相互変換を学習するCycleGANという手法もあります。1対1でないという点はある種の教師なし学習に近いものがあるのですが、実現には適切なデータセットの用意とハイパーパラメータの調整が必要なようで、結構大変そうです。
Pixabayへの投稿
Pixabayに大変お世話になったので、自分も少しは写真を投稿しようと思っています。スマホアプリを入れたら投稿が簡単だろうかと思っていたのですが、どうやらアプリは検索・閲覧専用のようでした。まあブラウザからポチポチと投稿しますかね…