http://qiita.com/taizan/items/7119e16064cc11500f32 で、PaintsChainerのソースが公開されていますが、PaintsChainerを学習済みモデルを使ってうごかしてみた、という記事やブログは多いのですが、自分で学習するのを試した人が見つからなかったので、やってみました。
追記 20170404:電気代の計算を一桁、過大に計算していました。。そんなに高くなかった。。
学習データの用意
元画像の用意
まず、なんと言っても学習データを用意しなければなりません。大量の画像を用意するのは大変ですし、元記事と同じPixivでやっても仕方ないので、ここでは、某アニメの動画を使ってみました。私の持っていたMP4の動画を、全フレーム画像化しています。
とりあえず、初期作品の1話〜6話を画像化しました。特にオープニング・エンディング・シーンにこだわらず、全て画像化しています。全部で172,729枚の画像になりました。
画像化には、ffmpegを使います。
生成した画像は、PaintChainer をチェックアウトしたディレクトリの、cgi-bin/paint_x2_unet/images/original に置きました。
$ cd cgi-bin/paint_x2_unet
$ mkdir -p images/original
$ ffmpeg -i movies/movie_01.mp4 -f image2 images/original/movie_01_%d.jpg
これを6話分やります。全話、ファイル名が被らないようにして、images/original/ に入れて下さい。
リサイズ・線画化
PaintChainerでは、128x128 の画像と、512x512の画像が必要です。
適等に、リサイズするスクリプトを書きました。
128x128
https://github.com/ikeyasu/PaintsChainer/blob/ikeyasu_mod/cgi-bin/paint_x2_unet/tools/resize.py
512x512
https://github.com/ikeyasu/PaintsChainer/blob/ikeyasu_mod/cgi-bin/paint_x2_unet/tools/resizex2.py
また、線画化は、k3nt0さんのブログを参考にさせてもらいました。
上記を先ほど取り出した画像に対して実行するのですが、とても時間がかかります。そこで、Gnu parallelを使って並列化します。
以下のようなスクリプトを書きました。
cgi-bin/paint_x2_unet/run.sh:
ls -v1 ../images/original/ | parallel -j 8 'echo {}; python resize.py -i {} -o ../images/color/{}'
ls -v1 ../images/original/ | parallel -j 8 'echo {}; python image2line.py -i {} -o ../images/line/{}'
ls -v1 ../images/original/ | parallel -j 8 'echo {}; python resizex2.py -i {} -o ../images/colorx2/{}'
ls -v1 ../images/original/ | parallel -j 8 'echo {}; python image2line.py -i {} -o ../images/linex2/{}'
$ cd cgi-bin/paint_x2_unet
$ cd tools
$ ./run.sh
また、データセットの一覧を dat/images_color_train.dat に格納します。
$ pwd
~/PaintsChainer/cgi-bin/paint_x2_unet/tools
$ cd ../images/original
$ ls -v1 > ../../dat/images_color_train.dat
学習
あとは学習するだけです。元のコードを多少いじくりました。(学習を始めたときにPaintChainerのコードがベースなので、ちょっと古いです)
$ pwd
~/PaintsChainer/cgi-bin/paint_x2_unet/images/original
$ cd ../../
$ python train_128.py -g 0 --dataset images/ -e 20 -o result1
$ cp result1/model_final models/model_cnn_128
$ python train_x2.py -g 0 -o result2/ --dataset images/ --snapshot_interval 5000 -e 20
実行してみる
読み込むモデルは cgi-bin/paint_x2_unet/cgi_exe.py に書かれています。
serializers.load_npz(
"./cgi-bin/paint_x2_unet/models/unet_128_standard", self.cnn_128)
と
serializers.load_npz(
"./cgi-bin/paint_x2_unet/models/unet_512_standard", self.cnn)
の部分です。これにあわせで、モデルをコピーします
$ pwd
~/PaintsChainer/cgi-bin/paint_x2_unet
$ cp result1/model_final models/unet_128_standard
$ cp result2/model_final models/unet_512_standard
そして、server.pyを実行します
$ pwd
~/PaintsChainer/cgi-bin/paint_x2_unet
$ cd ../../
$ python server.py
http://localhost:8000 をブラウザで開くと、PaintChainerを見ることができます。別のPCから見たい場合は、 python server.py --host 192.168.1.3
などと、実行しているホストのIPを指定して下さい。
気になる結果は?
人工知能の創作物に著作権が無いとはいえ、これは色塗りなのため、線画部分には著作権があるので、ここに結果をバーンと載せるわけにはいかないですね。。
画面の一部の引用程度にとどめておきます。
髪の毛、目の色は綺麗に塗れています
課題
うまくいっている結果を載せましたが、ファンイラストの手書きの線画を載せても全然うまくいきません。これは、線画化の手法が良くなかったのかもしれません。やはり、人工知能は良い教材を与えないといけないという事で。。
http://d.hatena.ne.jp/zuruo/20080528/1212143328
(頭部のリボン部分)
また、PaintChainerの特徴である、色のヒントを与えてもあまり、うまく塗ってくれません。これは何ででしょう。やはり、学習データが良くないのでしょうか。
注意!!めっちゃ時間掛かるよ!
さくっと試せたように書いていますが、ここまで実行するのに、294時間(12日と6時間!)かかっています。
元記事 が一晩と書いているのは、1段目だけの話かな。。
- 1段目 2/5 20:48 -> 2/7 23:48 = 51時間 (2日3時間)
- 24 epoch, 253250 iteration(当初、40 epoch の予定を途中で中断)
- 2段目 2/8 1:29 -> 2/18 4:34 = 243時間 (10日3時間!)
- 20 epoch, 863640 iteration
PCの電気代を200Wと仮定して電気代は、
200*(51+243)*0.026=1,528.8円
ここで0.026を書けているのは、東電の電気代が1kw/hが26円のためです。
あと、PCも GTX1080 を載せた自作PCで、17万円ほどかかってます。