Fully Convolutional Networks for Semantic Segmentation



CNN feature抽出器を用いて画像の重要な特徴を学習した.これはモデルのEncoder部分です.画像がボリュームlayerを通過するにつれて、それはサンプリングされます.画像は復号層、すなわち付加的なConvolutional Layerに移動する.Decoder layerは、画素レベル予測(labeling)を得るために画像を段階的に増幅する.

広く使われているDecoderはFCN-32、FCN-16、FCN-8である.

まず、FCN-32を見てみましょう.2 x 2 window size,2 x 2 stepを使用してプール操作を行うと、画像が半分に縮小します.これは、256個のx 256イメージを2個のx 2/2プールに統合すると、128個のx 228イメージが生成されることを意味する.FCN-32には5つのプール層があり、イメージを2^5,32倍に減らすことができます.
pool 5と呼ばれるpoolingのoutput layerは、元の画像を返すには32倍の拡大が必要です.すなわち、各画素はPool 5の32倍でなければならない.32倍の拡大は、各クラスをピクセル単位で予測します.

FCN−16はFCN−32に類似しているが、Pol 5を使用し、Pol 4も使用している.遠くのPool 5を2倍に拡大し、Pool 4と同じサイズにし、1 x 1ボリュームを使用してPool 4予測を作成します.この2層(2 x Upsampled PreditionとPool 4 predition)の追加は16ステップに拡大されます.

FCN-8 DecoderはFCN-16 Decoderに類似している.pool 5の2倍のプリフェッチ層とpool 4のプリフェッチ層を追加し、さらに2倍に拡大します.また、Pool 3に1 x 1のPool 3を加えてプリセットし、8倍に拡大する.

FCN−32,FCN−1,FCN−8の結果を比較することにより,FCN−8の分割結果は連続性に近いことが分かった.
def fcn8_decoder(Pool1, Pool2, Pool3, Pool4, Pool5, n_classes):
  '''
  
  # 2xUpsampled Predction form Pool5 
  o = tf.keras.layers.Conv2DTranspose(n_classes , kernel_size=(4,4) ,  strides=(2,2) , use_bias=False )(Pool5)
  o = tf.keras.layers.Cropping2D(cropping=(1,1))(o) 

  # 1x1 convolution to reshape from Pool4 - Pool4 Prediction
  o2 = Pool4
  o2 = ( tf.keras.layers.Conv2D(n_classes , ( 1 , 1 ) , activation='relu' , padding='same'))(o2)

  # 1st addition ( 2xUpsampled Prediction from pool5 + Pool4 Prediction) 
  o = tf.keras.layers.Add()([o, o2])

  # 2xUpsampled Predction from 1st addition
  o = (tf.keras.layers.Conv2DTranspose( n_classes , kernel_size=(4,4) ,  strides=(2,2) , use_bias=False ))(o)
  o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)

  # 1x1 convolotuion to reshape from Pool3 - Pool3 Prediction
  o2 = Pool3
  o2 = ( tf.keras.layers.Conv2D(n_classes , ( 1 , 1 ) , activation='relu' , padding='same'))(o2)

  # 2nd addition (2xUpsampled Predction from 1st addition and Pool3 Prediction)
  o = tf.keras.layers.Add()([o, o2])
  
  # upsampling to original image size
  o = tf.keras.layers.Conv2DTranspose(n_classes , kernel_size=(8,8) ,  strides=(8,8) , use_bias=False )(o)

  # softmax activation
  o = (tf.keras.layers.Activation('softmax'))(o)

  return o