Fully Convolutional Networks for Semantic Segmentation 본문

ML & DL/Paper Review

Fully Convolutional Networks for Semantic Segmentation

eremo2002 2021. 1. 29. 23:29

ASCAL c segmentation task에서 SOTA를 달성하였다.

 

Abstract

  • convolution layer만 사용하는 FCN(Fully Convolutional Network)을 제안하였고, pixel 단위의 예측을 해야하는 semantic segmentation task에서 SOTA를 달성하였다.
  • AlexNet, VGG, GoogLeNet 구조를 fully convolutional network 형태로 튜닝하고, transfer learning을 이용하였다.
  • 또한, skip connection구조로 low-level feature, high-level feature를 결합하여 보다 정교한 segmentation output을 낼 수 있었다.
  • 제안하는 FCN은 PASCAL VOC segmentation task에서 SOTA를 달성하였다. (기존 모델대비 약 20%의 성능 향상)

 

Introduction

CNN은 classification, detection 등 다양한 recognition task에서 뛰어난 성능을 보여주고 있다. segmentation task에선 coarse feature를 통해 pixel-wise prediction을 위한 fine feature를 잘 생성해야 한다.

  • 본 논문에서는 'coarse'라는 키워드를 지속적으로 사용한다. 이 단어는 '굵은', '거친'이라는 의미를 가지고 있으며 'fine'과 반대의 의미를 지닌다. coarse feature가 처음엔 low-level feature를 의미하는 줄 알았는데 그게 아니고 CNN의 conv, pooling layer를 통해 resolution이 충분히 작아진 feature를 의미한다.
  • 일반적으로 classification task에선 coarse feature를 벡터로 만들어 classifier의 입력으로 넣어 분류를 수행하지만 pixel 단위의 prediction을 수행해야 하는 segmentation task에선 coarse feature를 다시 input image size와 비슷한 크기로 up-sampling해주는 작업이 필요하다. 그래야 더욱 정교한 pixel-wise prediction이 가능하기 때문이다.

본 논문에서 제안하는 fully convolutional network(FCN)는 pixel-wise prediction을 위한 최초의 end-to-end 모델이자 pre-training 모델을 사용하였다. 기존에 fully convolutional 형태의 network들이 존재하긴 했지만 이러한 모델들은 랜덤하게 crop된 image patch를 입력으로 넣는 patchwise training을 사용하였고 fully conv 모델에서는 patchwise training이 더 비효율적이다. FCN은 patchwise training을 사용하지 않고 이미지 전체를 하나의 입력으로 사용하였다.

밑에서 설명하겠지만 coarse feature를 다시 up-sampling하는 과정에서 정보가 손실될 수 있다. 이러한 문제를 방지하기 위해, skip connection 구조를 사용하여 좀 더 다양한 feature spectrum을 다루고자 하였다.

  • deep feature ↔ shallow feature
  • coarse ↔ fine
  • semantic ↔ appearance

 

Fully convolutional networks

기본적으로 convolution 연산은 translation invariance하다. 이는 레이어를 거듭하여 feature size가 down sampling되더라도 위치 정보는 변하지 않는다. 예를 들어, 이미지 왼쪽 상단에 고양이가 있었을 때 convolution layer를 여러 번 거쳐 resolution이 줄어들더라도 여전히 왼쪽 상단에 고양이에 대한 정보가 남아있다.

또한, FCN은 fully-connected layer를 사용하지 않기 때문에 고정된 입력 size를 사용해야 하는 제한에서 벗어날 수 있다. 일반적인 classification network에선 충분히 추출된 feature map을 vector로 변환한 뒤 classifier의 입력으로 사용한다. 이미 네트워크를 정의하면서 vector의 크기 또한 정의되었기 때문에 반드시 입력 이미지 크기가 고정되어야 한다.

  • 연산량, 파라미터가 너무 많고 고정된 입력 사이즈를 받아야 한다는 점에서 fully-connected layer가 갖는 문제는 명확하다. 이러한 문제로 인해 Global Average Pooling(GAP)을 사용하는 모델들이 많다.

Adapting classifiers for dense prediction

LeNet AlexNet, VGG 등 fully-connected layer를 사용하는 유명 모델들은 대부분 입력 사이즈를 고정된 크기로 받아 공간적인 정보가 사라진 non-spatial output을 출력하게 된다.

fully-connected layer가 공간정보를 잃어버리는 특징이 있지만 다른 관점에서 생각해봤을 때, convolution kernel의 사이즈가 입력 region 전체를 커버하는 크기로 conv 연산을 수행하는 것으로 해석할 수도 있다.

  • fully-connected layer를 f.c layer와 비슷한 효과를 낼 수 있는 conv layer로 대체하여 고정된 입력 크기를 받는 문제에서 벗어나고자 함
  • 고정된 입력 사이즈를 받아야 하는 문제를 해결함과 동시에 출력 output feature map의 크기 또한 입력 사이즈와 동일하게 생성할 수 있다. 입력의 height, width값이 500x500이였으면 출력도 500x500이 된다.

Shift-and-stitch is filter rarefaction

input shift and output interlacing trick은 coarse output에서 dense prediction feature를 생성하기 위한 방법 중 하나이며 OverFeat에서 소개되었다. 해당 trick은 일종의 up-sampling 방법이라고 볼 수 있는데 interpolation을 사용하지 않고 up-sampling을 수행한다.

 

5x5 input에 zero-padding, shift연산을 수행하여 translate된 4개의 입력을 만들어낸 후 각 입력에 대해 2x2 max-pooling 연산을 수행한다. 첫 번째(red)를 보면 output의 크기가 3x3가 나오게 되고, 다른 output을 보면 3x2, 2x3, 2x2 등의 output이 나오게 된다. 어느 방향으로 shift 연산 했는지에 따라 output 사이즈가 달라지게 된다.

shift 방향에 따라 output 크기가 3x3가 아닌 경우 sliding window 연산이 더 적게 수행된다. 왜 sliding window를 끝까지 수행하지 않는지 이해가 잘 안되었는데 아래 예제에선 결과적으로 입력 크기와 동일한 5x5를 만들어 내기 위해선 3x3, 3x2, 2x3, 2x2 output이 필요하다. output을 어떻게 stitching 할 것인지에 따라 3x3, 3x3, 3x3, 3x3 output을 가지고도 5x5를 만들어 낼 수 있을 것이다.

 

어쨌든 이러한 4개의 output을 combine하여 오른쪽 아래 그림과 같이 입력 사이즈와 동일한 5x5 output을 생성한다.

 

https://stackoverflow.com/questions/40690951/how-does-shift-and-stitch-in-a-fully-convolutional-network-work

 

 

 

본 논문에서는 convolution layer의 filter와 stride 값에 따라 shift-and-stitch trick과 유사한 결과를 낼 수 있다고 한다. 그러나 결과적으로 해당 trick을 적용하지 않는다. 추후 소개되는 skip connection 구조가 더욱 효과적이기 때문이다.

 

 

 

Upsampling is backwards strided convolution

coarse output에서 dense prediction을 만들어내기 위해 upsampling이 필요하다. interpolation으로 upsampling을 수행할 수 있지만 본 논문에선는 deconvolution이라는 layer를 사용하여 upsampling을 수행한다. deconvolution은 convolution의 역연산으로 가중치가 있기 때문에 end-to-end 방식으로 학습이 가능하며 비선형 함수를 통해 비선형성 또한 증가시킬 수 있는 장점이 있다. 논문에서는 deconvolution을 통해 빠르고 효과적인 dense prediction이 가능해졌다고 말한다.

 

deconvolution

  • Decovnolution은 convolution의 역연산
  • 5x5 input이 있을 때 3x3 kernel을 사용하면 2x2 output을 만들어낸다. 2x2 ouput을 다시 기존의 5x5 input과 동일한 값으로 복원하고자 할 때 사용한다.
  • 단순히 spatial size만 동일하게 upsampling하는 것이 아니라 기존의 input pixel 값과 동일한 값을 만들어내야 한다. 따라서 convolution 연산에 사용되었던 kernel과 동일한 kernel을 사용해야 한다.

Transposed convoltuion

  • deconvolution과 유사하지만 명백한 차이점이 있다.
  • output을 input과 동일한 크기로 upsampling한다는 점에서는 같다.
  • 그러나 기존의 input pixel 값과 동일한 값을 만들어낼 필요는 없다. 따라서 convolution 연산에 사용되었던 kernel과 다른 kernel이 사용된다.
  • tranpose라는 의미는 아래 예로 보면 더욱 명확하다.

우선 일반적인 convolution의 matrix 연산은 아래와 같이 수행된다.

4x4 input은 16x1 vector로 만들어주고 3x3 kernel은 4x16 sparse matrix로 변환하여 계산한다.

stride로 인한 값을 0으로 채워주기 때문에 sparse matrix라고 한다.

 

 

 

 

기존의 convolution 연산에서 3x3 kernel을 4x16 sparse matrix로 변환해서 사용하였다. 그러나 transposed convolution은 4x16 sparse matrix가 아닌 16x4 sparse matrix를 사용한다. 그래서 이름이 "transposed" convolution이다.

 

 

본 논문에서는 deconvoltuion이라는 단어를 사용하는데 구체적으로 따지면 deconvolution은 아니고 transposed convolution이다. ML, DL 쪽에선 초창기 deconvolution과 transposed convolution을 명확히 구분하지 않고 혼용하여 사용했기 때문에 논문에서도 이러한 혼용이 있는 거 같다.

 

 

Patchwise training is loss sampling

patchwise training이란 하나의 이미지에서 객체가 존재하는 위치를 crop하여 하나의 patch로 만든 뒤 모델에 입력하는 training 방식이다. patchwise training을 사용하는 이유는 이미지에 필요없는 정보들이 존재할 수 있고 하나의 이미지에서 서로 다른 객체가 존재하는 경우 redundancy가 발생하기 때문이다.

  • 고양이와 관련된 feature를 추출해야 하는데 어쩔 수 없이 car가 있는 영역까지 보게 되는 문제

 

patch를 어떤 방식으로 만들어낼 것인지에 따라 다양하겠지만 patch간에 overlap이 일어나지 않는다면 patchwise training과 whole image training이 동일하다. 만약 100x100의 입력 이미지가 있을 때 이를 10x10 grid로 분할하면, 10x10 크기의 patch를 100개 만들어낼 수 있다. 100개의 patch를 모두 조합하면 결국 100x100 이미지가 된다. 이 경우 patch를 뽑아낼 때 overlapping을 적용하지 않은 경우이고, 만약 overlapping을 허용하여 patch를 뽑아내게 되면 더 많은 수의 patch가 만들어진다.

  • patch를 overlap되지 않게 추출한다고 해도 patchwise training과 whole image training이 동일하다고 말하는 건 조금 동의하기 어렵다. patch들을 전부 모으면 결국 하나의 원본 image가 되겠지만 개별 patch에서 feature를 뽑아내는 것과 image 전체를 보고 feature를 뽑아내는 것에는 명백한 차이가 있기 때문이다.

 

patchwise training의 장점은 class imbalance 문제를 완화할 수 있지만 spatial correlation 정보가 부족해지는 단점이 있다. spatial correlation이 부족하다는 것은 결국 이미지의 일부(patch)를 볼 것이냐 이미지 전체를 볼 것이냐의 차이를 말한다.

 

해당 section의 제목이 patchwise training is loss sampling인 이유는 내가 이해한 바로 하나의 이미지를 100개의 patch로 분할하여 각 patch마다 모델에 입력했을 때 100개의 prediction이 나오게 되고 100개의 loss 값이 계산된다. 그럼 여기서 background 같은 중요치 않은 patch들이 존재할 수 있고 object가 포함된 중요한 patch들이 포함되는 경우도 있을 것이다. 따라서 각 patch마다 계산된 loss값을 모두 다 더해서 사용하는 게 아니라 각 loss마다 weight를 주거나 중요한 patch에서 계산된 loss값만 샘플링해서 사용하겠다는 것으로 이해하였다.

 

결과적으로 본 논문에선 patchwise training을 사용하지 않았다. 실험에서 whole image training이 dense prediction을 위한 training 속도 측면에서 더 효과적이고 효율적이었다고 한다.

 

 

Segmentation Architecture

From classifier to dense FCN

AlexNet, VGG, GoogLeNet를 FCN 방식으로 튜닝하였다. GoogLeNet의 경우 네트워크의 중간중간 softmax layer가 존재하는데 해당 layer를 제외하고 final loss layer만 사용하였다. PASCAL VOC dataset의 class 개수를 맞추기 위해 1x1 conv를 사용하였다.

 

실험 결과론 VGG가 가장 높은 성능을 보여주었고 GoogLeNet의 경우 segmentation task와 적합하지 않은 모델로 보임

 

 

Combining what and where

입력 이미지가 pooling layer를 거치면서 아래와 같은 비율로 사이즈가 줄어든다. 결과적으로 pool5까지 거치게 되면 feature의 크기는 입력 이미지의 1/32이 된다. (224x224 → 7x7)

 

32배 작아진 feature를 가지고 32배 upsampling 하게 되면 디테일한 정보들이 많이 없는 상태에서 과도하게 크기를 늘리게 때문에 정확한 prediction이 어렵다. 그래서 논문에선 사이즈를 차근차근 증가시키고 coarse feature에서 부족했던 정보를 pool3, pool4에서 가져와서 결합한 뒤 채우겠다는 것이다. coarse feature는 상대적으로 global feature를 담고 있기 때문에 local feature가 부족하고 부족한 local feature를 이전 레이어의 feature에서 가져오겠다는 것

  • conv6: 7x7x512 → 7x7x4096
  • conv7: 7x7x4096 → 7x7x21

  • pool3, pool4에서 가져온 featuer를 2x conv7, 4x conv7과 결합하기 위해선 채널 사이즈를 맞춰주어야 한다. 채널 사이즈 매칭은 1x1 conv를 이용함

 

이러한 upsampling을 몇번 수행할 것인지에 따라 FCN-32, FCN-16, FCN-8 3가지 버전의 모델이 만들어지게 된다. 당연히 FCN-8이 더 많은 feature combining을 이용하기 때문에 성능이 높다. upsampling을 더 수행하면 FCN-4, FCN-2도 만들 수 있겠지만 FCN-8까지만 만들었다.

 

 

Experimental framework

  • optimizer: SGD, momentum: 0.9
  • batch size: 20
  • learning rate의 경우 각 모델마다 고정된 값을 사용함
    • AlexNet: 1e-3
    • VGG16: 1e-4
    • GoogLeNet: 1e-5

 

실험에서 patch sampling 방식과 full image 방식을 비교하였는데 sampling 방식이 loss 수렴 속도도 늦고 학습 속도도 더 오래 걸린다. 결과적으로 full image 방식을 사용하여 학습하였다.

 

 

data augmentaton으로 randomly mirroring, jittering, translating 을 사용하였다.

  • image mirroring은 flip이라고 생각하면 됨
  • jittering은 이미지 픽셀 값 자체를 변화(?)시킨 일종의 노이즈 추가로 보인다.

 

Result

본 논문에서는 4가지 metric을 사용하여 평가한다.

 

 

 

실험 결과

 

 

 

 

 

각 실험 table에서 다른 모델과 비교했을 때 FCN 구조가 SOTA를 달성하였다.

 

 

 

 

아래 prediction 결과를 봤을 때 굉장히 작은 부분까지 정교하게 예측하기엔 어려워 보인다. 특히 4번째 row를 봤을 때 구명조끼를 사람으로 잘못 인식한 결과를 보여주었다.

 

 

Conclusion

modern classification model을 fcn 방식으로 재구성하여 semantic segmentation task를 풀고자 하였다.

향후 multi-resolution layer 같은 아키텍처 튜닝을 통해 더욱 성능을 개선할 것으로 보고 이와 동시에 모델 구조 또한 심플하게 구축한다면 학습, 인퍼런스 속도 또한 개선할 수 있다.

 

 

my opinion

  • 기존 classification model을 응용하여 semantic segmentation task를 해결한 모델로 semantic segmentation 대표 모델 중 하나로 꼽히는 중요한 논문이다.
  • 고정된 입력 사이즈를 해결하고, 효과적인 upsampling, skip connection 등의 여러 technique을 결합하여 SOTA를 달성했다는 점 그럼에도 모델 구조 자체가 복잡하지 않고 심플함
  • 이미지의 작고 디테일한 영역까지 정교하게 segmentation하기 어려워 보이고 인간보다 높은 segmentation 성능을 내려면 아직 갈 길이 멀다.
  • fully connected layer를 convolution으로 변환하는 conv6 layer의 경우 7x7 kernel을 사용하는 것보다 1x1 kernel을 사용하는 것이 파라미터 수, 연산량 측면에서 더 효율적일 것 같다는 생각이 듦
Comments