Chainer使ってお手軽CNN画風変換したよ [chainer-gogh]
どうも、今回は画像処理です。最近、人工知能を使ってどんな写真も名画風に書き換えられる!!なんてのが流行りましたが、今回はまんまそれです。普段は画像処理なんてやらないのですが、なぜやったかというと、この手法で生成した画像をWebデザインに使えないかなと思ったからです。生成サンプルとして挙げられている画像を見ると、名画風変換以外にも新聞の紙面みたいに変換したり、何かしらの設計図風に変換しているものがあったので、発想によってはより面白い画風変換ができると思います。
というわけで、今回はお手軽にchainer-goghというChainerで実装された画風変換アルゴリズムを使って画風変換しました。ちなみに、今回の記事で上2つの画像から下の画像を生成するということができちゃいます(生成された画像はトリミングしたものです)。
ちなみに、今回はChainer環境はすでに整っているということを前提に作業していきますので、まだ環境が整っていない方は、始めに構築しておいてください。本サイトでも作業備忘録を残しているので、よかったら参考にしてみてください。
OS : Ubuntu 16.04 LTS
GPU : GeForce GTX 750 Ti
1. chainer-goghのダウンロード
では始めていきます。まずは、本記事メインである「chainer-gogh」をGithubからダウンロードしてきます。ダウンロードはGitHubのページからZIPを落としてもいいですし、以下のコマンドでもできます。
1 |
$ git clone https://github.com/mattya/chainer-gogh.git |
ダウンロードが完了したら、次に学習に使用するモデルを準備します。GitHub上でも紹介されていますが、chainer-goghのデフォルトで対応しているモデルは、”nin“,”vgg“,”googlenet“,”i2v”の4つみたいです。これらの内どれかを選んでダウンロードしてくれば大丈夫です。実際に試したところお手軽に試したいのであればnin、多少時間がかかっても綺麗な画像を生成したい場合はvggという選択肢になると思います。ダウンロードは、各モデルの配布ページに行って「caffemodel_url」とか書いてある箇所を見つけてダウンロードすれば大丈夫です。余談ですが、自分はcaffeは全く関係ないライブラリと思っていたので別の場所をずっと探してしまいました。ちなみに上記の画像はvggを用いて生成したものです
2. ひと工夫が効くらしい
さて、準備は整ったので早速実行といきたいところですが、VGGモデルを使用する場合は正直めちゃくちゃ重いです。実装主さんもVGGモデルは重いとおっしゃっているのでそのとおりなのでしょう。というわけで、ひと工夫している方がいらっしゃいました。なんでもcaffeモデルを読み込んでいるのが遅い原因なので、Chainerモデルに変換しておけば比較的マシになるようです。というわけでやっていきましょう。まずは、以下のコマンドで、pkl形式にモデルを書き換えます。
1 2 3 4 5 |
$ python > from chainer.links.caffe import CaffeFunction > import cPickle as pickle > vgg = CaffeFunction('VGG_ILSVRC_16_layers.caffemodel') > pickle.dump(vgg, open('VGG_ILSVRC_16_layers.pkl', 'wb')) |
これで、モデルを書き換えられたので、次に実行プログラムで読み込む先をcaffeモデルからpklに書き換えます。というわけで、”chainer-gogh.py”を書き換えていきます。
1 2 3 4 5 6 7 8 9 10 11 |
# コード先頭あたりに追加 # pklを読み込むために必要 import pickle # 26行目を以下のものに書き換え # def __init__(self, fn="VGG_ILSVRC_16_layers.caffemodel", alpha=[0,0,1,1], beta=[1,1,1,1]): def __init__(self, fn="VGG_ILSVRC_16_layers.pkl", alpha=[0,0,1,1], beta=[1,1,1,1]): # 28行目を以下のものに書き換え # self.model = caffe.CaffeFunction(fn) self.model = pickle.load(open(fn, 'rb')) |
これで、ひと工夫はおしまいです。ついでですが、111行目のrange関数の引数を”max_iter+1″に書き換えておくのをおすすめします。というのも、そのままではループがなんか気持ち悪い箇所で終わっちゃうからです。まぁ、生成される画像にはそれほど関係ないのでどちらでも良いのですが…。
3. 実際に動かしてみる
これで準備は完了です。実際に動かしてみましょう。先ほどダウンロードしたディレクトリ内の”sample_images”内に色々画像があるので、お試しするならこの画像を使えばいいと思います。というわけで、以下のコマンドで実行してみてください。 ちなみに、CPUで動かしたい場合は-gのオプションはいらないです。
1 2 |
$ # python chainer-gogh.py -m [使いたいモデル名] -i [入力画像] -s [スタイル画像] -o [出力ディレクトリ] -w [幅] -g [GPUID] $ python chainer-gogh.py -m vgg -i cat.png -s style_6.png -o output_dir -w 256 -g 0 |
4. 結果
というわけで結果です。入力画像は以下の2つです。左の画像を入力画像、右の画像をスタイル画像として実行しました。
上記のコマンドのように、VGGモデルを使用し、出力画像の幅を256とすると、20分くらいの処理時間を経て、以下のような画像が出力されました。
出来栄えは…まぁまぁかなー。実装者さん曰く画像は正方形のほうが良いようです。また、lamというパラメータをいじることによって入力画像、スタイル画像のどちらをより強く反映させるかを設定することができるようです。
おわりに
というわけで、今回は画風変換なるものをやって来ました。正直自分の低下力環境では実行できかも怪しいなと思っていたのですが、意外と大丈夫でした(そもそもCPUでもそこそこの速度で出来るみたいです)。しかし、入力する画像によってはなかなかうまく生成されず難しいです。実際に、使いたかったWebページに合うような画像生成はできませんでした。しかし、本記事冒頭の画像は現在Twitterのアイコンとして使っているので、まったく収穫がなかったわけでは無いので良しとします。
「画風を変換するアルゴリズム」
「Chainerのchainer-goghで画風を変換してみた」