관리 메뉴

TEAM EDA

Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation (DeepLabv3+) 본문

EDA Study/Image Segmentation

Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation (DeepLabv3+)

김현우 2021. 9. 23. 17:40

Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation

DeepLab 시리즈의 마지막 글인 DeepLabv3+의 리뷰를 하도록 하겠습니다. v3+ 또한 기존의 논문들과 구성 자체는 비슷하기에, 기존의 DeepLab 논문을 아직 안보시는 분들은 아래의 글을 먼저 참고하시기 바랍니다.

Motivation

image-20210923134108951

위의 DeepLabv3의 그림을 보면 알겠지만, 한계점 중에 하나가 디테일한 정보인 Object Boundary의 손실입니다. 이를 해결해주기 위해서 기존의 Deeplab은 CRF를 적용하기도 하였고 특징맵을 원본 이미지 대비 1/8까지만 줄여서 사용했습니다. 하지만, 이는 좋은 해결책은 맞지만 아직 충분하지는 않았습니다.

figure/Untitled.png

이를 해결해주기 위해서, 논문에서는 Encoder-Decoder 구조와 Spatial Pyramid Pooling 구조를 합칩니다.

image-20210923145305846

기존의 DeepLab과 PSPNet을 생각해보면 DeepLab은 Atrous Spatial Pyramid Pooling (Dilated Conv with different rates)을 통해서 다양한 Resolution을 가지는 정보를 잡았습니다. 또한, PSPNet은 다른 Grid Scale의 Average Pooling을 통해서 다양한 Resolution을 가지는 정보를 추출했습니다. 하지만, 이렇게 할 경우에 경계면의 자세한 정보들이 손실되는 문제가 있었습니다. 이를 해결해주기 위해서, Encoder-Decoder 구조에서 Encoder에 Low-Level Features를 결합하는 구조를 사용하게 됩니다.

BackBone

Deeplabv1에서는 Vgg16을 v2, v3는 ResNet101을 사용했지만 v3+에서는 Modified Xception을 사용합니다. Xception은 아래와 같이 Depthwise Separable Conv을 사용하는 방법입니다.

figure/Untitled%204.png

Depthwise Separable Convolution은 Depthwise Conv과 Pointwise Conv을 결합한 방법입니다.

image-20210923145714321

위의 그림과 같이 Depthwise Convolution은 각 Channel 별로 Convolution을 수행합니다. 이는 기존의 Convolution이 Spatial과 Dimension에서 상관성이 있었다면, Depthwise Convolution은 채널별로 Convolution을 수행하기에 공간적인 정보만 가지고 결과를 냅니다. 그리고, Pointwise Convolution은 1x1 Convolution을 의미합니다. 이는 Depthwise Convolution의 결과를 채널별로 연산함으로서 공간적인 정보는 보지않고 채널의 정보만을 통해서 연산을 진행한다고 생각하면 됩니다. 이러한 방법의 가장 큰 장점은 연산량이 감소하는 특징이 있습니다.

image-20210923150421591

논문에서는 이러한 Xception이 아닌 Modified Xception을 조금 수정한 Modified aligned Xception을 사용합니다. 기존의 Xception과 Modified Xception의 차이점은 다음과 같습니다.

  • Entry Flow의 Maxpooling의 연산을 Depthwise Separable Convolution + BatchNorm + Relu으로 변경합니다.
  • Middle Flow에서 8번 반복하던 구조를 16번으로 늘려서 깊은 레이어를 사용합니다.
  • Exit Flow의 Maxpooling의 연산을 Depthwise Separable Convolution + BatchNorm + Relu으로 변경합니다. 또한, 2개의 Depthwise Separable Conv가 아닌 3개의 Depthwise Separable Conv을 사용합니다.

위의 구조가 Modified Xception입니다. 단, 여기서 Aligned Xception의 경우 가지의 차이점이 있습니다.

  • Xception 구조를 Segmentation 문제에 사용하는 경우, 4번의 strided convolution을 통해 입력을 1/16 크기로 줄입니다. 즉, 마지막 Exit Flow의 Strided Convolution을 사용하지 않습니다. (단, 논문에서는 OS인 Outsize Stride에 따라서 1개만 없애서 1/16로 활용할지 2개를 없애서 1/8로 활용할지로 나뉩니다.)
  • Exit Flow의 Convolution은 Dilation 2의 Convolution을 사용합니다. (마지막 3개의 Convolution을 의미)

Encoder-Decoder 구조

image-20210923151352876

여기까지의 구조가 다음과 같습니다. 512x512의 입력이 들어오면 16배를 줄여서 32x32를 만들고, 이때의 네트워크는 Modified Align Xception 입니다. 그리고, 이 결과가 먼저 ASPP를 통과합니다. ASPP는 지난 DeepLabv3 논문에서 봤던 구조를 똑같이 사용합니다. 관련해서 기억이 안나시는 분은 https://eda-ai-lab.tistory.com/597 의 글을 참고하시기 바랍니다.

image-20210923151614887

다음으로 이제 Entry Flow 내 첫번째 블록 출력을 Decoder로 전달합니다. 이는 128x128로 4배만큼 줄어든 크기이고, 깊은 레이어와 Strided Convolution을 거치기 전이라 정보의 손실이 적은 정보입니다. (정보의 손실이 적기도하고 낮은 수준의 색상, 모양과 같은 정보를 담고 있습니다.)

image-20210923151749625

그리고, 이 둘의 결과를 같이 결합해줍니다. 먼저, Low-Level의 특징은 1x1 Conv를 통해서 채널을 맞춰주고 ASPP의 출력은 Bilinear-Interpolation을 통해서 크기를 맞춰줍니다. 그리고, 이를 Concat 해줘서 Low Level과 High Level의 특징을 모두 사용하고, 이에 3x3 Conv을 통해서 클래스의 수만큼 Pixel-Wise Classification을 수행합니다. 마지막으로 4배만큼 Bilinear Interpolation을 통해서 원본 크기만큼 복원하면 DeepLabv3+가 끝납니다.

Experiments

DeepLab의 논문답게 많은 실험을 통해서 위의 결과를 생성했습니다.


첫째, Decoder에 사용하는 1x1 Conv의 채널을 몇으로할지에 대해서 48이 가장 높은 성능을 달성했습니다.

figure/Untitled%208.png


둘째, low level features로 어떤 특징을 사용할지에 대해서 striding 이전의 Conv2의 feature map에 3x3 Conv 2개를 추가로 적용한게 성능이 가장 좋았습니다. Conv2가 정확히 어디를 언급하는지는 모르겠지만, https://github.com/jfzhang95/pytorch-deeplab-xception/blob/master/modeling/backbone/xception.py 의 코드에 따르면 위의 그림에서 특징맵을 추출해서 사용했습니다.

figure/Untitled%209.png

그리고, 이때 채널은 256으로 kernel size는 3x3으로 해서 2개를 적용하는게 성능적으로 가장 좋았습니다.


셋째, 네트워크에 대해서 Encoder-Decoder실험입니다. ResNet에서 Xception으로 변경시에 85.7에서 87.8로 2.2가 상승했습니다.

image-20210923153234366


마지막으로, Decoder 부분을 적용했는지 여부에 따라서 Object의 Boundary가 많이 살아나는 것을 확인할 수 있습니다.

image-20210923153311702

Results

결과적으로 DeepLabv3+는 기존의 모델들 대비해서 SOTA 성능을 달성했습니다. 그림또한 Boundary 부분이 더 좋아진 것 또한 확인이 가능합니다.

image-20210923153410810

그래도 아직 실패한 케이스가 있다면, 맨 마지막의 줄인데, 소파의 모습이 굉장히 이상하다든지, 철창 뒤의 객체가 있어서 가린다든지, 차의 뒷 모습처럼 잘 안나오는 부분이 물에 띄어있는 것처럼 생소한 케이스들에 대해서 안되는게 확인가능합니다.

Conclusion

최근 연구들이 대부분 Encoder-Decoder의 구조를 가지는 것처럼 Deeplabv3+도 Encoder-Decoder 구조를 사용했습니다. 이때, Low level Feature를 다시 활용해서 Object Boundary 부분 또한 활용하는 모습을 보여서 이전의 Segmentation 연구들의 총집합이라는 생각이 들었습니다. 하지만, 최근의 연구들이 High Resolution을 사용하는 HRNet과 Attention을 통해서 Channel 혹은 Scale에 집중하는 연구가 많이 진행되어서, 이에 대한 아이디어를 추가하면 더 좋아지지 않을까에 대한 생각이 듭니다. Attention-to-Scale의 저자랑 같은 저자인 만큼 해당 아이디어를 바로 적용할 수 있을 것 같은데, 이에 대한 결과가 꽤 궁금했습니다. (MS의 결과가 성능적으로 많이 증가하지 않은 것을 봐서는 큰 차이가 없을 것 같지만, 그래도 궁금하네요.)


여기까지해서 본격적은 DeepLab 계열의 모든 논문을 살펴봤습니다. 다음 글에서는 Unet3+부터 시작해서 Attention을 이용한 최근 Unet 계열의 논문들에 대해서 살펴보도록 하겠습니다.