본문 바로가기
BOOSTCAMP AI TECH/PStage

03-01. Object Detection / Segmentation

by 이민우 2021. 4. 26.
728x90
반응형

COCO Dataset

-일반적으로 객체 구분과 검출에 자주 사용되는 데이터 셋

-이미지에 대한 box, segment 위치를 포함한다.

-Info 에는 데이터셋에 대한 high-level의 정보가 포함된다.

-licenses 에는 이미지의 라이센스 목록이 포함된다.

-images 에는 데이터 셋의 전체 이미지 목록 및 각각의 width, height, 파일명을 포함한다.

-categories 에는 class에 해당하는 id, name 및 supercategory가 포함된다.

-annotations 에는 해당 이미지의 자세한 라벨 정보들이 포함된다.

 

 

 

 

 

mAP (mean average precision)

-AP (Average Precision)은 x를 recall, y를 predicsion으로 둔 그래프의 면적의 넓이이다.

-mAP는 AP의 평균.

 

 

 

 

 

mIOU

-합집합 대비 교집합 (Segmentation에서 사용)

-타겟과 예측의 합집합에 교집합을 나누고 이를 평균을 낸 지표

 

 

 

 

 

세그멘테이션

-Semantic의 경우 같은 종류의 객체는 하나로 취급하고, Instance Segmantation의 경우 같은 종류라도 다른 객체이면

 다른 클래스로 취급한다.

-Segmentation은 객체 탐지 및 이미지 분할 등에 사용되어, 자율주행이나 의료 분야에서 자주 활용된다.

 

 

 

 

 

 

FCN(Fully Convolution Networks)

-VGG 네트워크를 백본으로 사용하되, VGG 네트워크의 FC 레이어 3개를 Convolution으로 대체했다.

-Transposed Convolution을 활용해 Pixel Wise Prediction을 수행했다.

 

 

Fully Connected Layer vs Convolution Layer

-FC 레이어의 경우 Flatten을 수행해야 한다.

-이러한 방식은 위치가 아닌 특징만 추출하는 task에서는 잘 작동하는 방식이었다.

-하지만 Segmentation 분야에서는 각 픽셀이 어느 class에 속하는지를 분류해야 했고, 이로 인해 FC 레이어를

 Convolution으로 대체했다.

-또한 Filly Convolution Layer 사용 시 input 이미지의 사이즈에 관계 없이 파라미터의 수정이 필요가 없어진다.

-즉, 어느 이미지든 resize 없이 바로 입력이 가능한데, 이는 이전 채널의 데이터의 파라미터 수를 반드시 입력해야 하는

 Linear 레이어가 없어졌기 때문.

-그에 반해 Convolution 레이어는 커널의 파라미터에 영향을 받지만, 이미지 혹은 레이어의 크기에는 전혀 영향을

 받지 않는다.

 

 

Transposed Convolution

-기존 CNN은 컨볼루션과 풀링 과정을 거치며 이미지의 사이즈가 점점 줄어드는데, 이를 다운 샘플링이라 부른다.

-하지만 Object Detection이나 Segmentation을 위해 이미지 사이즈를 다시 늘려야 하는데, 이를 업샘플링이라 부른다.

-FCN에서는 업샘플링을 위해 Transposed Convolution을 활용한다.

-Transposed Convolution도 학습을 통해 좋은 weight의 kernel의 파라미터를 찾아가며 이미지를 복원한다.

-즉, Convolution에서 사용한 커널과 똑같은 커널을 사용하는 것이 아니라, 또다른 학습 가능한 커널을 활용하여 

 복원한다. (같은 커널 사용시 다른 값으로 복원됨)

-이러한 이미지 복원 작업을 Upsampling, Deconvolution, Tranposed Convolution이라고 한다.

-엄밀히 말해서는 Transposed Convolution이 가장 제대로 된 의미.

-Deconvolution이 가장 제대로 된 의미가 아닌 이유는 같은 커널을 사용하여 다운샘플링, 업샘플링을 하는 것이

 아니기 때문.

 

 

FCN의 상세한 구조

-VGG를 사용했기에 5개의 Conv 블록을 사용한다.

-커널 수(채널 수)는 64 - 128 - 256 - 512 - 512 이다.

-FC6, 7는 CBR을 사용하여 4096개의 특징으로 바꾸고, Dropout을 적용한다.

-Score에서는 1*1 conv를 활용해 스코어맵을 만들면서, num_class만큼의 채널을 세팅함으로써 채널 단위로

 분류를 수행한다.

-그리고 이를 UpSampling 하여 이미지를 복원한다.

 

def CBR(in_channels, out_channels, kernel_size = 3, stride = 1, padding=1) :
	return nn.Sequential(nn.Conv2d(	in_channels = in_channels,
    								out_channels = out_channels,
                                    kernel_size = kernel_size,
                                    stride = stride,
                                    padding = padding),
                         nn.ReLU(inplace = True)
                         )
                         
#conv1
self.conv1_1 = CBR(3, 64, 3, 1, 1)
self.conv1_2 = CBR(64, 64, 3, 1, 1)
self.pool1 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv2
self.conv2_1 = CBR(64, 128, 3, 1, 1)
self.conv2_2 = CBR(128, 128, 3, 1, 1)
self.pool2 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv3
self.conv3_1 = CBR(128, 256, 3, 1, 1)
self.conv3_2 = CBR(256, 256, 3, 1, 1)
self.conv3_2 = CBR(256, 256, 3, 1, 1)
self.pool3 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv4
self.conv4_1 = CBR(256, 512, 3, 1, 1)
self.conv4_2 = CBR(512, 512, 3, 1, 1)
self.conv4_2 = CBR(512, 512, 3, 1, 1)
self.pool4 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv5
self.conv5_1 = CBR(512, 512, 3, 1, 1)
self.conv5_2 = CBR(512, 512, 3, 1, 1)
self.conv5_2 = CBR(512, 512, 3, 1, 1)
self.pool5 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#FC6
slef.fc6 = CBR(512, 4096, 1, 1, 0)
slef.drop6 = nn.Dropout2d()

#FC7
slef.fc7 = CBR(4096, 4096, 1, 1, 0)
slef.drop7 = nn.Dropout2d()

#Score
self.score_fr = nn.Conv2d(4096, num_classes, 1, 1, 0)

#UPScore using deconv
self.upscore32 = nn.ConvTransposed2d(num_classes, num_classes, kernel_size = 64, stride = 32, padding = 16)

 

 

 

FCN의 성능 향상

 

1) FCN-16s

-기존의 CNN의 과정을 거치며 FCN은 디테일한 위치 정보를 소실하게 된다.

-그저 대략적인 정보만을 유추하고, 확실한 경계를 볼 수는 없다.

-이를 방지하기 위해 Stride 사이즈를 줄이며 이전의 Output Featuremap을 불러오는 Skip-connection을 활용한다.

-이전의 알고리즘은 하나의 Deconv를 사용해 32배로 키웠다면, 진화한 알고리즘은 하나의 Deconv로 2배로 키우고,

 풀링 이전의 특징맵을 가져와 결합하여 16배로 키우는 Deconv2 레이어가 있다.

-이러한 방식은 풀링에 의해 잃어버린 정보를 복원해주는 작업을 진행한다.

-또 Upsampled Size를 줄여주기에 (한 번에 32배로 키우는 게 아니라 보다 천천히 복원하기에) 좀 더 효율적인

 이미지 복원이 가능하다.

 

def CBR(in_channels, out_channels, kernel_size = 3, stride = 1, padding=1) :
	return nn.Sequential(nn.Conv2d(	in_channels = in_channels,
    								out_channels = out_channels,
                                    kernel_size = kernel_size,
                                    stride = stride,
                                    padding = padding),
                         nn.ReLU(inplace = True)
                         )
                         
#conv1
self.conv1_1 = CBR(3, 64, 3, 1, 1)
self.conv1_2 = CBR(64, 64, 3, 1, 1)
self.pool1 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv2
self.conv2_1 = CBR(64, 128, 3, 1, 1)
self.conv2_2 = CBR(128, 128, 3, 1, 1)
self.pool2 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv3
self.conv3_1 = CBR(128, 256, 3, 1, 1)
self.conv3_2 = CBR(256, 256, 3, 1, 1)
self.conv3_2 = CBR(256, 256, 3, 1, 1)
self.pool3 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#conv4
self.conv4_1 = CBR(256, 512, 3, 1, 1)
self.conv4_2 = CBR(512, 512, 3, 1, 1)
self.conv4_2 = CBR(512, 512, 3, 1, 1)
self.pool4 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2
#Score pool4 /변경
self.score_pool4_fr = nn.Conv2d(512, num_classes, kernel_size = 1, stride = 1, padding = 0)

#conv5
self.conv5_1 = CBR(512, 512, 3, 1, 1)
self.conv5_2 = CBR(512, 512, 3, 1, 1)
self.conv5_2 = CBR(512, 512, 3, 1, 1)
self.pool5 = nn.MaxPool2d(2, stride = 2, cell_mode = True) #1/2

#FC6
slef.fc6 = CBR(512, 4096, 1, 1, 0)
slef.drop6 = nn.Dropout2d()

#FC7
slef.fc7 = CBR(4096, 4096, 1, 1, 0)
slef.drop7 = nn.Dropout2d()

#Score
self.score_fr = nn.Conv2d(4096, num_classes, 1, 1, 0)

#UPScore using deconv /변경
self.upscore2 = nn.ConvTransposed2d(num_classes, num_classes, kernel_size = 4, stride = 2, padding = 1)

#이제 forward에서
#h = upscore2의 결과값 + score_pool4_fr의 결과값을 한 후

self.upscore16 = nn.ConvTransposed2d(num_classes, num_classes, kernel_size = 32, stride = 16, padding = 8)

 

2) FCN-8s

-풀링 4의 결과 뿐 아니라 풀링 3의 결과도 가져와 컨볼루션한다.

 

 

 

 

 

 

 

 

 

FCN의 한계점

-객체의 크기가 크거나 작은 경우 예측을 잘 수행하지 못했다.

-큰 객체의 경우 지역적인 정보만으로 예측하는데, 버스의 유리창에 비친 자전거를 보고

 버스를 자전거로 인식하기도 함. 이로 인해 큰 객체의 경우 같은 객체여도 다른 라벨링이 일어날 수 있음.

-반대로 객체의 크기가 작으면 무시하는 경우도 있음.

-Deconvolution의 절차가 너무 간단하여 객체의 디테일한 모습이 사라지는 문제도 있음.

 

 

 

Decoder를 개선한 모델

-FCN의 문제를 개선하기 위해 인코더-디코더 구조로 바꾸어 연구를 진행

 

1) DeconvNet

-디코더를 인코더와 대칭으로 만들었다.

-컨볼루션 네트워크는 VGG16을 만들었다.

-디컨볼루션 네트워크는 업샘플링, 디컨볼루션, ReLU로 이루어져있다.

-Unpooling은 아래와 같이 풀링한 결과를 복원하는 과정

-풀링은 노이즈를 제거하지만 그 과정에서 정보가 손실된다.

-언풀링을 통해 풀링 시 지워진 경계에 정보를 기록했다가 복원.

-학습이 필요없기에 속도가 빠르나, sparse한 activation map이 생성되기에 이를 채워줘야 하고, 이를 위해 Transposed

 Convolution을 수행해야 한다.

-Deconvolution Network의 Activation map을 보면 층과 풀링 방법에 따른 특징이 있다. 낮은 층은 전반적인 특징,

 깊은 층은 복잡한 패턴을 잡아낸다.

-그래서 Unpooling의 경우 example-specific한 구조, 즉 자세한 구조를 잡아낸다.

-그리고 Transposed Conv의 경우 "class-specific"한 구조를 잡아낸다. 즉, 빈 부분을 채워넣는다.

-둘을 병행할 경우 활성화 맵이 더 디테일해진다.

 

 

2) SegNet

출처 : V. Badrinarayanan, A. Kendall and R. Cipolla, "SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation," in IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 39, no. 12, pp. 2481-2495, 1 Dec. 2017, doi: 10.1109/TPAMI.2016.2644615.

-Road Scene Understanding applications라는 분야에서 Semantic Segmentation을 수행하기 위해 모델이 필요한

 능력에 대한 고민

-자율 주행에 있어 중요한 것은 클래스들을 빠르고 정확하게 분류하는 작업이었다.

-VGG16의 13개 층을 인코더로 사용하고, 뒤집어서 디코더로 사용했다.

-FC 레이어를 모두 제거했고, 디코더 파트에서 Convolution을 사용했다.

-인코더는 Pretrained된 네트워크 사용.

 

 

 

 

 

Skip Connection을 적용한 모델

-Skip Connection은 ResNet에서 나온 개념으로, input과 output을 연결하여 더하는 테크닉.

-이전 레이어의 output을 입력으로 제공함으로써 깊은 레이어에서 성능을 좋게 만들어줌.

-DenseNet은 같은 DenseBlock 내에서 이전의 모든 레이어의 output을 가져온다.

 

1) FC DenseNet

출처 : Simon jegou Michal Drozdzal, David Vazquez, Adriana Romero, Yoshua Bengio, “The One Hundred Layers Tiramisu: Fully Convolutional DenseNets for Semantic Segmentation”

-FC DenseNet은 이러한 DenseNet의 Skip Connection을 빌려왔다.

-Block 내부에서는 DenseNet의 Skip Connection을 수행하고, Block 사이에서는 ResNet의 Skip Connection을 수행한다.

 

2) Unet

출처 : O. Ronneberger, P. Fischer, and T. Brox. U-net: Convolutional networks for biomedical image segmentation. In MICCAI, pages 234–241. Springer, 2015”

-가장 큰 특징은 인코더를 통과하는 특징맵의 결과를 같은 레벨 층의 디코더의 output과 concat (총 4회)

 

 

 

 

Receptive Field를 확장시킨 모델

출처 : Peng, C., Zhang, X., Yu, G., Luo, G., Sun, J.: Large kernel matters–improve semantic segmentation by global convolutional network. In: CVPR. (2017)

-Receptive Field란 뉴런이 얼마만큼을 바라보고 있는지, 즉 얼마만큼의 영역을 바라보고 있는지를 의미한다.

-Receptive Field가 객체에 대한 정보를 다 포함하지 못하면 예측 정확도가 낮아질 수 있다.

-즉, Receptive Field는 객체의 일부가 아닌 전체를 보고있어야 한다. (위의 경우 B < C)

-Conv → Max pooling → Conv 반복하면, 효율적으로 receptive field를 넓힐 수 있음

-그러나, Resolution 측면에서는 low feature resolution 을 가지는 문제점 발생

-그래서 이미지의 크기 자체를 너무 줄이지 않고, 파라미터의 수도 변함이 없는 채로 Receptive Field만 넓게 하는 방식이

 필요해짐.

 

1) DeepLab V1

출처 : A technical report on convolution arithmetic in the context of deep learning (https://github.com/vdumoulin/conv_arithmetic) (MIT License)

-위의 테크닉이 바로 Dialated Convolution이다.

-이미지의 크기를 적게 줄이면서도 효율적인 receptive field를 넓히는 방법.

-Dilated Convolution & downsampling 시 파라미터를 줄이며 Receptive Field를 넓힐 수 있다.

-커널이 적용되는 넓이를 넓히며, 나머지에는 0을 채운다.

-이러한 개념을 처음으로 도입한 것이 DeepLab V1

-2*2가 아닌 3*3 Max풀링 사용, 마지막 풀링은 평균풀링 사용.

-마지막 UpSampling은 Bilinear Upsampling인데, 이웃 좌표들의 값을 각 좌표에서 거리를 기반으로 채워넣는 방법

 

 

2) DialatedNet

-DeepLab v1과 비슷한 구조이나 보다 Dialated Convolution을 효율적으로 사용하는 방식.

-DialatedNet은 2*2 맥스 풀링 사용, 두 개의 맥스풀링(평균풀링) 제외로 맥스풀링으로 인한 정보 손실 방지.

 그리고 rate을 4로 주고, Deconv 사용

 

3) DeepLab v2

출처 : L. Chen, G. Papandreou, I. Kokkinos, K. Murphy and A. L. Yuille, "DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs," in IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 40, no. 4, pp. 834-848, 1 April 2018, doi: 10.1109/TPAMI.2017.2699184.

-DeepLab v1의 앞부분은 동일하나 FC 레이어를 변경함.

-브랜치를 뻗어 네 갈래로 만들었는데, 이를 ASPP라고 명명함.

-이렇게 네 개의 각자 다른 dilate rate를 다르게 주어 1*1 conv를 거친 후 합쳐 BiLinear Interpolation 수행

 

4) PSPNet

-Receptive Field를 넓히는 데 이전과 다른 방법 사용

-도입 배경은

 1) Mismatched Relationship : 모델이 외관만 보고 물체를 판단

 2) Confusion Categories : 비슷한 카테고리를 헷갈려함

 3) Inconspicuous Classes : 크기가 작아 잘 보이지 않는 객체를 헷갈려함

-이러한 문제점들은 주변의 특징들을 동시에 파악하면 충분히 제대로 된 예측이 가능해진다.

-또 다른 도입 배경은 왜 FCN은 MaxPool에 의해 줄였는데 Receptive Field가 넓혀지지 않을까?

출처 : B. Zhou, A. Khosla, A. Lapedriza, A. Oliva, and A. Torralba. Object detectors emerge in deep scene cnns. arXiv:1412.6856, 2014

-이러한 점은 2014년에 나온 논문에서 파악할 수 있는데, 이론적인 Receptive Field와 실제는 다르기 때문.

-PSPNet은 이러한 문제를 해결하기 위해 Dialated Conv가 아닌 Global Average Pooling을 도입했다.

출처 : Zhao, H., Shi, J., Qi, X., Wang, X., Jia, J.: Pyramid scene parsing network. In: CVPR. (2017)

-Global Average Pooling은 주변 정보를 토대로 객체를 인식할 때 활용되는 방식이다.

 

5) DeepLab v3

출처 : Liang-Chieh Chen, George Papandreou, Florian Schroff, and Hartwig Adam. Rethinking atrous convolution for semantic image segmentation. CoRR, abs/1706.05587, 2017.

-Global Average Pooling을 사용한 버전

-ASPP 부분에서 Global Average Pooling이 추가되었다.

 

 

 

 

 

 

U-Net

출처 : O. Ronneberger, P. Fischer, and T. Brox. U-net: Convolutional networks for biomedical image segmentation. In MICCAI, pages 234–241. Springer, 2015

-바이오, 의료 쪽에 포커싱이 맞춰진 모델이나, 성능이 좋아 여러 Segmentation 분야에서 사용되었다.

-의료 쪽의 데이터의 문제점은, 데이터의 수가 부족한 것이다. 라벨링을 일반인이 하는 것이 불가능하기 때문.

-또한 데이터들에 개인 정보가 포함되어 있어 데이터 수가 부족할 수 밖에 없다.

-두 번째 문제는 데이터의 인스턴스의 경계를 테두리로 만들어야하는 작업이 필요했다.

-U-Net은 U자 형태의 네트워크를 구성하고 있다.

-왼쪽의 인코더는 Contracting Path라 부르며, 입력 이미지의 전반적인 특징을 추출하며 다운샘플링 한다.

-오른쪽의 디코더는 Expanding Path라고 하며, 업샘플링을 수행하여 Segmentation을 수행한다.

-제로 패딩을 사용하지 않아 특징맵의 크기가 계속해서 감소한다.

-채널이 인코더에서는 두 배씩 감소, 디코더에서는 두 배씩 증가하며, 같은 레벨의 인코더 층의 출력을

 디코더에서 Concat 하는 Skip connection을 활용함으로써 이전 레이어의 정보를 효과적으로 활용.

-인코더에서는 3*3 conv + BN + ReLU 작업을 두 번 수행 => 2*2 맥스풀링 (절반 감소)

-디코더에서는 2*2 업컨벌루션 => Concat => 3*3 conv + BN + ReLU 두 번 수행

-마지막에는 1*1 conv로 output channels 수 설정

-유넷은 인코더가 확장함에 따라 채널의 수를 1024까지 증가시켜 좀 더 고차원에서 정보를 매핑한다.

-각기 다른 계층의 인코더의 출력을 디코더와 결합시켜 이전 레이어의 정보를 효율적으로 활용한다.

 

 

U-Net의 테크닉

1) Data Augmentation

-데이터 부족 현상을 해결

 

1-1) Random Elastic Deformations를 통해 증강 수행

출처 : O. Ronneberger, P. Fischer, and T. Brox. U-net: Convolutional networks for biomedical image segmentation. In MICCAI, pages 234–241. Springer, 2015

-RED는 데이터에 외부적인 압력을 가하여 변형시키는 방법.

-바이오, 의료에서는 같은 종류의 세포라도 사람에 따라 다를 수 있음. 그렇기에 세포의 모양에 관계 없이

 같은 세포임을 파악할 수 있도록 하기 위해 사용했다.

-용어로 설명하면 모델이 invariance와 robustness를 학습할 수 있도록 하는 방법

 

1-2) Sliding Window

출처 : O. Ronneberger, P. Fischer, and T. Brox. U-net: Convolutional networks for biomedical image segmentation. In MICCAI, pages 234–241. Springer, 2015

-윈도우가 이미지를 훑으며 이미지의 부분을 사용.

-쉽게 하나의 이미지를 여러 이미지로 늘릴 수 있으나, 몇몇 이미지에는 배경만 존재하고, 전체가 아닌 부분적인

 정보만 가지고 모델을 학습할 수 있고, 특정 이미지에서 이전의 이미지와 겹치는 영역이 존재한다는 문제가 있다.

-유넷에서는 이미지가 겹치지 않도록 slice 수행.

 

2) Weight map

출처 : O. Ronneberger, P. Fischer, and T. Brox. U-net: Convolutional networks for biomedical image segmentation. In MICCAI, pages 234–241. Springer, 2015

-두 번째 단점인 데이터의 인스턴스의 경계를 구분하기 위한 테크닉

-즉 인접 셀을 구분하기 위한 테크닉

-Pixel-wise loss weight을 계산하기 위한 Weight map 생성

 

 

U-Net의 한계

-기본적으로 깊이가 4로 고정되는데, 데이터셋마다 최고의 성능을 보장하지 못한다.

-Skip Connection이 너무 단순하다.

-이러한 한계 극복을 위해 U-Net++가 등장했다.

 

 

 

 

U-Net++

출처 : Z. Zhou, M. M. R. Siddiquee, N. Tajbakhsh, and J. Liang, “UNet++: A nested U-net architecture for medical image segmentation,” in Deep Learning in Medical Image Analysis and Multimodal Learning for Clinical Decision Support. Berlin, Germany: Springer, 2018, pp. 3–11.

-U-Net의 한계 극복을 위해 새로운 형태의 구조를 제시했다.

-인코더를 공유하는 다양한 깊이(1~4)의 U-Net을 생성하고, Skip Connection을 동일한 깊이에서의 특징맵이

 모두 결합되도록 유연한 특징맵을 생성했다.

-U-Net의 최종 결과는 depth 1~4를 모두 앙상블하는 효과가 있다.

-또한 Loss를 Pixel wise Cross Entropy와 Soft Dice Coefficient를 앙상블한 로스를 사용한다.

-이러한 Loss를 X(0,1)에 1*1 conv를 한 후 softmax를 통해 probablity를 계산하고, x(0,2)에서도 계산하는 식으로

 이어나간다. 그리고 이 Loss들을 평균을 내서 사용하는데, 이를 Deep Supervision 이라고 부른다.

출처 : Z. Zhou, M. M. R. Siddiquee, N. Tajbakhsh, and J. Liang, “UNet++: A nested U-net architecture for medical image segmentation,” in Deep Learning in Medical Image Analysis and Multimodal Learning for Clinical Decision Support. Berlin, Germany: Springer, 2018, pp. 3–11.

-U-Net++의 한계는 너무 복잡한 커넥션으로 파라미터가 증가하고, 메모리가 증가했다는 점이다.

 또한 인코더-디코더 사이에서 Connection이 동일한 크기를 갖는 특징맵에서만 진행되어

 Full Scale에서 충분한 정보를 탐색하지 못해 위치와 경계를 명시적으로 학습하지 못한다.

-이러한 단점 극복을 위해 U-Net3+가 등장했다.

 

 

U-Net 3+

출처 : H. Huang et al., "UNet 3+: A Full-Scale Connected UNet for Medical Image Segmentation," in ICASSP 2020-2020 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), 2020: IEEE, pp. 1055-1059.

-디코더에서 특징맵을 결합하는 방법을 조금 복잡하게 변경했다.

-인코더 레이어로부터 같은 스케일의 인코더 레이어로부터 직접 특징맵을 받고,

 더 작은 스케일의 low-level 특징맵도 받아 풍부한 공간 정보를 통해 경계를 강조한다.

 더 큰 스케일의 high-level 특징맵도 받아 위치 정보를 구현한다.

-이를 Full-scale Skip Connection이라고 한다.

 

U-Net 3+의 Techniques

1) Classification-guided Module (CGM)

출처 : H. Huang et al., "UNet 3+: A Full-Scale Connected UNet for Medical Image Segmentation," in ICASSP 2020-2020 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), 2020: IEEE, pp. 1055-1059.

-낮은 레벨의 레이어에 있는 배경의 노이즈가 발생하여 false-positive 문제가 발생

-그래서 정확도 향상을 위해 extra classificaion task 수행

-높은 레벨의 특징맵을 사용.

-Dropout => 1*1 conv => AdaptiveMaxPool => Sigmoid 를 통과한 결과에

 argmax를 통해 Organ이 있으면 1, 없으면 0을 출력하여 나온 결과와 각 low-layer마다 나온 결과를 곱셈.

-즉 출력값을 디코더의 값에 곱해줌으로써 loss term 계산

 

2) Full-scale Deep Supervision (Loss Function)

출처 : H. Huang et al., "UNet 3+: A Full-Scale Connected UNet for Medical Image Segmentation," in ICASSP 2020-2020 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), 2020: IEEE, pp. 1055-1059.

-순서대로 Focal Loss : 클래스의 불균형 해소

-ms-simm Loss : 경계 인식 강화

-IoU : 픽셀의 분류 정확도 상승

 

 

U-Net의 버전들

1) Residual U-Net

출처 : Z. Zhang, Q. Liu and Y. Wang, "Road Extraction by Deep Residual U-Net," in IEEE Geoscience and Remote Sensing Letters, vol. 15, no. 5, pp. 749-753, May 2018, doi: 10.1109/LGRS.2018.2802944.

-Encoder 및 Decoder 부분의 block마다 residual unit with identity mapping 적용

 

2) Mobile-U-Net

출처 : Jing, J.; Wang, Z.; Matthias, R.; Zhang, H. Mobile-Unet: An efficient convolutional neural network for fabric defect detection. Text. Res. J. 2020.

-어플리케이션의 속도 강화를 위한 MobileNet을 백본으로 사용.

 

3) Eff-U-Net

출처 : B. Baheti, S. Innani, S. Gajre, S. Talbar Eff-unet: A novel architecture for semantic segmentation in unstructured environment The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR) Workshops (2020)

-EfficientNet을 백본으로 사용.

 

 

 

 

DataLoader

-dataset : 로드할 데이터셋

-batch_size : 배치 사이즈

-shuffle : 모든 Epoch의 데이터를 섞을 지

-num_workers : 로드에 사용할 프로세스 수 => 0은 기본 프로세스 => 윈도우는 0, 리눅스는 크게 맞추는 게 좋음

-collate_fn : sample의 list를 merge하여 텐서의 minibatch 구성

 

 

Segmeantation_models_pytorch

-다양한 segmentation 모델 불러오기가 가능하고, 백본 교체도 쉬움

-smp.readthedocs.io/en/latest/index.html

 

 

 

Validation

Validation이 중요한 이유

1) 제출을 하지 않더라도 모델의 성능을 평가할 수 있다.

2) Public 리더보드의 성능에 오버피팅 되지 않도록 돕는다.

 

Hold Out

-고정된 비율로 데이터 셋을 Train-Valid로 나누는 방법.

-빠른 속도로 모델이 검증하다는 장점이 있으나, 20%의 데이터를 사용할 수가 없다.

 

K-Fold

-기본적으로 고정된 비율로 데이터 셋을 나누는 방법은 홀드 아웃과 같으나, 모든 데이터를 학습에 활용할

 수 있다.

-K가 5라면 다섯 개의 모델을 만들고, 이 모델들을 앙상블하여 최종 결과를 출력한다.

-장점으로는 모든 데이터 셋을 학습에 참여시킬 수 있고, 전체 데이터셋에 대해 검증을 진행하여

 신뢰성 있는 검증 결과를 만들 수 있다.

-또한 앙상블 효과로 인해 대부분의 경우 모델의 성능이 향상된다.

-하지만 홀드아웃 방식에 비해 K배의 시간이 소요되고, k의 선택에 대한 문제도 존재한다.

 K의 선택에 따라 성능과 시간이 달라질 수 있기 때문.

-또한 데이터셋이 나누어지는 것이 랜덤성에 의존하기 때문에 편향된 데이터 셋으로 학습이 진행될 수 있다.

 

Stratified K-Fold

-Class 분포를 고려하지 못하는 k-fold 방식을 개선한 방법.

-폴드마다 클래스 분포를 동일하게 하여 split 하는 방식으로, 클래스가 불균형한 상황에 좋다.

 

Group K-Fold

-아예 특정 클래스만 검증 셋으로 만들어버리는 방법.

 

 

 

 

 

Augmentation

-데이터 수의 증가, 일반화 성능 강화, 성능 향상, 클래스 분균형 해소 등을 위해 사용된다.

-Torchvision.transforms에 다양한 Augmentation이 있고,

 Albumentation에서도 가능한데, Albumentation에는 분류, 객체 검출, 시멘틱 세그멘테이션 등 다양한

 분야에 적용이 가능하다. 또한 다양한 라이브러리를 기반으로 최적화 하여 속도가 빠르다.

 

Kaggle에서 자주 사용되는 Augmentation

1) Cutout

출처 : DeVries, Terrance, and Graham W.Taylor “improved regularization of convolutional neural networks with cutout”

-Cutout의 경우 렌덤하게 박스를 생성하기에 사진마다 성능의 편차가 존재한다.

-즉, 객체를 전부 가려버릴 수도 있고, 배경만 가려 성능에 별로 도움이 되지 않을 수 있다.

-이러한 문제의 해결을 위해 Gridmask 기법이 등장했다.

 

2) Gridmask

출처 :Pengguang Chen, et al., “GridMask Data Augmentation”

-규칙성 있는 박스를 통해 Cutout하는 방안을 제시했다.

 

3) Cutmix

-여러 가지 이미지를 합성시킨 것.

-굳이 밑에 처럼 구현할 필요는 없고,

  from cutmix.cutmix import CutMix

  from cutmix.utils import CutMixCrossEntropyLoss

 를 불러와 사용해도 좋음.

def rand_bbox(size, lam) :
  # 1. 랜덤하게 잘릴 박스 추출
  H = size[2]
  W = size[3]
  cut_rat = np.sqrt(1, -lam)
  cut_w = np.int(W * cut_rat)
  cut_h = np.int(H * cut_rat)

  # 2. 박스의 위치 결정
  cx = np.random.randint(W)
  cy = np.random.randint(H)

  bbx1 = np.clip(cx - cut_w // 2, 0, W)
  bby1 = np.clip(cy - cut_h // 2, 0, H)
  bbx2 = np.clip(cx + cut_w // 2, 0, W)
  bby2 = np.clip(cy + cut_h // 2, 0, H)

  return bbx1, bby1, bbx2, bby2

# 3. Input 이미지들의 순서를 섞고 박스의 크기를 결정할 람다 추출
lam = np.random.bera(beta, beta)
rand_index = torch.randperm(input.size()[0]).cuda()
target_a = target
target_b = target[rand_index]
bbx1, bby1, bbx2, bby2 = rand_bbox(input.size(), lam)
input[:, :, bbx1:bbx2, bby1:bby2] = input[rand_index, : , bbx1:bbx2, bby1:bby2]

lab = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (input.size()[-1] * input.size()[-2]))
output = model(input)
loss = criterion(output, target_a) * lam + criterion(output, target_b)

 

4) SnapMix

출처 : Shaoli huang, Xinchao Wang, Dacheng Tao, “SnapMix: Semantically Proportional Mixing for Augmenting Fine-grained Data"

-CAM(Class Activation Map)을 이용해 이미지 및 라벨을 합치는 방법

-영역 크기만을 고려해 라벨을 생성했던 cutmix와 달리 영역의 의미적 중요도를 고려해 라벨을 생성한다.

 

 

 

 

 

HRModel

출처 : Ke Sun et al., “High-Resolution Representations for Labeling Pixels and Regions"

 

 

 

 

LR_Scheduler

-lr이 고정되었을 때, lr이 너무 작으면 학습 시간이 오래 걸리고 Local Optima에 빠질 위험이 있다.

-하지만 너무 크다면 loss가 발산할 수 있다.

-그렇기 때문에 lr을 확정하지 못한 상황에서는, 하나의 lr을 사용하는 것보다 좀 다양하게 사용할 필요가 있다.

-다양하게 사용하면 빠른 속도로 수렴이 가능하고, 높은 정확도를 가지게 된다.

 

1) CosineAnnealingLR

-lr의 최대값과 최소값을 정해 그 범위의 학습률을 코사인 함수의 형태로 스케줄링하는 방법.

-lr이 급격하게 증가되었다 감소되기 때문에 saddle point, 정체 구간을 빠르게 탈출할 수 있다.

 

2) ReduceLROnPlateau

-metric의 성능이 향상되지 않을 때 learning rate를 조절하는 방법.

-local minima에 빠졌을 때 lr을 조절하여 효과적으로 빠져나올 수 있다.

 

3) Gradual Warmup

https://github.com/ildoonet/pytorch-gradual-warmup-lr

-학습을 시작할 때 마우 작은 lr로 출발해서 특정 값에 도달할 때까지 lr을 서서히 증가시킨다.

-이 방식을 사용하면 weight이 불안정한 초반에도 비교적 안정적으로 학습 수행이 가능하다.

-백본 네트워크 사용 시 weight가 망가지는 것을 방지할 수 있다.

 

 

 

 

Batch_size

-배치 사이즈가 크면 더 빠른 학습이 가능하고, 다양한 데이터를 한 번에 학습할 수 있어

 일반화 성능이 좋아진다.

 

1) Gradient Accumulation

-모델의 weight를 배치마다 업데이트하지 않고, 일정 step만큼 gradient를 누적한 다음 누적된 gradient를

 사용해 weight를 업데이트

-이 방법은 배치 사이즈를 키울 수 있는 장점이 있다.

 

2) Mixed-Precision Training of Deep Neural Networks

출처 : https://github.com/znxlwm/pytorch-apex-experiment

-웨이트의 소수점 자리를 32에서 16으로 대체하여 배치를 키우는 방법

 

 

 

 

Optimizer

-보통 Adam을 많이 사용하지만 조금이라도 성능 향상을 위해서라면 보다 최신 최적화기를 사용하는 것이 좋음.

-AdamW, AdamP, Radam 등

 

1) Lookahead optimizer

-Adam이나 SGD를 통해 K 번 업데이트 후 처음 시작했던 방향으로 1 step back 후 그 지점에서 다시 k번 업데이트

-Adam이나 SGD로 빠져나오기 힘든 Local minima를 빠져나올 수 있다.

 

 

 

Ensemble

1) Epoch Ensemble : epoch마다 모델을 저장한 후 마지막부터 N개의 모델을 이용해 앙상블

2) SWA : 각 step마다 weight를 업데이트 시키는 SGD와 달리 일정 주기마다 weight를 평균내는 방법.

3) Seed Ensemble : 랜덤 요소를 결정하는 시드를 바꿔가며 여러 모델을 학습시킨 후 앙상블 하는 방법

4) Resize Ensemble : 입력 이미지의 크기를 다르게 학습해 앙상블하는 방법

                            출력 이미지에 대해서도 가능하다.

5) TTA (Test time augmentation) : 테스트 셋으로 성능 테스트 시 augmentation을 수행하는 방법.

 

 

 

 

Pseudo Labeling

-라벨이 없는 데이터에 라벨을 붙여 학습에 활용하는 방법

 

1) 모델을 학습시킨다.

2) 성능이 가장 좋은 모델에 대해 Test 데이터셋에 대한 예측을 진행한다.

   *이 때 Softmax를 취한 확률값이나, Softmax 이전의 값, torch.max를 취하기 전의 값을 예측해야 한다.

   *Test 데이터셋은 Model1의 예측값이 threshold(예 : 0.9) 인 것을 사용한다.

3) 2단계에서 예측한 test 데이터셋을 활용해 재학습 진행.

4) 3단계를 학습한 모델로 test 데이터셋을 예측

728x90
반응형

'BOOSTCAMP AI TECH > PStage' 카테고리의 다른 글

03-03. Object Detection  (0) 2021.05.10
03-02. MRC (Machine Reading Comprehension, 기계독해)  (0) 2021.04.26
02-02. Tabular  (0) 2021.04.24
02-01. KLUE  (0) 2021.04.24
01. Computer Vision  (0) 2021.04.24