본문 바로가기

Study doc./Deep Learning

[cs231n] CNN Architecture

지금까지 CNN의 전체적인 프로세스와 그 속에 있는 layer들을 자세히 공부했습니다.

convolutional layer를 지나고 batch normalization를 지나고 다시 conv layer를 지나고,, 이렇게 층을 쌓아 마지막에 FC layer를 통해 score를 냅니다.

 

이제는 conv layer를 어떤  filter size로 언제 몇번 할지, 

batch normalization을 얼마나 언제 할지, 

drop out 을 할지, pooling 을 할지,

learning rate는 얼마로 할지 등을 고려해서 CNN의 전체 구조를 세워야 합니다.

 

하지만 저희는 아직 딥러닝 초보자 입니다.

성능 좋은 구조를 처음부터 끝까지 뚝딱뚝딱 만들기가 현실적으로 불가능하죠.

따라서 사람들에게 널리 알려진, 이미 잘 만들어진 구조들을 먼저 공부하겠습니다.

 

오늘 포스팅의 핵심은 아이디어 입니다.

모델을 만든 사람이 왜 이렇게 구조화 했는지, 어떤 아이디어를 적용했는지에 집중해서 따라와주세요.

그럼 시작해볼까요?


순서

  1. AlexNet
    1. 구조
    2. 핵심 아이디어 및 특징
  2. VGGNet
    1. 구조
    2. 핵심 아이디어 및 특징
  3. GoogleNet
    1. 구조
    2. 핵심 아이디어 및 특징
  4. ResNet
    1. 구조
    2. 핵심 아이디어 및 특징
  5. 정리

 


 

1. AlexNet

1-1. 구조

AlexNet의 기본 구조는 다음과 같습니다.

총 8개의 layer로 이루어져 있습니다(conv 5개 + FC 3개, 학습하는 layer만 취급).

 

 

1-2. 핵심 아이디어 및 특징

1) 핵심아이디어 : 최초의 large scale CNN, 특별한 아이디어 없음

 

2) 특징

    - 당시(2012년) GPU메모리 크기 제한으로 모델링을 두 부분으로 나뉘어서 진행함

      (Conv3, FC6,7,8 layer에서는 GPU가 공유됨)

    - activation function : ReLU 사용

    - loss 함수 : softmax 사용

    - regularization : dropout, data augmentation 사용

    - normalization : Local response normalization 사용 (요즘은 사용하지 않는 방법)

    - test 단계에서 앙상블 사용

    - FC layer의 사용으로 파라미터 수 많음 (ex. FC6 : 6*6*256*4096 개의 파라미터 존재) 

 

 

+ 추가) ZFNet

단순히 AlexNet 의 파라미터를 조절하여 성능을 높인 구조

 


 

* 층이 깊어지기 시작함

* Batch Normalization이 발명되기 이전이기 때문에 층이 깊어졌을때의 문제를 해결하기 위한 다양한 기술이 필요했음

* GoogleNet의 경우 보조 분류기를 사용하는데, BN이 사용되면 굳이 필요하지 않음

 

2. VGGNet

2-1. 구조

VGGNet의 기본구조는 다음과 같습니다.

총 16~19개의 layer로 구성되어 있습니다(conv 13개 + FC 3개/ conv 16개 + FC 3개).

 

 

2-2. 핵심 아이디어 및 특징

1) 핵심아이디어 : 더 작은 필터(3*3) 사용

 

2) 특징

    - 작은 size의 필터를 사용함으로써 파라미터 수가 감소하고, 이에 따라 layer를 더 많이 쌓을 수 있음

    - VGGNet19가 16보다 성능이 아주 조금 좋지만, 메모리를 더 많이 소모하기 때문에 보통 VGG16 사용

    - test 단계에서 앙상블 사용


 

3. GoogleNet

3-1. 구조

GoogleNet의 기본 구조는 다음과 같습니다.

처음에는 기존과 동일하게 conv layer와 pooling layer로 구성된 단계를 지납니다.

그리고 GoogleNet의 핵심 아이디어인 inception module이 여러개(9개) 쌓여진 단계를 거친 후,

마지막으로 score 를 냅니다(GoogleNet에서는 FC layer가 없음).

 

FC layer 를 없앤 이유는 파라미터 수를 줄이고 층을 깊게 쌓기 위함인데, 

층을 깊게 쌓을수록 gradient 가 작아져서 사라지는 문제가 발생했습니다.

이를 해결하기 위해 보조 분류기를 사용하여 중간중간에서도 output를 출력해줍니다.

자세한 내용은 아래에서 더 설명하고, 지금은 전체 구조를 파악합시다.

 

 

3-2. 핵심 아이디어 및 특징

1) 핵심아이디어 : 높은 계산량을 효율적으로 하는 것에 중점 -> Inception module의 사용

 

+ inception module이란?

다양한 크기의 필터로 convoluntion을 병렬적으로 진행한 후, depth 방향으로 모두 합쳐버리는 개념입니다.

다양한 필터를 이용해서 다양한 특징을 추출하고 싶었던 거죠!

초기의 모양은 아래 그림과 같습니다.

 

 

1*1, 3*3, 5*5 필터를 이용한 conv layer 와 3*3 max pooling layer에서 나온 결과를 모두 depth 방향으로 합친 것을 output으로 내보냅니다(28*28이 변하지 않는 것은 필터의 크기에 따라 자동으로 stride를 조절하여 크기를 유지하기 때문).

하지만 이렇게 했을때 depth가 엄청 커지는 단점이 생기는데 아래 예시를 보겠습니다.

 

 

각 layer 의 필터 개수를 다음과 같이 지정했을때 최종 depth가 무려 672가 됐습니다.

이렇게 되면 파라미터 수가 엄청나게 늘어나면서 연산량도 많아지게 되겠죠?!

 

예를 들어 3*3 conv layer의 연산량을 계산해보면

3*3의 필터 하나가 한 번의 conv를 수행하기 위해서는 3*3*256의 연산량이 필요합니다.

그렇다면 하나의 필터가 전체 면적에서 conv를 수행하려면 3*3*256*28*28 만큼의 연산량이 필요하겠죠.

그리고 총 192개의 필터로 가정했으니 최종적으로 3*3*256*28*28*192 의 연산량이 요구됩니다.

하나의 Inception module에 이런게 4개나 있으니 연산량이 엄청나겠죠??

그래서 생각한게 bottleneck layer, 즉 1*1 conv layer 입니다.

 

 

bottleneck layer는 input의 depth를 조절할 수 있기 때문에 계산의 복잡도를 조절(Dimension Reduction)할 수 있습니다.

위 그림에서 보듯 단순히 필터의 개수로 output의 depth가 결정되듯이 말이죠!

따라서 아래 그림과 같이 3*3, 5*5 conv layer로 들어가기 전과 3*3 pooling layer를 지난 후에 bottleneck layer를 설치하여 연산량을 줄여줍니다.

 

 

얼마나 줄어들었나 계산을 해보니 854M 에서 358M으로 반 이상 감소했음을 알 수 있습니다.

게다가 ouput의 depth 역시 많이 줄어들었죠!

 

 

이렇게 하나의 input에 여러 가지 필터를 적용하면서도 연산을 효율적으로 할 수 있었고, 층을 더 깊게 쌓을 수도 있었습니다.

 

 

+ 보조 분류기(Auxiliary Classifier)란?

앞서 말씀드린 Inception module의 사용으로 층을 깊게 쌓을 수 있었습니다.

하지만 네트워크가 깊어지면 backpropagation을 진행할 때 gradient vanishing 문제가 발생할 수 있습니다.

따라서 모델의 끝 뿐만 아니라 중간중간에 loss를 계산해둠으로써 모델 학습에 도움을 줍니다(실제 동작시 고려X).

 

 

2) 특징

    - Inception module 의 사용 -> 다양한 필터를 사용하면서 층을 깊게 쌓을수 있게 됨

    - layer가 깊어서 발생하는 gradient vanishing 문제를 보조 분류기를 통해 해결

    - FC layer를 하나만 사용 -> 연산량 감소


 

4. ResNet

4-1. 구조

ResNet의 기본 구조는 다음과 같습니다.

총 152개의 layer로 구성되어 있는데, 단순하게 쌓는 방식이 아닌 Residual block 을 구성하여 쌓습니다.

(3*3 conv layer 두개로 이루어짐)

 

Residual block 의 기본 아이디어는 input가 output의 차이를 학습하는 것인데,

기존에는 input인 x가 conv layer를 통과하여 H(x)가 되었다면

Redsidual block 에서는 H(x)와 input인 x를 뺀 값, 즉 변화량(F(x), Residual, 잔차)을 학습에 사용합니다.

이를 Residual Learning 이라고 합니다.

 

이 아이디어는 층이 엄청 깊을때 gradient vanshing 문제를 해결해주었는데요!

수학적으로 보면 F(x) + x = H(x) 이고, 이를 미분하면

F'(x) + 1 = H'(x) 이기 때문에 gradient가 항상 1 이상인 것을 확인할 수 있습니다.

 

 

위 그림을 보면 input인 x가 갈고리 모양으로 올라가는 것을 볼 수 있습니다.

이를 skip connection 이라 하고, 가중치 없이 x를 그대로 identity mapping 했다는 말과 동일합니다.

(필요없는 layer를 사용하지 않도록 하는데에 유용)

이 행위를 통해 최종 출력값은 x + F(x) 를 가질 수 있습니다.

 

이렇게 ResNet 은 Residual block 을 이용하여 성능을 유지한 채 층을 깊게 쌓을 수 있었습니다.

 

 

4-2. 핵심 아이디어 및 특징

1) 핵심아이디어 : 층이 깊을수록 무조건 좋다? No! -> 입력과 출력의 차이를 학습 -> Residual Learning

 

+ 층이 깊을수록 성능이 무조건 좋다? No!

아래 그림을 보면 오른쪽의 test 단계에서 56 레이어 네트워크 성능이 더 안좋은데,

train 단계에서도 같은 모습을 보이는 것으로 봐서는 단순히 overfit 문제가 아니라는 것을 알 수 있습니다.

 

 

 

2) 특징

    - input인 x의 변화량만을 학습하기 때문에 input과 output이 크게 변하지 않음.

    - FC layer 대신 Global Average Pooling layer(GAP)을 사용(하나의 map을 average pooling 함) -> 파라미터 수 감소

    - 하나의 FC layer만을 사용함

    - Batch Normalization 사용 / dropout은 사용하지 않음

    - 가중치 초기화를 위해 Xavier/2 사용

    - Optimization 으로 SGD+Momentum 방식 사용

 

 

5. 정리

지금까지 크게 4 종류의 CNN Architecture를 공부했습니다.

사실 해당 Architecture들은 ILSVRC의 우승자가 사용했던 구조입니다.

아래 그림을 보면 2012년 AlexNet을 사용해서 우승했고, 

가장 최근인 2015년 ResNet을 사용해서 우승했습니다.

 

그래프를 자세히 보시면 사용한 layer의 수도 볼 수 있는데,

점점 layer가 깊어지는 추세를 확인할 수 있고, 최근 ResNet에서 layer 수가 급격히 늘어났습니다. 

 

 

각 구조의 복잡도를 보겠습니다.

아무래도 layer 가 깊을수록 복잡도가 높은 경향을 보이고, 가장 복잡도가 높은 Inception-v4 는 ResNet과 Inception 을 합친 방법입니다.

 

오른쪽 그래프의 x축은 연산량 원의 크기는 메모리 사용량인데,

GoogleNet이 효율성으로는 가장 좋고, 

ResNet이 성능은 좋지만 메모리 사용량과 연산량이 높은 것을 확인할 수 있습니다.

 

 

현재도 더 나은 네트워크 구조가 탄생되고, 활발히 연구되고 있습니다.

저희는 그 중 많이 알려진 몇가지의 구조만을 공부했을 뿐이고, 이게 정답이라고 할 수 없습니다.

다만 단순히 layer를 깊게 쌓는다고 성능이 좋아지는 것이 아니기 때문에 많은 사람들이 어떤 아이디어를 가지고 어떻게 접근하는지에 대한 통찰력을 기를 수 있었습니다.

 

이래서 딥러닝 분야에 종사하는 사람들은 끝없는 공부를 해야한다고 하나봅니다.

계속해서 새로운 논문이 나오고, 새로운 네트워크가 업데이트 되니깐요.. 

 

다음 시간에는 이런 네트워크를 어떻게 사용할지 실습을 통해 배워보도록 할게요!!