Python
DeepLearning
Chainer
MachineLearnng

Convolutional Neural Networkを使ったもう1つのスタイル変換手法

More than 1 year has passed since last update.


Convolutional Neural Networkを使ったスタイル変換手法

Convolutional Neural Network(CNN)を使ったスタイル変換手法として、"A Neural Algorithm of Artistic Style"(以下Neural style)が有名で以下のような実装があります。

スタイル変換の別手法として"Combining Markov Random Fields and Convolutional Neural Networks for Image Synthesis"(以下「MRFを使ったスタイル変換」)があり、今回はこちらの紹介を行います。

この手法をChainerで実装してみました。

ソースコードは https://github.com/dsanno/chainer-neural-style にあります。


スタイル変換とは


  • コンテンツ画像とスタイル画像の2つの画像を用意する

  • 画像の内容はコンテンツ画像、画像のスタイルがスタイル画像に近いような画像を生成する


スタイル変換例


論文筆者によるサンプル

https://github.com/chuanli11/CNNMRF


Chainer実装によるサンプル

生成画像
コンテンツ画像
スタイル画像

油彩画


水彩画


いわさきちひろの「はなぐるま

ペン画


画像提供元:


概要

MRFを使ったスタイル変換では以下のような画像を生成します。


  • 内容がコンテンツ画像に近い

  • 局所的なスタイルが、スタイル画像の局所的にスタイルに近い

Neural-styleが画像全体のスタイルをスタイル画像に近づけるのに対し、MRFでは局所的なスタイルをスタイル画像に近づけるという違いがあります。


既存の実装


アルゴリズム

タイトルに"Markov Random Field (MRF, マルコフ確率場)"が入っていますが、MRFはアルゴリズムの肝ではないので説明は割愛させていただきます。


入力と出力

コンテンツ画像とスタイル画像を入力とします。

コンテンツ画像を$x_c$、スタイル画像を$x_s$で表します。

出力する生成画像を$x$で表します。


CNN

この手法ではNeural styleと同様にVGG等の画像認識用CNNを使用します。


レイヤー出力

画像$x$をCNNに入力したときの特定のレイヤーの出力を$\Phi(x)$で表します。

コンテンツ画像を入力したときのレイヤー出力は$\Phi(x_c)$、スタイル画像を入力したときのレイヤー出力は$\Phi(x_s)$となります。


パッチ

CNNのレイヤー出力からパッチを生成します。

パッチとはレイヤー出力の$k\times k$の領域を1つにまとめたもので、長さ$k \times k \times C$($C$はレイヤー出力のチャンネル数)のベクトルです。

1つのレイヤーから複数のパッチを生成でき、$i$番目のパッチを$\Psi_i(\Phi(x))$で表します。


エネルギーの定義

このアルゴリズムでは、エネルギーを$x$の関数として定義します。

そしてエネルギーを最小とするような$x$を計算します。

エネルギー関数の定義は以下の通りです。

各項の説明については以降で説明します。

E(x) = E_s(\Phi(x), \Phi(x_s)) + \alpha_1 E_c(\Phi(x), \Phi(x_c)) + \alpha_2 \Upsilon(x) 


MRFs loss function

1項目の$E_s$はMRFs loss functionと呼ばれるもので定義は以下の通りです。

E_s(\Phi(x), \Phi(x_s)) = \sum^{m}_{i=1}||\Psi_i(\Phi(x)) - \Psi_{NN(i)}(\Phi(x_s))||^2

ただし$NN(i)$は以下の式で定義します。

NN(i) := \mathop{\rm arg\,max}\limits_{j=1,...,m_s} \frac{\Psi_i(\Phi(x)) \cdot \Psi_j(\Phi(x_s))}{|\Psi_i(\Phi(x))| \cdot |\Psi_j(\Phi(x_s))|}

論文ではargminとなっているのですが、実装を見たところargmaxが正しいようです。

この式は以下のような意味をもちます。


  • $x$から生成されたパッチの各々について、近いものを$x_s$から生成されたパッチ集合の中から選択する

    近さの基準として、パッチ間の相関を用いる

  • 選択したパッチと$x$から生成されたパッチとが近いほどエネルギーが小さくなる


Content loss function

2項目の$E_c$はContent loss functionと呼ばれるもので定義は以下の通りです。

E_c(\Phi(x), \Phi(x_c)) = ||\Phi(x) - \Phi(x_c)||^2

これは$x$から生成されたCNNレイヤーと$x_c$から生成されたCNNレイヤーが近いほどエネルギーが小さくなることを意味しています。


Regularizer

3項目の$\Upsilon$は画像を滑らかにするための正則化項です。

定義は以下の通りで、$x_{i,j}$はx座標が$i$、y座標が$j$のピクセルの値です。

隣り合うピクセルの差が小さいほどエネルギーが小さくなります。


\Upsilon(x) = \sum_{i,j}((x_{i,j+1} - x_{i,j})^2 + (x_{i+1,j} - x_{i,j})^2)


実装

Chainerで実装してみました。

CNNにはChainer-goghでもおなじみのVGG 16 layersモデルを使っています。

ソースコードは https://github.com/dsanno/chainer-neural-style にあります。


手法の比較


実行時間

実行時間はNeural-styleよりも短くて済みます。Neural-styleが数千イテレーション必要なのに対し、MRFを使ったスタイル変換は数百イテレーションで済みます。


スタイルの違い

Neural-styleだと色使いもがらりと変わりますが、MRFを使ったスタイル変換は色使いは大きくかわらず、絵のタッチが変わるという印象があります。


応用

MRFを使ったスタイル変換の応用としてneural-doodleがあります。

neural-doodleは画像のどの領域にどのスタイルを指定するかを指定することができます。

リンク先の画像を見ていただければわかりますが、顔写真をゴッホの肖像画風に変換していますが、領域ごとのスタイル指定を行うことでより自然な変換を実現しています。

neural-doodleでは、CNNレイヤーから出力したパッチベクトルにスタイル番号を表すベクトル(パッチがどのスタイルに該当するかというone-hot vector)を連結することでスタイル指定を実現しています。


参考文献