Fully Convolutional Networks for Semantic Segmentation

Hanna·2022년 2월 18일
0


CNN feature extractor를 사용해 이미지의 key feature를 학습을 하게 됩니다. 이 부분이 model의 Encoder 부분입니다. 이미지가 convolutional layer를 지남에 따라, downsampling이 됩니다. 이미지는 추가의 Convolutional layer인 decoder layer로 옮겨집니다. Decoder layer는 pixelwise prediction(labeling)을 얻을 수 있도록 이미지의 단계별 upsampling을 하게 됩니다.


널리 사용하는 Decoder는 FCN-32, FCN-16, FCN-8입니다.


먼저 FCN-32에 대해 보도록 하겠습니다. 2x2 window size, 2x2 stride로 pooling을 하게 되면 이미지는 반으로 줄어들게 됩니다. 즉, 256x256 이미지를 2x2/2 pooling을 하게 되면 128x128 이미지가 되는 것입니다. FCN-32는 5개 pooling layer로 되어 있어 있어서 2^5, 32배로 이미지가 줄어들게 됩니다.
우리가 pool5라고 부르는 pooling의 output layer는 원본 이미지로 돌아가기 위해서는 32배의 upsampling이 필요합니다. 즉, Pool5의 각각의 pixel들을 32배 해야한다는 의미입니다. 32배의 upsampling은 각각의 class들을 pixelwise prediction하게 됩니다.

FCN-16은 FCN-32와 비슷하지만 Pool5를 사용할 뿐만 아니라 Pool4도 함께 사용합니다. 먼제 Pool5를 2배만큼 upsampling하여 Pool4와 같은 크기를 갖도록 만들고, Pool4를 1x1 convolution을 사용하여 Pool4 prediction을 만듭니다. 이 두 layer(2x Upsampled prediction과 Pool4 predcition)의 addition은 16 stride로 upsampling합니다.

FCN-8 Decoder는 FCN-16 Decoder와 비슷합니다. Pool5를 2배 upsampling한 layer와 Pool4 Prediction한 layer를 addition을 한 다음 2배 upsampling을 합니다. 또한, Pool3을 1x1 convolution을 한 Pool3 Prediction을 addition을 하여 8배 upsampling을 합니다.


FCN-32, FCN-1, FCN-8의 결과를 비교해보면 FCN-8의 Ground truth에 가깝게 segmentation 된 것을 알 수 있습니다.

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
profile
매일 성장하고 있습니다

0개의 댓글