9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

KawaiiGen: かわいい女の子の顔画像を生成するPythonモジュールの裏側

kawaii-genとは

かわいいアイドルの顔画像を生成するpythonモジュールkawaii-genを最近公開しました。本記事では、このモジュールに使われているstyleganのモデル、stylegan用データセット作成のために実装したデータパイプラインの説明をします。

styleganは1024x1024pixelの解像度かつ写真のような画像が生成でき、隠れ変数の空間が高い線形分離性と補完性を持つようなGANです。今回はStyleGANを使い256x256と超解像の512x512で試しました。

データパイプラインに関してですが、styleganはFFHQのデータセットが7万枚の画像であることからも多くの枚数の画像が必要なため、手動アノテーション枚数を減らすためにアクティブラーニングの考えを使い2000枚ちょっとのアノテーションで女性の顔だけ自動で取り出せるようにしました。

StyleGANの説明

StyleGANの概要

StyleGANは次のような特徴を持つGANです。

  • 隠れ空間の補完性能が従来手法より改善
  • 隠れ空間の軸と軸を従来手法よりdisentangleできる。= より良い線形分離空間を作れる。

補完性能とは、隠れ変数空間内で、似たようなものが近くに配置されるような空間になっているような性質で、顔画像ならば、笑顔の度合いの順で並んでいたり、メガネを掛けている顔画像は空間上で近かったりするようなものです。

よりよいdisentangleとは、軸が独立に近い空間が作れることで、
そのような空間と線形分離に近い空間の関係ですが、感覚的には、独立した特徴量を使った方が分類ロジックなどが作りやすいので、独立した軸を持つ空間(=特徴量が独立)のほうがより良い線形分離ができそうです。

StyleGANでは、Zは線形分離しやすい空間ではありませんが、(Fig.2)、アーキテクチャ(Fig.1)のZをWに変換するネットワークがZを線形分離しやすい空間に変換してくれます。

Fig.1
スクリーンショット 2019-12-07 19.29.49.png

Fig.2
スクリーンショット 2019-12-07 19.24.23.png

実装

styleganの公式リポジトリのコードをほぼそのまま利用しました。様々なデータセットをTFRecords形式に変換してくれるスクリプトやオプションを用意に変更できる学習スクリプトなどがあります。すべてのオプションをPythonのDictionaryuで書くんですが、
argparseなどで引数をつけるようにするより、思ったよりも変更しやすかったです。
詳細は公式README参照ですが、dataset_tool.py create_from_imagesコマンドでデータセットを学習スクリプトtrain.pyが受け付けるtfrecord形式のデータセットを作成し、train.pyの引数をいじって実行するのみです。

データパイプライン

全体像

Data Pipeline (StyleGAN) (1).png

データの流れと処理コンポーネントは上の図の通りで、
処理のはじめに汎用、特定サイト用のクローラーが顔画像を収集します。
その後、その画像から顔を検知し、男性の顔を除去、各種オクルージョンを除去した上で、
目や花の位置を揃えるアライメントの処理を行い、アライメント除去をします。
アライメント後の画像が学習データセットに保存されます。

顔検知のアルゴリズム

今回はdlibのcnnアルゴリズムを使いました。この顔検知アルゴリズムはスライディングウィンドウでウィンドウ内が顔であることの判別にcnnを使います。判別にhog特徴量とsvmで行うアルゴリズムもdlibには用意されていて、顔画像生成を始め試すときには正面画像のみとれるhogが最も適しているかもしれません。

他にはSSDやretinanetなどのモデルを使う方法があり、EndToEndにしてGPUでバッチ実行することで高速化できるかもしれません。dlibのcnnも実装最適化されていて、相当早いですけど。

アラインメント

StyleGANの学習負荷を減らすために学習データを正規化します。
目な鼻の位置や方向を揃えることでバリエーションを減らします。 

StyleGANのアライメントをほぼそのまま使いました。
顔画像の目や鼻のランドマークの位置を元に矩形を作り直すのと方向の修正をします。
回転や移動したときにできた空白は白でPaddingされますが、このpaddingの領域が大きすぎるものは除去します。
髪や顔の一部が除去されすぎる可能性があるからです。

ランドマーク検知には、オクルージョン対応できるランドマーク検知モジュールを使いました。

男性の顔の除去

元々、アイドルの顔分類器を作ろうと思ってて、顔画像を2000枚くらいアノテーションしてました。dlibで顔特徴量を抽出して、顔特徴量空間でクラスタリングして似ているものを一気にラベルづけ、その後、confidenceスコアの低いものをラベルづけしていきました。

オクルージョン、正面画像以外の排除

マイク、手、文字、食べ物などが顔にかかっている写真が幾つかあったのでそれらを検知する機能を作りました。また、正面を向いている顔以外をフィルタする機能も作りました。数十万枚の画像を処理するとかなり時間がかかるので、GPU数を増やす目処が立っていないためこの機能はオフにしています。ただ、顔に謎の物体がうっすらと見える画像が何枚かあり、それを省くためにオクルージョン対応は必須だと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?