[인공지능] AI - CS231n 9강 CNN Architectures


cs231n 9강 youtube 강의 링크
cs231n 공개 강의자료
cs231n 과제 링크


CS231n 9강 - CNN Architectures

Keywords

  • AlexNet
  • VGG
  • Receptive field
  • GoogLeNet
  • Inception module
  • Bottleneck layer
  • ResNet
  • Residual block
  • Network in Network(NiN)
  • Wide ResNet
  • ResNeXt
  • Stochastic Depth
  • FractalNet
  • DenseNet
  • SqueezeNet

이번 강의에서는 최신 2017년 기준.. CNN 아키텍쳐들에 대해 배워볼 시간이다. 사람들이 어떤 식으로 CNN을 구성했는지 확인해보자.

1. AlexNet

최초의 large scale CNN으로 2012년 당시의 딥러닝이 아닌 모델들을 능가하는 놀라운 성능을 보여줬다. layer 구조는 LeNet과 상당히 유사하다. LeNet의 경우 [Conv-Pool-Conv-Pool-Fc-Fc]이고 AlexNet은 아래와 같다.
AlexNet

Q1. AlexNet의 입력의 크기가 227x227x3이고, CONV1에서 11x11 필터가 stride=4로 96개가 있다면 CONV1의 출력 사이즈는?

(227-11)/4+1 = 55이므로 55x55x96이다. 답을 모르겠다면, 여기로

Q2. CONV1의 총 파라미터 수는?

11113*96 = 34848 개이다.

Q3. POOL1에서 3x3 필터가 stride=2라면 POOL1의 출력 사이즈는?

(55-3)/2+1 = 27이므로 27x27x96이다.

Q4. POOL1의 총 파라미터 개수는?

0개이다!! 이전 layer에서 Maxpooling으로 값을 추리는 것이기 때문에 파라미터가 없다.

AlexNet은 ReLU를 처음으로 사용했으며, 지금은 잘 사용하지 않는 Norm layers들도 사용했다. 또한 위 그림을 보면 알겠지만, 하나의 Input 데이터가 둘로 나누어져서 학습이 이루어지고 있는데, 이는 당시에 GPU의 메모리가 충분하지 않았기 때문에 둘로 나누어서 학습해야 했기 때문이다. 나중에 나누어 처리하는 과정을 살펴보자 그렇기에 CONV1,2,4,5에서는 서로 다른 GPU에 나눠진 feature map만을 학습하게 되므로 이를 합쳐주는 구간이 필요했다. 그런 구간이 CONV3, FC6-7-8이다.

이후에 ZFNet이 이 AlexNet의 파라미터 값만을 변경했는데도 성능이 많이 좋아졌다. CONV1에서 11x11 stride4를 7x7 stride2로, CONV3-4-5에서 필터를 각각 512, 1024, 512개를 사용하였다. 파라미터값의 설정이 얼마나 중요한 지 알 수 있는 대목이다.


2. VGGNet

VGGNet은 AlexNet과 뭐가 달라졌을까? 가장 큰 차이점은 layer가 깊어졌다는 것이다. AlexNet은 8개의 layer에 그치지만, VGG는 뒤에 숫자에 따라 layer가 16개에서 19개를 사용하였다. 또한 CONV에서 3x3의 아주 작은 필터를 사용하였다.

왜 이렇게 작은 필터만을 사용했을까? 3개의 3x3 conv(stride: 1)를 사용하면 7x7의 필터를 적용한 것과 같은 효과를 얻을 수 있다. 이는 Receptive field 측면에서 그런건데 아래 그림을 보면 보다 잘 이해할 수 있다.

출처: https://medium.com/deep-learning-g/cnn-architectures-vggnet-e09d7fe79c45
출처: https://medium.com/deep-learning-g/cnn-architectures-vggnet-e09d7fe79c45

똑같이 7x7만큼의 데이터가 있다면 7x7 필터를 적용하면 1x1의 output을 얻을 수 있고 3x3 필터 3개를 적용하면 마찬가지로 1x1의 output을 얻어 같은 결과를 얻을 수 있다.

그래서 어떤게 이득일까?
일단 첫 번째로, 학습 파라미터 수가 감소한다. 하나의 layer 당 channel 수를 C라고 하자. 이는 곧 depth와 같다. 7x7 필터를 사용한 경우의 파라미터 수를 계산해보자. 7x7 필터에 depth를 곱해주고 input depth와 output depth를 같게 유지해야 하기 때문에 depth만큼 한 번 더 곱해주어야 한다. 결론적으로 7x7xCxC 개이다. 3x3의 경우는 같은 방식이지만 3 개의 stack을 쌓기 때문에 3을 더 곱해주면 된다. 결과적으로 3x(3x3xCxC) 개이다. 결국 27 < 49로 파라미터 수가 많이 줄어든 것을 확인할 수 있다.

두 번째로, 같은 receptive field를 유지한 채로 더 깊은 layer를 쌓을 수 있게 되어서 비선형성이 증가한다. 비선형성이 증가하면 일반적으로, 모델이 특징을 잘 식별하게 된다.

위의 식을 토대로 파라미터의 수를 세어보면 다음과 같다.
VGGNet parameters
수치를 잘 살펴보면, 초기의 CONV layer가 많은 메모리를 잡아먹고 있다. 이미지 당 96MB의 메모리나 필요한데 VGGNet은 이렇게 메모리 사용량이 많다. 그리고 FC layer에서는 파라미터의 수가 1억개가 넘는다. 어마무시한 개수.. 이 때문에 GoogLeNet같은 것들은 FC layer를 아예 없애는 경우도 있다.


3. GoogLeNet

이번엔 2014년에 등장한 모델로 이름에서 알 수 있듯, 구글에서 만든 네트워크이다. VGGNet처럼 매우 깊은 네트워크를 사용하고 있다. 다만 차이점은 inception module을 통해 효율적인 계산을 수행하도록 디자인을 했다는 점이다.

Inception Module
이게 바로 inception module인데, GoogLeNet은 이러한 module을 여러 개 쌓아서 만든다. 앞서 말했듯, GoogLeNet은 FC-layer들을 없앴는데 파라미터를 줄이기 위해서이다. 그렇기 때문에 AlexNet보다 1/12배인 5M정도이다. 그렇지만 그럼에도 불구하고 훨씬 더 네트워크가 깊다.

Inception Module
Inception module을 배우기 앞서 naive한 버전을 먼저 살펴보자. Inception module 내부에는 동일한 입력을 받는 서로 다른 필터들이 병렬로 존재한다. 1x1, 3x3, 5x5 세 가지의 Conv layer와 3x3 max pooling layer가 있다. 이 layer를 거친 output들을 depth 방향으로 concatenation한다. 그러면 하나의 tensor로 출력이 되고 다음 레이어의 input이 된다.

Q1. Naive한 Inception module의 문제점은?

계산 비용이 너무 크다. 각 layer들의 출력 값을 이어붙이기 때문에, 총 depth가 너무 커진다.

또한 pooling layer에서도 depth size가 줄어들지 않고 유지되기 때문에 feature depth는 증가할 수 밖에 없다. GoogLeNet의 inception module은 이 문제점을 1x1 conv layer를 통해 해결하였다. 이전 강의에서도 설명했듯, spatial dimension을 유지하면서 depth를 필터의 개수로 dimension을 줄이는 방법이다. 이를 1x1 conv bottleneck layers라고도 한다.

GoogLeNet의 구조는 1) Stem Network, 2) Stacked Inception Modules, 3) classifier output으로 이루어져있다. 1) Stem Network는 [Conv-Pool-Conv-Conv-Pool]의 구조로 일반적인 네트워크의 구조로 시작한다. 2) 그 후 앞서 배운 Inception module이 쌓이고 3) 마지막으로 classifier output에서 SoftmMax로 1000개의 imageNet class를 구분한다.

또한 네트워크 중간에 Auxiliary classifier를 달아서 중간 layer의 학습을 도와준다. 이를 다는 이유는 네트워크가 너무 깊어서 기울기가 소실될 수 있기 때문이다.

FC layer 대신, global average pooling을 사용하였는데, 앞서 deep하게 layer를 쌓아 학습을 해서 효과적으로 feature map을 얻었으므로 이러한 pooling만으로 충분하다고 한다.

cf) FC layer들이 없다는 것은 마지막에 1000개의 output을 만들 때 없다는 것이 아니라 다른 모델들처럼 별도의 FC layer를 두지 않는 다는 말이다.


4. ResNet

GoogLeNet의 22개의 layer도 매우 깊었는데, ResNet은 가히 Revolution의 Depth라고 할 수 있다. 무려 152개에 달한다. 왜 그 전까진 network를 깊게 쌓을 수 없었을까? 일반적인 CNN layer를 깊게 쌓으면 어떻게 될까?

56 layers
직관적으론 layer를 많이 쌓으면 엄청나게 많은 파라미터가 있기 때문에 Overfitting할 것이다라고 생각하겠지만, 실제로는 test error뿐 아니라 training error 또한 더 안 좋아졌다. ResNet의 저자들은 최적화를 잘 못했기 때문에 이런 현상이 일어났다고 생각한다.

또 ResNet의 저자들은 최소한 얕은 네트워크만큼은 성능이 나와야하지 않을까하고 생각해서 이런 것을 보장하는 방식을 구상했다. 그게 Residual block의 출발점인데, 더 얕은 모델의 가중치를 깊은 모델의 일부 레이어에 복사하고 나머지 레이어는 identity mapping을 하는 것이다. identity mapping이란 input에 어떤 처리(conv나 relu 등)를 하지 않고 output으로 바로 내보내는 것이다.

아이디어는 마련했으니 이를 아키텍쳐에 적용해보자. 결국 우리가 원하는 것은 입력이 출력으로 그대로 나오는 것이다. 이를 기존과 비교하며 정확히 이해해보자. 기존의 NN은 input인 x를 타겟 클래스 값 y로 매핑하는 함수 H(x)를 찾는 것이다. 즉 H(x)-y가 0이 되는 것을 원하는 것이다.

Residual block
이제 ResNet의 경우를 살펴보자. 위 그림을 보면 plain layer의 경우 input x가 2 개의 conv layer를 거쳐서 H(x)라는 결과물을 얻었다. 근데 residual block에서는 F(x)+x를 결과물로 얻는다. 참으로 이상하다!! 왼쪽의 결과물이 H(x)이면 오른쪽의 결과물은 H(x)+x여야 하는 것 아닌가? 답을 알게되는데 꽤 오랜 시간이 걸렸다…ㅜㅜ

일단, H(x)를 plain과 residual block일 경우 다르게 봐야 한다. 논문이 아닌 단편적인 강의라 자세히 나와있지 않은데, 결국 H(x)는 둘 다 output을 의미한다. Residual block일 경우 layer를 통과한 결과물을 F(x)로 하기로 했고 이에 x를 더한 값이 output인 H(x)가 되는 것이다. 결과적으로, H(x) = F(x) + x이고, 이를 Residual block이라고 하는 것도 F(x)가 H(x)-x와 같기 때문이다. 즉, H(x)-x가 0이 되는 것을 원하는 상황인 것이다.

아직도 이해가 안간다면 원래의 아이디어를 떠올려보자. 우리는 input이 output이 되는 상황을 원하고 있다. 그렇게 되면 F(x)+x = x가 되어야 하기 때문에 F(x)가 0이 되는 방향으로 학습을 진행하게 될 것이다.

이게 왜 더 최적화의 난이도를 낮춰줄까? 실제로 mapping하는 함수인 H(x)를 바로 학습하는 것보다 변화량인 F(x)만을 학습하면 되기 때문이다. 전체를 학습하는 것보다 예시에서는 2개의 weight layer 쉬워지는 이유는 전체의 경우 각 weight layer가 모두 분리되어 있기 때문에 각 layer마다 학습을 진행해줘야 하는 반면, 추가적인 정보인 F(x)만을 학습하면 되기 때문이다. 결국 답을 찾는 함수를 매핑하는 것보단 input을 0으로 만드는 걸 찾는게 더 쉽다 이말인듯..?

Residual block은 성능이 저하되는 문제인 degradation도 해결했지만 gradient vanishing 문제도 해결하였다. H(x) = F(x)+x를 미분해도 1+F’(x)로 모든 layer에서의 gradient가 1 이상의 값을 갖기 때문이다.

Resnet은 결국 이러한 residual block을 여러 개 쌓았다 모든 residual block은 3x3 conv layer를 2개 갖으며, 주기적으로 필터 수를 2배 늘려준다. 필터 수를 늘리는 이유는 feature map의 spatial dimension이 stride 2를 적용하여 줄어들기 때문에 layer 간 연산의 균형을 맞춰주기 위해서 이다. 필터 수가 늘어나면 그만큼 연산량이 늘어나기 때문이다. 또한 GoogLeNet처럼 마지막에 Global Average pooling을 해서 FC layer 하나를 구한다. GoogLeNet 때와 마찬가지로 파라미터 수를 줄이기 위함이다.

cf) 만약 50 개보다 깊게 layer를 쌓는다면, 파라미터 수가 너무 많기 때문에 GoogLeNet처럼 bottleneck layer1x1 convolution를 둔다.

Other architectures

  1. Network in Network(NiN)

  2. Identity Mappings in Deep Residual Networks

  3. Wide Residual Networks

  4. Aggregated Residual Transformations for Deep Neural Networks(ResNeXt)

  5. Deep Networks with Stochastic Depth

  6. FractalNet: Ultra-Deep Neural Networks without Residuals

  7. Densely Connected Convolutional Networks

  8. SqueezeNet