MODEL . INPUT_SIZE, MODEL . OUTPUT_SIZE, channets=MODEL. CHANNELS, scaIe=FLAGS. scate, batch—size=FLAGS . batch—size / / 4 ) # 省略 図 4.6 は、表 4.3 の条件で学習した場合の誤差の変化です。カラー画像なので、学習に時間が かかると予想して 60 万ステップに設定しましたが、実際には、 10 万ステップ以降は大きな変化 がありませんでした。 表 4.3 学習条件 条件 画像の倍率 (scale) 学習率 (learning-rate) ニバッチサイズ (batch_size) ステップ数 (max_step) チャンネル数 (CHANNELS) 値 2 3 (RGB カラ 図 4.6 誤差の変イヒ (smoothing=O. 9) 7 ℃び」 e ・ 3 6 き 3 5 ℃ CCe -3 3 [ 0 」 e ・ 3 2.0C0 き 3 0 CC 6 : . Ck 5C0. 20C ℃ k 100. 400. 00k 0. 縦横 510PX のカラー画像を用意しました ( 図 4.7 ) 。 一平価用の画像として、 66 第 4 章 さまざまなモデル
def __train(file_list, patches_count, train_dir) : checkpoint—path = OS . path . join(train—dir, 'model . ckpt') math . ceil(patches—count / FLAGS . batch_size) step—of—epoch toad—image ( images, ground—truths fite list, MODEL . INPUT_SIZE, MODEL . OUTPUT_SIZE, channeIs=MODEL . CHANNELS, scaIe=FLAGS. scale, batch_size=FLAGS . batch—size / / 4 ) FLAGS. min_after_dequeue + 4 ☆ FLAGS. batch_size capacity lr—image—batch, ground—truth-batch = tf. train . shuffte—batch( [images' ground—truths] , batch size=FLAGS . batch_size, capacity=capacity, enqueue_many=True, min_after_dequeue=FLAGS. min_after_dequeue, num_threads=FLAGS . num_threads) MODEL . inference(tr_image—batch) loss(sr—images, ground—truth-batch) sr_nmages IOSS tf.VariabIe(), trainable=FaIse) gtobal—step init_optimizer(FLAGS. learning—rate) opt opt. minimize(toss, global—step=global—step) train_op config = tf. ConfigProto( at10w_soft_pIacement=True, Iog—device—ptacement=FLAGS. tog—device—ptacement) saver = tf. train . Saver(tf. global—variables()) tf. train . Coordinator() coord with tf. Session(config=config) as sess: tf. train . get_checkpoint—state(train_dir) checkpoint if not (checkpoint and checkpoint. model—checkpoint—path) : sess . run(tf. global—variables—initializer()) else: 30 第 2 章 CNN で超解像
リスト 3.6 : srcnn/eval.py def _srcnn(image—path, scale, # スライド幅を変更 stride (MODEL. OUTPUT_SIZE, train_dir): MODEL. OUTPUT_SIZE) name, ext = OS. path. sptitext(os. path. basename(image_path)) dir OS . path . dirname(image_path) dir OS . path. join(dir, MODEL . NAME) if not os . path . exists(dir): os . mkdir(dir) padded_fite result fite OS . path . j Oi n ()i r , 96s—96dx ・ png % (name, scale)) OS . path . join(dir, '96s—96dx—resuIt ・ png % (name, scale)) lmage ・ open(image—path) 1 mage resized_image image . resize( (image. width 大 scale, image ・ height ☆ scale) , 工 mage. BICUBIC) if MODEL . CHANNELS resized image 1 : resized—image. convert('L') padding calc—padding(resized—image, stride) resized_image —pad(resized—image, padding=padding) —save—image(resized—image, padded—fite, padding=padding) blocks blocks extract_blocks(resized—image, stride) —process(btocks, train—dir) resutt_image result_image —reconstruct(blocks) _normalize(resutt_image) ☆ 255 # パディングの再計算 pad round ( (MODEL. INPUT_SIZE MODEL. OUTPUT_S 工 (E) / 2 ) padding[ 工 NDEX_PADDING_LEFT] pad padding[ 工 NDEX—PADDING_TOP] pad padding[INDEX_PADDING_RIGHT] + = pad padding[INDEX_PADDING_BOTTOM] + ニ pad —save—image(resutt—image, result—file, padding=padding) 第 3 章超解像奮闘記 51
OS . path . join(dir, MODEL. NAME) dir if not os . path . exists(dir) : os . mkdir(dir) OS . path . j 0i n ( di r , 96s—96dx ・ png OS . path . j Oi n ()i r , '96s-96dx—resuIt. png padded_fite % (name, scate)) resutt file % (name, scale)) lmage . open(image—path) 1 mage image. resize( resized_image (image. width ☆ scale, image . height ☆ scale) , lmage . BICUBIC) if MODEL . CHANNELS resized image resized_image . convert('L') calc—padding(resized—image, stride) padding —pad(resized—image, padding=padding) resized_image —save—image(resized—image, padded—file, padding=padding) extract_btocks(resized—image, stride) btocks —process(blocks, train—dir) btocks —reconstruct(btocks) resutt_image normalize(result_image) ☆ 255 result_image round((MODEL. INPUT_SIZE MODEL . OUTPUT_SIZE) / 2 ) pad pad padding[INDEX_PADDING_LEFT] pad paddingCINDEX_PADDING_TOP] padding[INDEX_PADDING_RIGHT] + = pad padding[INDEX_PADDING_BOTTOM] + = pad —save_image(result image, result—fite, padding=padding) file, padded—file return result 平価 一平価用の画像として、縦横 510PX5 の画像を用意しました ( 図 2.5 ) 。 三ロ 38 第 2 章 CNN で超解像
cropped—image, (output_size, output_size) ) resized_image = tf. image. resize_nmages( cropped—image, (input—size / / scale, input_size / / scate) , method=tf. image . ResizeMethod . BICUBIC) lr—image tf. image. resize_images( resized_image, (input—size, input_size) , method=tf. image. ResizeMethod . BICUBIC) ground—truths. append(ground_truth) lr—images ・ append(lr—image) lr_images tf. stack(lr_images, axis=@) ground_truths tf. stack(ground—truths, axis=@) return lr_images / 255 , ground_truths / 255 ます、読み込んだファイルを tf. image. decode ー jpeg でデコードします 次に、指定したサイズでランダムで切り抜き (tf. random_crop) 、画像 cropped_image を指定のサイズ (output_size) に縮小します。これが ground_truth 、モデルの出力とし て期待する高解像度の画像となります。 また、 cropped-image を元に、解像度の低い画像 (tr_image) を作ります。一度 scale に指定された大きさに縮小 (resize) したあと、再び拡大することで擬似的に解像度を下げ ☆☆☆ 1 1 x 1 1 33X33 cropped—image 図関数 load_image の動作 ます。 CNN 33X33 lr—image ground—truth 21X21 第 2 章 CNN で超解像 27
画像の保存 ( パディングの除去 ) リスト 2.12 の関数 __save_image は、処理済みのデータを画像としてファイルに保存します。 MODEL に定義しているチャンネル数 (CHANNELS) が 1 ( グレースケール ) の場合は配列の 形を変更します 4 。 また、保存の前に付加したパディングを除去 (crop) します。 リスト 2.12 : srcnn/eval.py def —save—image(image, file, padding=None) : mode ' RGB' if MODEL . CHANNELS 1 : 1 mage 1 mage mode np. transpose(image, ( 2 , 0 , 1 ) ) # チャンネル軸を移動 image[@] 工 mage. fromarray(np. uint8(image) , mode=mode) result_image if padding is not None: teft padding[INDEX_PADDING_LEFT] paddingCINDEX_PADDING_TOP] top right result_image. width padding[INDEX_PADDING_RIGHT] bottom result—image . height paddingCINDEX_PADDING_BOTTOM] result_image result—image ・ crop((teft, top, right, bottom)) result—image. convert( ' RGB' ) . save(fite, 実行 ' PNG ' ) これまでのプログラムを組み合わせて画像に超解像処理をします。 リスト 2.13 の関数ー srcnn は、画像 (image_path) をデコードして、 scale 倍したものを、 train ー dir に保存されているパラメーターを使って、超解像処理を実行します。 最後に、モデルから出力されるピクセルの値 (@ . @-1. @) を 255 倍します ( 入力時と逆の (MODEL . INPUT_SIZE, MODEL . INPUT_SIZE) stride _srcnn(image—path, scale, train_dir) : def リスト 2.13 : srcnn/eval.py 処理 ) 。 name, dir ext = OS. path . sptitext()s . path. basename(image—path)) OS . path . di rname(image—path) 第 2 章 CNN で超解像 37
表 3.3 : 学習条件 条件 画像の倍率 (scale) 学習率 (learning-rate) 、ニバッチサイズ (batch_size) ステップ数 (max_step) チャンネル数 (CHANNELS) 1 ( グレースケール ) 図 3.17 誤差の変化 (smoothing=O. 9) 3 開 .0 開 128 0.81 2x 6. CCOe -3 5.80e -3 4.80e -3 3 ℃℃ 0 3 2.000e -3 1. 総 -3 0 、 80 10 ℃ 0 え 20 : ℃ Ok 40 k 50 、 60. : 光 k ℃ 0 イ 日 ) よ : k ℃ Ok 1 【℃ . 図 3.18 は、評価用の画像を 2 倍に拡大後、学習済みのモデルを使って超解像処理をした結果 です。 低解像度の画像にあった荒さが消えて、なめらかになっているのがわかります。また、目立 っノイズも見当たりません。 ずいぶん遠回りした気がしますが、ようやく、 CNN を使った超解像のモデルができました。 第 3 章 超解像奮闘記 57
weights—shape=[5, 5 , 64 , 32 ] , weight—stddev=le-l, biases—shape=[32] , biases—vatue=@ . @, st ri des= [ 1 , 1 , 1 , 1 ] , padding='VALID') tf. nn . reIu(conv2) 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='VAL 工 D') tf. nn . sigmoid(conv3) 1 ( グレースケール ) conv3 conv3 conv2 図 42 は、表 4.1 の条件で学習した場合の誤差の変化です。 return conv3 CHANNELS] , biases value=@ . @, 表 4.1 : 学習条件 条件 画像の倍率 (scale) 学習率 (learning-rate) ニバッチサイズ (batch_size) ステップ数 (max_step) チャンネル数 (CHANNELS) 図 4.2 誤差の変化 (smoothing=O. 9) 000 5 ℃ 00e -3 0.018 0.0150 0.02C0 0025 つ 00 三 ) ン 値 0. 開 1 128 300 , 開 0 1 CC :. 150. 28 し 250. ⅸ 第 4 章 3 〔 00 ス . さまざまなモデル 61
tr_images ground_truths for i in range(batch—size) : tf. random—crop( cropped—image image, (input—size, input—size, channels)) tf. image. resize_images( ground—truth cropped_image, (output—size' output—size)) tf. image. resize_images( resized image cropped—image' (input—size / / scale' input—size / / scate) , method=tf. image. ResizeMeth0d. BICUBIC) tf. image. resize_images( tr—image resized image, (input—size, input—size) , method=tf. image. ResizeMethod . BICUBIC) ground—truths. append(ground—truth) tr—images ・ append(lr—image) tf. stack(lr—images, axis=@) lr_images tf. stack(ground—truths, axis=@) ground_truths return tr_images / 255 , ground—truths / 255 ランダムで切り出した 33px の画像 (cropped-image) を縮小して高解像度の画像 「 ground-truth 」とします。また、 cropped-image を縮小してから、もう一度拡大する ことで、画像を低解像度の画像「 tr-image 」を作成しています。 48 第 3 章超解像奮闘記
MODEL . inference(tr_image_batch, is_train=True, extra_ops=extra_ops) extra_ops sr_nmages IOSS loss(sr—images, ground—truth—batch) gtobal—step tf.VariabIe(), trainabIe=Fatse) init_optimizer(FLAGS . learning_rate) opt train—op opt. minimize(loss, globat_step=global—step) tf. group(train—op, *extra—ops) 図 4.13 は、表 4.5 の条件で学習した場合の誤差の変化です。 表 4.5 学習条件 条件 画像の倍率 (scale) 学習率 (learning-rate) ニバッチサイズ (batch_size) ステップ数 (max_step) チャンネル数 (CHANNELS) train—op 2 3 (RGB カラ 図 4.13 誤差の変イヒ (smoothing=O. 9) 6.88-3 5.3-7 ( 総 -3 町工 0 ま 3 3 ℃ 0 コチ 3 2. C00 チ 3 1 ℃ 0 ( 辱 3 C.a コ 28- 18. 0.80 4C00k 0 BatchNormalization がないモデルと比べると幾分、誤差のバラッキが小さくなっているよう です。 図 4.14 は、評価用の画像を 2 倍に拡大後、学習済みのモデルを使って超解像処理をした結果 第 4 章 さまざまなモデル 73