computer vision의 한 획을 그은 ResNet의 아이디어 복습하기

1. introduction

 

최초로 100개 이상 layer를 쌓으면서도 성능이 더 좋아진다는 것을 보임

 

ImageNet에서 처음으로 인간 level의 성능을 뛰어넘고 1등

 

classification뿐만 아니라 localization, object detection, segmentation 전부 1등

 

CVPR best paper 수상

 

layer의 depth가 성능에 대단히 중요하다는 것을 보였다.

 

많은 연구자들이 좌절한 부분이었는데 도대체 이것이 어떻게 가능했을까

 

혜성같이 등장한 152 layer의 괴물 모델 ResNet

 

2. degradation problem

 

기존 network에서 20 layer와 56 layer의 학습 성능을 비교함

 

기존에는 layer가 증가하면 model parameter가 증가하여 overfitting에 취약할 것이라고 생각했다

 

무슨 말이냐면 layer가 깊으면 학습은 더 잘하여 train error는 낮아지더라도

 

일반화 성능이 떨어져서 test error가 얕은 layer보다 더 크게 나올 것이라고 생각했다

 

20 layer와 56 layer의 학습 반복에 따른 train error와 test error 비교

 

두 경우 모두 error가 반복에 따라 점점 낮아지다가 어느 순간부터 정체된다

 

근데 실제 결과는 56 layer가 모든 경우에서 그냥 error가 20 layer보다 더 컸다

 

만약 overfitting의 문제라면 train error가 56 layer에서 더 작아 train data에 잘 적합되었고,

 

test error가 20 layer에서보다 더 높아 일반화 성능이 떨어져야했다.

 

ResNet 연구자들은 depth를 증가시키면 발생하는 문제는 overfittting이 아니라 degradation 문제라고 생각했다.

 

오히려 최적화 문제로 56 layer의 학습이 잘 안된 것이 문제라고 지적했다.

 

여러가지 이유가 있겠지만 layer가 깊어지면서

 

gradient vanishing 현상이나 gradient exploding 현상이 발생하여 학습이 잘 안되는 것이라고 생각했다.

 

 

3. hypothesis

 

그래서 layer가 깊어지면 원하는 목적함수 H(x)를 input X에서 바로 학습하는 것은 어려울 것이다.

 

그러므로 한번에 H(x)를 학습하지말고

 

현재 주어진 input X의 identity인 X를 제외한 나머지 residual function F(x)=H(x)-x를 학습한다면 학습 부담이 경감될 것이다.

 

H(x)가 복잡할 때 적어도 자기자신 X를 보존하려는 노력은 안해도 된다.

 

그러면 원하는 함수 H(x)는 학습한 F(x)=H(x)-x에 x를 더하면 충분하다

 

오른쪽이 residual function F(x)=H(x)-x을 학습하는 residual block

 

어떻게 더했을까?

 

layer를 더 쌓는 것이 아니라 shortcut connection 혹은 skip connection이라고 부르는 경로를 만들어서

 

X를 그대로 가져와 학습한 F(x)에 더해주어 원하는 목적함수 H(x)를 만들었다

 

backpropagation에 의하면 원래 layer와 skip connection에 모두 gradient가 흐른다

 

layer가 깊어서 vanishing현상이 일어나더라도

 

identity mapping을 하는 skip connection에는 gradient가 쉽게 흐를수 있으니까 어느 정도 학습 기회를 보장할 수 있다

 

 

 

4. residual block은 왜 성능이 좋았을까?

 

ResNet의 연구자들은 왜 성능이 좋았는지 설명을 하지 못했지만 후속 연구자들이 여러가지 연구를 했다

 

그 중 하나는 주어진 input과 output을 연결하는 residual layer의 수가 n개라면 gradient가 흐를수있는 경로가 2n이나 된다는 것

 

residual layer 수가 3개이면 오른쪽 그림처럼 gradient는 8가지 경로로 흐를 수 있다

 

여러 경로로 gradient가 흐를 수 있어서 굉장히 복잡한 함수관계까지 학습할 수 있어서 성능이 좋다는 것이다.

 

 

5. 전체구조

 

 

처음에는 7*7 convolutional layer에 He initialization을 사용했다

 

residual block을 엄청 쌓아서 일반적인 initialization을 하면 상위 layer로 갈수록 weight가 너무 커지기때문에 이것을 방지하고자 했다

 

residual block을 엄청 쌓았고 3*3 convolution만 사용했다

 

그래서 parameter가 급격하게 증가하지는 않으며 연산도 상대적으로 빠르다

 

모든 convolution 이후에는 batch normalization을 사용했다.

 

residual block의 경우 잘 보면 4개의 큰 block으로 나눌 수 있는데 각 block을 지나면 공간 크기는 절반씩 감소하며 채널 수는 2배씩 증가한다

 

잘 보면 stride 2라고 표시되어있는 곳이 큰 block의 경계

 

average pooling이후 마지막 layer로 하나의 Fully connected layer를 사용했다

 

 

6. 코드 간단 분석

 

return_resnet으로 적당히 세팅하여 원하는 resnet 불러옴

 

 

basic block을 사용하며 위에서 4개의 큰 block으로 나눴던 것이 conv2,3,4,5임

 

조금 더 들여다본다면?

 

 

layer1,layer2,layer3,layer4가 위에서 나눴던 4개의 block

 

위에서 stride=2로 나눴던거 여기서도 볼 수 있음

 

각 큰 block별로 채널 수는 64,128,256,512로 2배씩 증가

 

stride=2로 공간 해상도를 절반씩으로 감소시킴

 

make_layer 함수를 더 들여다보면

 

block 인자에 맞춰 for loop로 layer를 알아서 자동적으로 생성해줌

 

 

 

 

forward pass 결과를 주목할 필요가 있는데

 

 

softmax를 취한 값이 아니고 그냥 fully connected layer를 통과한 값을 return함

 

softmax 값을 얻고 싶으면 따로 softmax를 취해줘야함

 

참고로 adaptive average pooling이 global average pooling

TAGS.

Comments