본문 바로가기

🤖AI/딥러닝

(04강) Semantic Segmentation

네이버 부스트캠프 AI Tech 2기 Level2 Ustage 6주차
1강과 3강의 Image classification은 사진이 주어졌을 때 사진 전체를 카테고리로 분류한다. 반면 Semantic Segmentation은 사진이 주어졌을 때 사진 내 각 픽셀을 카테고리로 분류하는 task이다. 즉, 하나의 사진이 아닌, 사진에 있는 모든 물체들을 분류한다는 것이다. 본 강의에서는 먼저 최초의 end-to-end segmentation 모델 FCN을 시작으로 Hypercolumn 모델을 배운다. 다음으로 segmentation의 breakthrough라고 볼 수 있는 UNet 모델에 대해 공부하고 Pytorch 코드 실습을 한다. 끝으로 최근까지 좋은 성능을 보이고 있는 DeepLab v3에 대해 배운다.

Further Reading

1.1. What is Semantic Segmantation?

  • 영상 단위가 아닌 pixel단위로 분류한다.
  • instance는 구분하지 않는다. 
  • 같은 class여도 다른 물체들을 구분하는 것은 instance segmantation으로 뒤에서 배운다.

1.2. Where can Semantic Segmentation be applied to?

  • Medical images
  • Autonomous driving (자율주행)
  • Computational photography

2.1. Fully Convolutional Netwoks (FCN)

  • semantic segmentation을 위한 첫 end-to-end 구조이다.
  • end-to-end: 입력에서부터 출력까지 모두 미분가능한 neuron network로 구성되어 있다.
  • 입력과 출력 데이터의 pair만 있으면 학습을 통해 semantic segmentation을 할 수 있다. 
  • 그전에는 사람이 만든 여러 가지 알고리즘을 결합해서 semantic segmentation을 진행해서 데이터가 많아도 학습 가능한 부분이 굉장히 제한되어 있었다.
  • 성능을 높이기 위해서 다양한 수학적인 모델을 사람의 손으로 시도해서 성능향상이 어려웠다. 
  • FCN은 입력으로 임의의 해상도를 넣을 수 있고 출력도 입력 해상도에 맞게 나올 수 있게 구성되어 있으며 중간 network가 모두 학습 가능하기 때문에 학습을 통해서 semantic segmentation문제를 바로 해결할 수 있게 되었다.
  • AlexNet의 경우에는 Convolutional Layer 뒤쪽에 flattening부분이 있어서 벡터화를 시켜놨었다.
    • 입력 해상도가 호환되지 않으면 학습된 FC layer를 사용하지 못하는 한계가 있었다.
    • 입력 해상도가 바뀌면 Convoltuional Layer의 Activation Map의 dimension이 달라지게 되고 Flattenting 하면 벡터의 길이가 달라지기 때문에 FC Layer와 호환이 되지 않게 된다.
  • FCN은 호환성이 매우 높다! 
  • Fully Connected Layer: 공간 정보를 고려하지 않고 fixed dimension vector가 주어지면 또 다른 fixed dimensional vector로 출력해 주는 구조이다. 즉, 벡터가 주어지면 multiplication이 되어서 또 다른 fixed dimension에 벡터가 나오게 되는 layer이다.
  • FCN(Fully Convolutional Networks)은 입력이 activation Map 즉, tensor이고 출력도 acitvation Map형태로 나온다. 즉, spacial coordinate를 유지한 상태로 operation이 수행되는 layer이다. 그리고 보통 1X1 Convolutional layer로 구현이 된다. 각 위치마다 classification 결과를 출력하는 map형태로 출력이 정해지게 된다.
  • activation map이 주어지면 AlexNet에서는 flattening을 통해서 긴 벡터 형태로 만들어준 뒤 fully-connected layer의 input으로 넣어주었다. 이렇게 하면 영상의 공간 정보를 고려하지 않고 하나의 벡터로 섞이게 된다. 

  • 각 위치마다 classification을 할 수 있도록 고쳐보자
  • 각 위치마다 channel 축으로 flattening을 한다. 각 위치마다 벡터가 하나씩 나온다.
  • 1x1 convolution layer와 완전히 동일하다
  • 채널 축으로 1x1 convolution 커널이 fc layer의 한 weight 칼럼이라고 볼 수 있다
  • 그래서 필터 개수만큼 통과를 시키면 각각 위치마다 fc layer를 별도로 돌려서 각각의 위치의 결과 값을 채워 넣는 것과 동일한 결과를 얻을 수 있다.
  • 1x1 convolution operation을 하기 위해선 sliding window 방식으로 weight 공유해서 적용하기 때문에 spatial information이 유지가 된다
  • 결론적으로 fully connected layer는 1 x 1 convolutional 해석과 구현이 가능하므로 fc layer를 convolution layer로 대체함으로써 어떤 입력 사이즈도 대응 가능한 fully convolutional neural network를 만들 수 있다
  • semantic segmentation 모델을 만들어서 사용하면 오히려 굉장히 작은 score map을 얻게 된다. 
  • input은 굉장히 큰데 output score는 굉장히 작은 것
  • stride와 pooling layer에 의해서 최종 activation map의 해상도는 저해상도인 경우가 많다.
  • stride나 pooling layer는 receptible size를 키워서 넓은 context를 고려하고 싶은 것
  • 저해상도를 막기 위해 Upsampling이 도입되었다.

What is Upsampling?

  • 작은 activation map을 원래 입력 사이즈에 맞춰주기 위해서 upsampling layer을 사용한다
  • stride나 pooling을 제거하면 작은 activation map을 얻지 못한다. 더 큰 고해상도의 activation map을 얻게 된다. 
  • 문제는 똑같은 수의 layer를 사용했을 때 receptible field가 굉장히 작기 때문에 영상의 전반적인 context를 파악하지 못한다. (tradeoff가 있다.) -> 일단은 작게 만들어서 receptible field를 최대한 크게 만들어놓는 게 성능에 좋다. 그 후에 강제로 Upsampling을 통해서 resolution을 맞춰준다.

Upsampling 방법

  • Transposed Convolution
  • Upsample and convolution

Transposed Convolution

  • a, b 두 개의 입력이 주어졌을 때 transposed convolution은 필터를 scaling 한 것을 해당하는 출력위치에 붙여놓는다.
  • convolution kernel size와 stride 사이즈 파라미터를 잘 조정해서 중첩이 생기지 않도록 신경 써서 튜닝해야 한다.

Upsample and convolution

  • upsample은 중첩 문제가 없고 골고루 영향을 받게 한다.
  • transposed convolution은 학습 가능한 upsampling을 하나의 layer로 한방에 처리한 것으로 볼 수 있다
  • upsampling convolution 같은 경우는 upsampling operation을 두 개로 분리한 것이다
  • 간단한 영상 처리 operation으로 많이 쓰이는 interpolation {Nearest-neighbor(NN), Bilinear} 들을 먼저 적용하고 학습 가능한 learnable upsampling으로 만들어주기 위해서 convolution layer을 적용해 준다

Back to FCN

  • 아무리 upsampling을 했다 해도 해상도가 이미 줄어든 상태에서 잃어버린 정보를 다시 살리는 일은 쉽지 않다
  • 그래서 각 layer 별로 activation map에 해상도와 의미를 살펴보면 다음과 같은 경향성이 있다.
  •  낮은 layer 쪽에서는 receptive field size가 작기 때문에 굉장히 국지적이고 작은 디테일을 보고 작은 차이에도 민감한 경향이 있다
  • 높은 layer 쪽에서는 해상도는 낮아지지만 큰 receptive field를 가지고 영상에서 전반적이고 의미론적인 정보들을 포함하는 경향을 갖고 있다
  • semantic segmentation에 필요한 건 사실 둘 모두이다
  • 왜냐하면 각 픽셀별로 의미를 파악하고 영상 전체를 바라보면서 현재 그 하나의 픽셀이 물체의 경계선 안쪽에 해당하는지 또는 밖깥쪽에 해당하는지 판별을 해야 한다.
  • 그래서 경계 부분을 디테일하게 파악해야 하기 때문에 둘 모두가 다 필요하다
  • 이 두 특징을 모두 확보하기 위해서 다음과 같이 fusion을 한다.
  •  높은 layer에 있던 activation map을 upsampling을 통해서 해상도를 크게 올리고 그에 맞춰서 다른 중간층의 activation map을 upsampling을 해서 가져온다
  • 이것을 concatenate 해서 최종 출력을 만들게 된다
  • FCN-8S가 가장 많은 activation map을 사용하는 버전이다. 이를 통해 각 픽셀마다 class의 score를 뱉어주게 된다.
  • FCN-32s : 맨 마지막 activation map만 사용한 결과
  • FCN-16s : 적당히 다른 중간 단계의 activaton map과 합친 결과
  • FCN-8s : 좀 더 많이 다른 중간 단계의 activation map과 합친 결과
  • 중간 단계의 activation map을 합치는 것이 큰 도움이 된다.
  • 정리하면 FCN은 end-to-end network로 손으로 만든 별도의 알고리즘을 도입해서 사용하지 않고 모두 neural network로 구성되어 있기에
    • GPU로 병렬처리가 가능하고 굉장히 빠르다
    • 또한 모델이 전반적으로 해당 task에 대해서 학습되기 때문에 더 좋은 성능을 발휘한다.
    • low level feature와 high level feature까지 고려한 end-to-end learning task를 통해서 경계선을 잘 따라가는 결과까지 얻을 수 있다

2.2.  Hypercolumns for object segmentation

  • 2015년에 거의 동시에 비슷한 연구가 나왔었다
  • hypercolumn이라는 논문도 FCN와 task, motivation 등 모두 동일한 연구이다
  • 다만 강조하는 포인트가 FCN과는 달리 낮은 layer와 높은 layer의 feature를 융합해서 쓰는 파트가 가장 강조됨.
    • FCN은 1x1 convolution이랑 fully convolutional layer가 강조되었다.
  • FCN의 마지막 부분과 마찬가지로 낮은 layer와 높은 layer의 특징을 해상도를 맞춰놓고 합쳐서 사용하는 것을 제시
  • end-to-end가 아니다. 다른 thrid party 알고리즘을 사용해서 각 물체의 bounding box를 먼저 추출한 뒤에 적용하는 모델로 소개되었다.

2.3.  U-Net

  • Fully-convolutional이다
  • 낮은 층의 feature와 높은 층의 feature의 특징을 더욱 잘 결합하는 방법을 skip connection을 통해서 제시했다.
  • 앞의 FCN보다 더 정교한 segmantation 결과를 얻을 수 있었다.
  • Contracting path (일반적인 CNN과 동일)
    • 먼저 입력 사진을 몇 개의 convolution layer에 통과시키고 (Repeatedly applying 3x3 convolutions)
    • pooling을 통해서 receptive field를 크게 확보하기 위해 해상도를 낮추고 채널 수를 늘린다(64  128) (Doubling the number of feature channels)
    • 위 과정을 몇 차례 반복해서 작은 activation map을 구하고 여기에 영상의 전반적인 정보가 잘 녹아있다고 가정한다 (being used to capture holistic context)
  • Expanding path (decoding이라 불리는 upsampling 부분)
    • 한 번에 upsampling 하는 대신에 점진적으로 단계별로 activation map의 해상도를 올려주고 채널 수를 절반으로 줄인다 (Repeatedly applying 2x2 convolutions and Halving the number of feature channels)
    • activation map의 해상도와 채널 수는 contracting path에서 대칭으로 대응돼서 오는 layer와 동일하게 맞춰서 낮은 층에 있었던 activation map을 합쳐서 사용할 수 있도록 만들어 준다. (Concatenating the corresponding feature maps from the contracting path)
    • channel size가 줄어들게 되지만 해상도는 늘어나는 구조
    • fusion 하는 방법으로 concatenation을 사용한다.
  • activation map의 해상도는 contracting path에서 절반씩 줄고 반대로 expanding path에서 두 배씩 늘어난다.
  • 채널 수는 두 배씩 늘어났다가 절반씩 줄어든다
  • 대칭되는 layer들은 activation map들이 concatenate 될 수 있도록 해상도와 채널이 호환성 있는 값을 가지도록 설계가 되어 있다.
  • 낮은 layer에서 전달되는 특징이 localized 정보를 준다
    • 공간적으로 높은 해상도와 입력이 약간 바뀌는 것 만으로 민감한 정보를 제공하기 때문에 경계선이나 공간적으로 중요한 정보들을 뒤쪽 layer에 바로 전달하는 중요한 역할을 한다

What if the spatial size of the feature map is an odd number?

  • 왼쪽: 7x7의 feature map을 down sampling 하면 일반적으로 버림이 돼서 3x3이 된다
  • 오른쪽 : 3x3 된 feature map을 다시 두배로 upsampling 하게 되면 7x7로 돌아가지 않고 6x6이 된다
  • 원래 입력하고 해상도 차이가 나게 된다.
  • 따라서 입력 영상을 넣을 때 중간에 어떤 layer에서도 홀수 해상도에 activation map이 나오지 않도록 유의해야 한다.

Pytorch code for U-Net

  • Contracting path
    •  
    • double_conv는 convolution layer 두 개 하고 사이에 relu activation function이 들어가서 두 번 반복된 layer를 정의
      • 두 번 반복되어서 double_conv라고 지은 거!
    • 각 contracting path에서는 double_conv 블록 한 번과 그 끝에 max pooling을 통해 해상도를 절반씩 줄이고 채널을 늘린다.
  •  
  • Expanding Path
    • upsampling을 위해서 transposed convolution이 사용된다(ConvTransposed)
    • 하이퍼파라미터를 보면 stride와 kernel_size 가 모두 2이다
      • 그래서 두 칸씩 띄면서 두 칸씩 채워 넣는 형태로 upsampling을 하게 된다
      • 이렇게 하면 중첩되는 부분이 생기지 않는다
      • kernel_size = 2는 2x2 filter size를 의미한다
    • channel size는 줄어든다

2.4 DeepLab

Conditional Random Fields (CRFs)

  • 핵심 2가지
    • CRF(conditional random field)라는 후 처리에 존재
    • dilated convolution(Atrous Convolution)이라 불리는 convolution operation의 사용
  • Conditional Random Field (CRFs)
    • 후처리에 사용되는 tool

 

Dilated convolution (Atrous Convolution)

  • convolution kernel 사이에 dilation factor 만큼 일정 공간을 넣어준다
  • 아래 오른쪽 dilation convolution 같은 경우는 weight 사이를 한 칸씩 띄어서 실제 convolution kernel 모다 더 넓은 영역을 고려할 수 있게 만든다
  • 파라미터 수는 늘어나지 않는다
  • 그래서 단순하지만 dilation layer를 몇 번 반복하는 것 만으로 receptive field의 size가 exponential 하게 증가하는 효과를 얻을 수 있다

Depthwise separable convolution (proposed by Howard et al.)

  • semantic segmentation의 입력 해상도 자체가 워낙 크기 때문에 연산이 오래 걸리는 것을 줄여보기 위해서 dilate convolution을 depthwise seperable convolution과 결합한 Atrous seperable convolution을 재현하여 사용
  • 기존 convolution layer는 하나의 activation 값을 얻기 위해서 kernel 전체가 채널 전체에 걸쳐서 내적을 해서 하나의 값을 뽑는다
  • depthwise convolution 은 이 절차를 둘로 나눈다
    • 첫 번째는 각 채널별로 convolution 해서 각 채널별로 activation map 값을 뽑고
    • 뽑힌 activation map 값들을 pointwise convolution 즉, 1x1 convolution을 통해서 하나의 값의 출력이 되도록 합쳐준다
    • 이렇게 두 개의 process로 나누면 convolution의 표현력도 어느 정도 유지가 되면서 계산량은 획기적으로 줄어든다
  • number of parameters:
    - Standard Convolution :  (총 6승)
    - Depthwise separable Convolution :  (5승+4승)
    - Depthwise separable Convolution이 order가 하나 작기 (5승 < 6승) 때문에 효율적인 계산량을 가진다

Deeplab v3+ 의 전체적인 구조

  • dilated convolution layer를 통해서 더 큰 receptive field를 가지는 CNN을 적용해서 feature map을 구한다
  • 영역별로 연관된 주변 물체 또는 배경 정보의 거리가 모두 다르므로 다양한 rate의 dilated convolution을 통해서 multi scale 을 처리할 수 있는 spatial pyramid pooling을 구현
  • 이렇게 구해진 feature map들은 하나로 concat 후에 convolution을 통해서 합쳐준다
  • 각각의 영상 내에 들어있는 물체가 여러가지 scale을 가질수 있기 때문에 이런 것들을 종합적으로 고려하기 위한 spatial pyramid pooling 이다
  • decoder라고 불리는 stage에서 낮은 레벨에서 온 low level feature 하고 pyramid pooling을 거친 feature를 upsampling한 것과 concat을 통해서 결합해준다
  • 이것을 upsampling을 통해서 segmentation map을 최종적으로 추출하는 구조이다

 

참고: https://velog.io/@babydeveloper/Semantic-segmentation

 

'🤖AI > 딥러닝' 카테고리의 다른 글

Regression task의 Loss: L1, L2, Huber, Log Cosh Loss  (0) 2024.06.26
Quickdraw dataset  (0) 2021.09.07
[딥러닝] RNN  (0) 2021.05.25
[딥러닝] CNN (Convolution Neural Network)  (0) 2021.05.15
[딥러닝] Optimization  (0) 2021.04.16