画像の高速スタイル変換を行う論文の紹介

  • 53
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

画像の高速スタイル変換

画像のスタイルを変換するアルゴリズムとしてGatysらの"A Neural Algorithm of Artistic Style"が知られていますが、これを高速に行う手法が現れました。
以下のつぶやきを見て驚愕したので早速調べました。

2016/4/12追記 Yusuke Tomoto氏による実装が公開されました。Chainerを使っています。
https://github.com/yusuketomoto/chainer-fast-neuralstyle

実装の元になった論文は以下にあります。
Justin Johnson, Alexandre Alahi, Li Fei-Fei, "Perceptual Losses for Real-Time Style Transfer and Super-Resolution"

本記事ではConvolutional Neural Network(CNN)の知識を前提とします。CNNについてよく知らないという方は以下の記事を読んでおくと良いと思います。
Convolutional Neural Networkとは何なのか
Convolutional Neural Networkを実装する

画像のスタイル変換とは?

コンテンツ画像とスタイル画像の2つの画像を用意し、以下の特徴を持つ画像を出力します。
Preferred Researchブログに例が載っています。

  • 描かれている物体はコンテンツ画像と同じ
  • スタイルがスタイル画像に似ている

従来手法

Gatysらの手法については先ほど紹介したPreferred Researchブログに詳しく書かれています。
この手法では、入力画像(ランダムな値を初期値とすることが多い)を少しずつ修正してスタイル変換後の画像を生成します。

提案手法

これに対して提案手法では入力画像のスタイルを変換するニューラルネットワーク(NN)を学習します。

style_transfer.png

$f_{W}$ がスタイル変換を行うNNで、$x$ にコンテンツ画像を入力するとスタイル変換後の画像 $\hat{y}$ が得られます。
この手法では $x$ を $f_{W} $に入力するだけでスタイル変換を行えるので高速に変換を行うことができます。
ただし $f_{W}$ を学習するのに時間がかかり、また $f_{W}$ はスタイル毎に学習する必要があります。

スタイル変換NNの構成

論文では、スタイル変換を行う $f_{W}$ の構成は以下のようになっています。

  • Downsamplingレイヤ
    ストライド2のCNN(論文では2層)を通してDownsamplingを行います
  • 複数のResidual block
    Downsampling後のデータをResidual networkに通して変換を行います
    Residual networkは複数のCNN, ReLU, Batch normalizationと恒等変換を組み合わせることでレイヤが多数になっても学習を行いやすくしたものです。 詳しくは[Survey]Deep Residual Learning for Image RecognitionTraining and investigating Residual Netsを参照してください
  • Upsamplingをするレイヤ
    ストライド1/2のCNN(論文では2層)を通してUpsamplingを行います

Residual block以外のレイヤでは、CNNの後にBatch normalizationととReLUを適用します。
ただし最終レイヤはReLUの代わりにtanhを使った後に定数を掛けて、出力が[0, 255]の範囲になるようにします。

スタイル変換NNの学習

学習時には、$f_{W}$ とは別に損失関数に使用するLoss Network $\phi$ を用意します。
Loss Networkには画像のカテゴリ分類で使用するNNが使われ、論文ではVGG-16を使っていました。
学習手順は以下に記述しますが、記号が多いのでまとめておきます。

$f_{W}$: スタイル変換NN
$\phi$: Loss Network
$x$: 入力画像
$y_{c}$: コンテンツ画像
$y_{s}$: スタイル画像
$\hat{y}$: $x$を$f_{W}$で変換した画像
$\phi_{i}(x)$: $\phi$ に $x$ を入力した時のレイヤ $i$ の値($\phi_{i}(y)$, $\phi_{i}(\hat{y})$)についても同様)

事前準備

  1. 事前に1つのスタイル画像と複数のコンテンツ画像を用意する
    論文ではMS COCOに含まれる8万枚の画像を使用していました。
  2. スタイル画像を$\phi$に入力し、$\phi_{i}(y_{s})$を得る

学習

以下を繰り返し行います

  1. コンテンツ画像を $f_{W}$ に入力し出力 $\hat{y}$ を得る
  2. $\hat{y}$をLoss Network $\phi$ に入力し、$\phi$ の各レイヤの値 $\phi_{j}(\hat{y})$ を得る
  3. コンテンツ画像を$\phi$に入力し、$\phi_{i}(y_{c})$ を得る
  4. $\phi_{j}(\hat{y}), \phi_{i}(y_{c})$ と $\phi_{i}(y_{s})$ からFeature Loss $l_{feat}^{\phi}$ とStyleをLoss $l_{style}^{\phi}$ を求める
  5. $l_{feat}^{\phi}$ と $l_{style}^{\phi}$ の重みつき和を減らすように $f_{W}$ を更新する

レイヤ j のFeature Loss:

Feature Lossは $\phi_{j}(\hat{y})$ と $\phi_{j}(y_{c})$ のユークリッド距離の2乗です。
学習時には $\phi_{j}(y_{c})$ は $f_{W}$ の入力 $x$ に一致します。

l_{feat}^{\phi,j}(\hat{y}, y_{c}) = \frac{1}{C_{j}H_{j}W_{j}}||\phi_{j}(\hat{y}) - \phi_{j}(y_{c})||_2^2

$C_{j}, H_{j}, W_{j}$ はそれぞれレイヤ $j$ のチャンネル数、高さ、幅です。

レイヤ j の Style Loss:

まずレイヤ $j$ のグラム行列を定義します。
グラム行列の要素は、レイヤ $j$ のチャンネル $c$ の要素をベクトル化(1列に並べた)したものと別のチャンネル $c^\prime$ の要素をベクトル化したものとの内積を定数で割った値です。
論文ではFeature Lossの計算対象になっているレイヤは1つです。

G_j^{\phi}(x)_{c,c^\prime}=\frac{1}{C_{j}H_{j}W_{j}}\sum_{h=1}^{H_j}\sum_{w=1}^{W_j}\phi_j(x)_{h,w,c}\phi_j(x)_{h,w,c^\prime}

次にStyle Lossを求めます。
Style Lossはグラム行列のフロベニウスノルムの2乗です。

l_{style}^{\phi,j}(\hat{y},y_{s})=||G_{j}^{\phi}(\hat{y})-G_{j}^{\phi}(y_{s})||_{F}^2

論文ではStyle Lossを計算するために4つのレイヤを使っています。
Preferred Researchブログだとグラム行列をチャンネル間の相関として説明しているのですが、私は相関を近づけることによって画像のスタイルが近づく理由を理解できていません。

実際に学習する時には画像を滑らかにするために上記のLossの他に $\hat{y}$ の分散を減少させるような正則化項も使用しています。詳しくは論文を参照してください。
Loss Networkの選び方によってはスタイル変換とは別の画像変換も行うことができます。
論文では別の変換として画像の高解像度化も行っていました。

まとめ

提案手法では、スタイル変換NNである $f_W$ を学習することで実行時に高速にスタイル変換を行うことができます。
この手法はスタイル変換に限定されず、学習データによっては別の変換も学習することができると考えられます。
今回紹介していませんが、論文では画像の高解像度化も行っていました。
実行時のパフォーマンスが重要になる局面で活用できそうな手法だと思います。

参考文献