目次
- 経緯
- 画風を変えるアルゴリズム
- はまりどころ
(TensorFlow成分はほとんど無し)
自己紹介・近況
- 名前: 中西克典
- 所属: 有限会社 来栖川電算(バイト)
- twitter: @n_kats_
- 発表は今回で2回目。(前回はfastTextの話)
- 昔は数学をしていた
経緯・目的
- AIっぽいことをしたい
- 何ができるとAIっぽいか。創造的なことができるとそれっぽい
- 絵を描かせてみよう
技術
関連する技術が活発に研究されている。
有名なもので、
- DCGAN
- pix2pix
など(ただし、細かい工夫があって難しそう)
したこと
画風を変換するアルゴリズムをTensorFlowで書いた。
日本だと、mattyaさんのchainer-goghが有名だと思う。
これを参考にTensorFlowで書いてみた。https://github.com/n-kats/tf-gogh
参考リンク
画風を変換するとは
元画像と画風画像を用意し、元画像の色合いなどを画風画像の色合いにする。
使い方
git clone https://github.com/n-kats/tf-gogh.git
cd tf-gogh
pyenv install 3.6.0
pyenv virtualenv 3.6.0 benkyoukai
pyenv local benkyoukai
pip install -U -r requirements.txt
wget https://www.dropbox.com/s/0cidxafrb2wuwxw/nin_imagenet.caffemodel
python main.py \
-m nin \
-i 元画像パス \
-s 画風画像パス
仕組み(一部単純化しています)
CNNを用いた、画像のある特徴量$F(X)$を用意する。($X$は画像)
画像$X$が元画像$X_\text{orig}$からどれだけ異なるかを特徴量の差のユークリッド距離で表す。(【追記】コンテンツ誤差)
L_\text{orig}(X) = \left|\left| F(X) - F(X_\text{orig})\right|\right| ^2.
画風の方は・・・
そもそも画風って何よ?
画風をどう扱うか
CNNの特徴量は、TensorFlowの言葉で大雑把に言えば、shapeが[高さ, 横幅, チャンネル数]のテンソルで表される値。
これを次元がチャンネル数と等しいベクトルが高さ×横幅だけあると考える。
これらのベクトルの分布を画風だと考える。
実際には、平均や共分散行列のようなもので数値化し、画風がどれだけ画風画像から異なるかを表す関数$L_\text{style}(X)$を作る。
学習
何を学習するのか
機械学習がすることは、アルゴリズムで良いパラメータを見つけること。
絵を描くということは、各ピクセルの色の値を決めること。
絵を表すshapeが[高さ, 横幅, 3]の変数を学習で良いものにしていく。
(特徴量などは学習しない)
損失関数
作成する画像が元画像に似ていながら、画風画像と近い画風であってほしい。
L(X) = \alpha L_\text{orig}(X) + \beta L_\text{style}(X).
というように単純に係数をつけて足す。
学習法
tf.train.AdamOptimizerというものを使う。
その他
画像の特徴量
特徴量は画像識別のCNNで現れる途中の層を使う。
有名なモデルは学習済みのパラメータが公開されているので、それを使う。
- NIN
- VGG
(CNNならどうにかなるはず)
NINを用いると速いが、出来上がる画像は微妙。
VGGを用いると遅いが、繊細な画像ができる。
(実は、パラメータの読み込みにchainerを使った)
はまりどころ
- 学習レートなどのパラメータを自分で適当につけても簡単には行かない。(先人のパラメータをそのまま使いましょう)
- 学習済みモデルを正しく使えていなかった。(opencvはBGR、pillowはRGB。魔法の数値を引く)
- VGGで動作確認すると時間を取られる。(速いNINからすべきだった)
覚えて帰ってほしいアイデア
- 画像の各ピクセルの値を学習する
- 学習済みモデル(特徴量)から新しい損失関数を作る
- 画風を特徴量の分布で解釈する