네이버 부스트캠프 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
- Checkerboard artifacts: https://distill.pub/2016/deconv-checkerboard/
- FCN: https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Long_Fully_Convolutional_Networks_2015_CVPR_paper.pdf
- UNet: https://arxiv.org/pdf/1505.04597.pdf
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 |