第 3 章 ) を それを知るには、モデルを構成 超解像奮闘記 本章では、失敗の原因を探り、どのようにすれば期待通りに動作するのか。その方法を探り 第 2 章で作成したモデルは、期待した動作をしませんでした。 入力すると、 21px の画像を出力します。 第 2 章のモデルは、 3 層の畳み込み層で構成される CNN です。 33px の画像 (tr_image 畳み込み処理とバディング ます。 図 3.1 CNN の入出力 33X33 21X21 CNN そもそもなぜ、入力と出力の大きさが異なるのでしようか している「畳み込み層」の処理に踏み込む必要があります。 畳み込み層 with tf. variable_scope(name) as scope: strides=(), 1 , 1 , 1 ) , padding='VALID'): biases_shape, biases_value, weights—shape, weight—stdde\/' def conv2d(name, input—layer, リスト 3.1 : srcnn/model/model—base. py 畳み込み層は、 model ー base. p の関数 conv2d で定義しています ( リスト 3. I) 。 第 3 章超解像奮闘記 padding=padding) conv tf. nn. conv2d(input—Iayer, weights, strides, weights —get—weights(weights—shape, stddev=weight—stddev) 41
図 3.9 image 」 oader_svs. py の動作 33X33 cropped—image lr—image 33X33 1 1 x 1 1 0 → 0 CNN ground—truth 21X21 これまで見てきたように、超解像を実現するには周辺部の特徴を取り込む必要があります。 しかし、畳み込み層でパディングを設定してもプロックの境目にノイズが発生します。 そこで、学習時にパディングの領域を含めて読み込むように変更します。 conv2d で 0 パディングを追加するのでなく、失われるピクセル分、大きめに画像を読み込み ます ( 図 3.10 ) 。 図 3.10 変更後の動作 cropped—image 33X33 lr—image 33X33 ☆☆☆ CNN ground—truth 21X21 リスト 3.5 は、変更後のプログラムです。 リスト 3.5 : srcnn/image 」 oader_vvv. py def toad_image(file_list, input_size, output_size, scaIe=2, batch_size=l) : with tf. name_scope( 'image_loader vvv' ) : channels=l, 第 3 章超解像奮闘記 49
図 3.3 入力 ( 左 ) と出力マップ ( 右 ) 要ーー第を一第 題をを一第第を蒻 ■当第 フィルターの右端が入力の右端に到達したときに、それ以上は移動できません。そのため、 畳み込みの結果は入力サイズより小さくなります。 図 3.4 画像サイズを超えてスキャンできない 第ーー第第第を事 畳み込み層の出力サイズは「入力サイズ - ( フィルターサイズ - スライド幅 ) 」で計算できます。 今回の例で 1 層目の畳み込み層は、入力を 9X9 のサイズのフィルターを使ってスライド幅 1 で スキャン ( 畳み込み ) しています。したがって、出力サイズは「 33 ー ( 9 ー 1 ) 」となります。 前章で構築した 3 層の畳み込み層からなるモデルの場合、各層でサイズが小さくなり、出力 サイズは 2 lpx となります。 リスト 3.2 : mode1915. py INPUT SIZE 1 ) は省略 OUTPUT_SIZE 図 3.5 は、各ピクセルがスキャンされる回数を濃淡で表しています。薄い周辺部はスキャンの 回数が少なく、濃い中心部は回数が多いのがわかります。 33 工 NPUT SIZE ( 5 ー 1 ) # ( 9 ー 1 ) 第 3 章超解像奮闘記 43
if biases_shape is not None: —get—biases(biases—shape, value=biases_value) biases conv = tf. nn . bias—add(conv, biases) return conv 畳み込み層は、入力に対して「フィルターによるスキャン」と「バイアスの加算」を行います。 入力とは、 2 次元の画像 + チャンネルの 3 階テンソル [ height , width, channet]lo 厳 密に言えば、、ニバッチのサイズを併せた [batch, height, width, channet] の形をし た 4 階テンソルです。 オペレーション tf. nn . conv2d は、指定した形と枚数 (weights-shape で定義されます ) のフィルターを使って、畳み込み処理をします。 畳み込み処理とは、フィルターをスライドさせて、入力をスキャンすることを言います。 図 3.2 は、フィルターが入力をスキャンする ( 畳み込む ) 様子を図示したものです。 図 3.2 33X33 の入力を、フィルターサイズ 9X9 、スライド幅 1 でスキャンした場合 編第彦第ド 第■・第第を第 第・・第第物当置 を、第を・・をー第 ■日 0 材を ・宿第画ーをー宿 を宿い 置第第重第第宿こ 第第ををき ・をー第 スキャンは左上から開始します。フィルターが右端に到達すると下にスライドして、もう一 度左端からスキャンします。これを繰り返して、次の層への出力マップを作成します。スキャ ン一回分の結果が、出力マップの 1 マスに当たります。 42 ー第 3 章超解像奮闘記
学習の実行・・ 画像処理・ パディングの付加・・ プロックに分割・・ 超解像処理・・ プロックの再構成・ 画像の保存 ( パディングの除去 ) 実行・・ ワワ -4 ・ l.n ^ 0 「 / ー 8 ワ 1 っ 0 っ 0 っ 0 00 00 っ 0 っ 0 評価 第 3 章超解像奮闘記 畳み込み処理とパディング・ 畳み込み層・・ パディングを設定する・・ 画像の読み込み処理 活性化関数 ReLU ・・ Sigmoid 関数・・ -4 -4 盟 / 4 5 浦 第 4 章さまざまなモデル・・ モデル ( 9-5-5 ) 画質の指標 (PSNR, SSIM) ・ カラー画像対応・・・ Batch NormaIization の導入・ 0 0 00 -0 参考・ あとがき・ 謝辞 著者紹介・ ・・ 76 ・・・ 78 ・・・ 78 ・・・ 81 目次 3
ノイズとなっています。 では、なぜ 1 . @ を超える値が出力されているのでしようか 数に注目します。 ReLU こで、畳み込み層の活性化関 現在のネットワークでは、すべての畳み込み層で活性化関数に ReLU (Rectified Linear Unit) def inference(lr—images) : リスト 3.9 : srcnn/modeI/mode1915. py を使用しています ( リスト 3.9 ) 。 # 省略 conv3 conv3 conv2d( 'conv3' input—Iayer=conv2, weights—shape=[5, 5 , 32 , weight—stddev=1e-3, biases—shape=[CHANNELS] , st ri des= [ 1 , 1 , 1 , 1 ] , padding='VALID') tf. nn . retu(conv3) CHANNELS] , biases_value=@ . @, return conv3 図 3.14 は、 ReLU の値域を示すグラフです。 図 3.14 Rectified Linear Unit の原因になっています。 @ 以上の値をそのまま通すため、 1 . @ を超える値でもそのまま最終層の出力になり、ノイズ 第 3 章超解像奮闘記 55
図 3.5 薄い周辺部はスキャンされる回数が少ない 画像の中の特定のピクセルを考えたとき、そのピクセルがスキャンされる回数が多いほど、 次の層への出力の影響が大きくなります。 超解像はプロックごとに処理するため、プロックとプロックの境目である周辺部の特徴が重 要なことは言うまでもありません。 しかし、第 2 章で作成したモデルは周辺部のスキャン回数が少ないため、周辺部の特徴が正 しく学習できていない状態である可能性が高いと言えます。 ノヾディングを設定する 仮説を検証するために、畳み込み層にパディングを設定します。 tf. nn . conv2d に padding='SAME' を指定すると、畳み込みの出力が入力と同じ大きさになるように自動的 にパディングを追加します。 たとえばスライド幅を 1 として、フィルターサイズが 9X9 であれば 4px 、 5X5 であれば 2px のパディングが上下左右に追加されます。 図 3.6 パディングを追加したプロック ( 41 X41 ) 要こ 第ー ■・・■ ■・■■ ■・・■ ■・・■ ■・■・ ■・■・ ■・・■ ■ー■・ ■・■・ ■・■・ 44 ー第 3 章超解像奮闘記
Sigmoid 関数 値域が制限された活性化関数の 1 つに Sigmoid 関数があります。 Sigm 。 id 関数が出力する値 の範囲は、 001.0 です ( 図 3.15 ) 。 図 3.15 Sigmoid 関数 0.2 ー 2 2 最後の畳み込み層の活性化関数を Sigmoid 関数へ置き換えます ( 図 3.16 ) 。 図 3.16 活性化関数を変更したモデル 33X33X1 convl 9X9X64 ReLU conv2 1XIX32 ReLU conv3 5X5X1 Sigmoid 21X21X1 リスト 3.10 は、最後の畳み込み層の活性化関数を Sigm 。 id に置き換えたプログラムです 0 def inference(lr—images) : リスト 3.10 : srcnn/modeI/mode1915—sigmoid. py # 省略 conv3 conv3 conv2d( 'conv3' input_Iayer=conv2, weights—shape=[5, 5 , 32 , weight—stddev=1e-3, biases—shape=[CHANNELS] , st ri des= [ 1 , 1 , 1 , 1 ] , padding='VALID') tf. nn . sigmoid(conv3) CHANNELS] , biases vatue=@ . @, 56 return conv3 図 3.17 は、表 3.3 の条件で学習した場合の誤差の変化です。 第 3 章超解像奮闘記
さまざまなモデル ようやく超解像のモデルが実現できました。 引き続き、画質の向上を目指して、別のモデルを試します。 ( 9 ー ( 5 ー 1 ) 第 3 章で、 第 4 章 考にした論文 1 で、 9-1-5 より画質が良かったとされているモデル ( 図 4. l) です。 畳み込み層のフィルターサイズを、これまでの 9 ー 1 ー 5 から、 9 ー 5 ー 5 に変更します。 モテル ( 9-5-5 ) 図 4.1 2 番目の畳み込み層のフィルターサイズを変更したモデル 33X33X1 これは参 17X17X1 convl 9X9X64 ReLU conv2 5X5X32 ReLU conv3 5X5X1 Sigmoid リスト 4.1 は、モデル 9 ー 5 ー 5 のグラフを構築する関数 inference です。フィルターサイズが 変わったことで OUTPUT ー s 工 ZE も変わり、出力サイズは 17px となります。 リスト 4.1 : srcnn/model/mode1955_sigmoid. py 'modet955_sigmoid ' NAME INPUT SIZE 33 INPUT SIZE OUTPUT_SIZE CHANNELS 1 def inference(lr—images) : ( 5 ー convl conv2 convl conv2d( 'convl' input_layer=lr—images, input_layer=convl, conv2d( 'conv2' tf. nn . retu(convl) padding='VALID') strides=[l, 1 , 1 , 1 ] , biases_shape=[64] , biases—value=@ . @, weight—stddev=le-l, weights—shape=[9, 9 , CHANNELS, 64 ] , 60 第 4 章さまざまなモデル
表 4.4 画質指標の比較 モデノレ BICUBIC mode1955—sigmoid-color Batch NormaIization の導入 ( 5 ー PSNR 26. 27.57 SSIM 0.9434 0.9481 PSNR 、 SSIM のどちらも、 BICUBIC よりも高い値となりました て出力します。収束性能が向上し、小さなバッチサイズ、高い学習率で学習を進めることがで Batch Normalization は、前層からの入力をミニバッチ単位で正規化 ( 平均を 0 、分散を 1) し 図 4.11 BatchNorm を加えたモデル きると言われています。 33X33X1 convl 9X9X64 BN conv2 5X5X32 conv3 17X17X1 ReLU BN ReLU 5X5X1 BN Sigmoid 図 4.11 を見てわかるとおり、畳み込み処理と活性化関数の間に Batch Normalization を追加し ます。 リスト 4.5 は、モデル 9 ー 5 ー 5 に Batch NormaIiza ⅱ on を加えたプログラムです。 inference に 2 つの引数、 is-train と extra-ops を追加しています。 これまでの また、 biases-shape に None を設定することで、畳み込み後のバイアスの加算を行わない ように変更します。 リスト 4.5 : srcnn/modeI/modeL955_sigmoid—bn—COlor. PY 'modet955—sigm0id—bn_color' NAME 工 NPUT_SIZE 33 工 NPUT_SIZE OUTPUT SIZE CHANNELS ( 9 ー 1 ) 3 ( 5 ー def inference(lr_images, is_train=FaIse, extra—ops=[]) : conv2d( 'convl' convl input_layer=lr—images, weights—shape= [ 9 , 9 , CHANNELS, 64 ] , weight—stddev=le—l, biases shape=None, biases value=@ .@' st ri des= [ 1 , 1 , 1 , 1 ] , padding='VALID') 第 4 章 さまざまなモデル 69