Path: blob/master/site/ja/tutorials/generative/style_transfer.ipynb
25118 views
Copyright 2018 The TensorFlow Authors.
ニューラル画風変換
このチュートリアルでは、ディープラーニングを使用して、ある画像を別の画像の画風で作成します(ピカソやゴッホのように描いてみたいと思ったことはありませんか?)。これはニューラル画風変換として知られるテクニックで、「A Neural Algorithm of Artistic Style」(Gatys et al.)に説明されています。
注意: このチュートリアルでは、元の画風変換アルゴリズムを実演しています。画像のコンテンツを特定の画風に最適化するものです。最新のアプローチでは、画風が適用された画像を直接生成するようにモデルをトレーニングします(CycleGAN に類似)。このアプローチではより高速に実行することが可能です(最大 1000 倍)。
TensorFlow Hub から事前トレーニングされたモデルを使用した画風変換の簡単なアプリケーションについては、任意の画像様式化モデルを使用する任意のスタイルの高速画風変換のチュートリアルをご覧ください。TensorFlow Lite を使用した画風変換の例については、TensorFlow Lite を使用した芸術的な画風変換を参照してください。
ニューラル画風変換は、コンテンツ画像と画風参照画像(有名な画家の作品など)という 2 つの画像をブレンドしてコンテンツ画像に見えるが、画風参照画像の画風で「描かれた」ように見える画像を出力するための最適化テクニックです。
これは、コンテンツ画像のコンテンツ統計と画風参照画像の画風統計に一致するように出力画像を最適化することで実装されています。これらの統計は、畳み込みネットワークを使用して画像から抽出されます。
たとえば、以下の犬の画像とワシリー・カジンスキーの作品 7 を使用しましょう。

ウィキペディアコモンズの Yellow Labrador Looking。作成者、Elf。ライセンス CC BY-SA 3.0

ガジンスキーがこの画風のみを使用してこの犬の絵を描こうとしたら、どのようになるのか見てみましょう。以下のようになるでしょうか?
セットアップ
モジュールのインポートと構成
画像をダウンロードして、画風画像とコンテンツ画像を選択します。
入力を視覚化する
画像を読み込んで、その最大寸法を 512 ピクセルに制限する関数を定義します。
画像を表示する単純な関数を作成します。
TF-Hub を使用した高速画風変換
このチュートリアルでは、画像コンテンツを特定の画風に最適化する、元の画風変換アルゴリズムを実演します。詳細に踏み込む前に、TensorFlow Hub が何を行うのかを確認しましょう。
コンテンツと画風の表現を定義する
モデルの中間レイヤーを使用して、画像のコンテンツと画風の表現を取得します。ネットワークの入力レイヤーから数えて最初のいくつかのレイヤーアクティベーションは、エッジやテクスチャといった低レベルの特徴を表します。ネットワークをさらに深く探ると、最後のいくつかのレイヤーは、車輪や目といった高レベルの特徴を表します。この場合、VGG19 ネットワークアーキテクチャという、事前トレーニング済みの画像分類ネットワークを使用しています。中間レイヤーは、画像からコンテンツと画風の表現を定義するために必要となるレイヤーです。入力画像については、これらの中間レイヤーにある、対応する画風とコンテンツターゲットの表現に一致するようにします。
VGG19 を読み込んで、画像で実行し、正しく使用されていることを確認します。
分類ヘッドを除く VGG19
を読み込み、レイヤー名をリストします。
画像の画風とコンテンツを表現する中間レイヤーをネットワークから選択します。
画風とコンテンツ用の中間レイヤー
では、事前トレーニング済みの画像分類ネットワーク内のこれらの中間出力によって画風とコンテンツの表現を定義できるのはなぜでしょうか。
大まかに言えば、ネットワークが画像分類を行うには(このネットワークがトレーニングされた目的)、画像を理解している必要があります。これには、生の画像を入力ピクセルとして取り、生の画像ピクセルを、画像内に存在する特徴の複雑な理解への変換する内部表現が必要です。
これが、畳み込みニューラルネットワークがうまく一般化できる理由でもあります。不変性をキャプチャして、バックグラウンドノイズやその他の邪魔なものにとらわれない特徴をクラス内(猫と犬など)定義することができます。そのため、生の画像がモデルにフェードされる場所と出力分類ラベルの間のどこかで、モデルは複雑な特徴量抽出器としての役割を果たしていることになります。モデルの中間レイヤーにアクセスすることによって、入力画像のコンテンツと画風を説明することができます。
モデルを構築する
tf.keras.applications
のネットワークは、Keras の Functional API を使用して、中間レイヤーの値を簡単に抽出できるように設計されています。
Functional API を使用してモデルを定義するには、入力と出力を以下のように指定します。
model = Model(inputs, outputs)
以下の関数は、中間レイヤーの出力を返す VGG19 モデルを構築します。
モデルを作成するには、以下のように行います。
画風を計算する
画像のコンテンツは、中間特徴量マップの値によって表現されます。
これにより、画像の画風は、異なる特徴量マップの平均と相関によって表現できるようになります。各場所での特徴ベクトルの外積を取り、その外積をすべての場所で平均することにより、この情報を含むグラム行列を計算します。特定のレイヤーのグラム行列は以下のように計算できます。
これは、 tf.linalg.einsum
関数を使用して簡潔に実装できます。
画風とコンテンツを抽出する
画風とコンテンツのテンソルを返すモデルを構築します。
画像に対して呼び出されると、このモデルは style_layers
のグラム行列(画風)と content_layers
のコンテンツを返します。
勾配下降法を実行する
この画風とコンテンツの抽出器を使用して、画風変換アルゴリズムを実装できるようになりました。各ターゲットに相対する画像の出力の平均二乗誤差を計算し、これらの損失の加重和を取って行います。
画風とコンテンツターゲット値を設定します。
最適化する画像を含めて tf.Variable
を定義します。これを素早く行うには、コンテンツ画像で初期化します(tf.Variable
は、コンテンツ画像を同じ形状である必要があります)。
これはフローと画像であるため、ピクセル値を 0 から 1 に維持する関数を定義します。
オプティマイザを作成します。論文では、LBFGS が推奨されていますが、Adam
も使用できます。
これを最適化するために、重みづけされた、2 つの損失の組み合わせを使用して合計損失を取得します。
tf.GradientTape
を使用して画像を更新します。
いくつかのステップを実行してテストします。
機能しているので、さらに長い最適化を実行します。
総変動損失
この基本実装には、 高周波アーチファクトが多く生成されるという難点があります。これらは、画像の高周波コンポーネントに明示的な正則化項を使用することで低下させることができます。画風変換では、通常これは総変動損失と呼ばれています。
これは、高周波コンポーネントがどのように高まったのかを示します。
また、この高周波コンポーネントは基本的にエッジ検出器でもあります。似たような出力は、Sobel エッジ検出器でも見られます。以下に例を示します。
これに伴う正則化損失は、値の二乗の和です。
何を行うかについては実演されましたが、これを自分で実装する必要はありません。TensorFlow には、標準実装が含まれています。
最適化を再実行する
total_variation_loss
の重みを選択します。
train_step
関数にそれを含めます。
イメージ変数とオプティマイザーを再初期化します。
そして、最適化を実行します。
最後に、結果を保存します。
詳細情報
このチュートリアルでは、元の画風変換アルゴリズムを紹介しました。画風変換の簡単なアプリケーションについては、このチュートリアルを参照してください。TensorFlow Hub から任意の画風変換モデルを使用する方法についての詳細が記載されています。