[풀잎스쿨] CS231n 9강 CNN Architectures (1)

데이터 여행자·2021년 2월 20일
0
  • 스탠퍼드 대학의 CS231n: Convolutional Neural Networks for Visual Recognition
    본 포스팅은 CS231n의 내용을 정리한 것이다. 이곳에 출처가 따로 언급되지 않은 이미지들은 스탠퍼드 대학에서 제공하는 강의 슬라이드에서 가지고 왔다.
    [CS231n] http://cs231n.stanford.edu/2017/syllabus.html

CNN Architectures


9장에서는 많이 사용되는 최신 CNN 아키텍처에 대해서 배울 것이다. 이들은 모두 ImageNet 챌린지에서 우승한 모델이다. 연대순으로 AlexNet, VGGNet, GoogLeNet, ResNet이 있다. 또한 많이 사용되지는 않지만 역사적인 관점으로 흥미로운 모델들도 다룰 것이다.

예전에 본 적이 있는 LeNet은 산업에 성공적으로 적용된 최초의 ConvNet이다. 이미지를 입력으로 받아 stride = 1 인 5 x 5 필터를 통해 몇 개의 Conv Layer와 pooling layer를 거치고, 마지막으로 FC Layer를 통과한다. 간단한 모델이지만 필기체 숫자 인식에서 성공하여 우편번호(zip code) 인식에 사용되었다. (Exploration 1 숫자 인식)

AlexNet


2012년 AlexNet이 나왔다. AlexNet은 기존의 머신러닝 모델을 능가하는 성능을 보여주었으며 Conv Net 연구의 붐을 일으켰다. AlexNet은 LeNet과 비슷하게 생겼다. conv - pool - normalization이 2번 반복되고, conv layer 몇 개(CONV 3,4,5) pooling layer(Max POOL3), 그리고 몇 개의 FC-layer(FC6, FC7, FC8)가 연결된다. LeNet보다 레이어의 수만 많아진 것이다. 즉 AlexNet는 5개의 Conv Layer와 3개의 FC-Layer로 구성된다.


AlexNet의 ImageNet으로 학습시키는 경우 입력의 크기는 227 x 227 x 3 이다. AlexNet의 첫 레이어인 Conv1은 stride = 4, 96개의 11 x 11 필터가 존재한다. 이 때, 첫 레이어의 출력 사이즈는 어떻게 될까?

공식 '(전체 이미지 크기 - 필터 크기) / Stride + 1'에 의해 출력 차원은 55이므로, 첫 레이어의 출력 사이즈는 55 x 55 x 96이다. 그렇다면 이 레이어의 전체 파라미터 갯수는 몇 개일까?


11 x 11 필터가 총 96개 있고 입력의 depth는 3이다. 필터 하나가 11 x 11 x 3 을 통과하고, 필터의 개수가 96개이므로 첫 번째 레이어는 (11 x 11 x 3) x 96 = 35K의 파라미터를 가지고 있다.

두 번째 레이어인 Pooling Layer를 보자. 여기에는 stride = 2 인 3 x 3 필터가 있다. 이 레이어의 출력값의 크기는 27 x 27 x 96이다.

이 레이어의 파라미터는 몇 개일까?

pooling layer에는 파라미터가 없으므로 0개이다. 파라미터는 우리가 학습시키는 가중치이다. Conv Layer에는 학습할 수 있는 가중치가 있지만 pooling layer는 특정 지역에서 큰 값을 뽑아내기 때문에 학습시킬 파라미터가 없다.


모든 레이어의 파라미터 사이즈와 갯수를 계산해 보자.

  • 계산
    INPUT : [227 x 227 x 3]
    CONV1 : 96 11x11 filters at stride 4, pad 0 -> (227 - 11)/4 + 1 = 55 -> [55 x 55 x 96], p = (11x11x3)x96
    MAX POOL1 : 3x3 filters at stride 2 -> (55 - 3)/2 + 1 = 27 -> [27 x 27 x 96], p=0
    NORM1 : [27 x 27 x 96]
    CONV2 : 256 5x5 filters at stride 1, pad 2 -> (27 + 2*2 - 5)/1 + 1 = 27 -> [27 x 27 x 256], p=(5x5x96)x256
    MAX POOL2 : 3x3 filters at stride 2 -> (27 - 3)/2 + 1 = 13 -> [13 x 13 x 256], p=0
    NORM2 : [13 x 13 x 256]
    CONV3 : 384 3x3 filters at stride 1, pad 1 -> (13 + 2*1 - 3)/1 + 1 -> 13 -> [13 x 13 x 384], p=(3x3x256)x384
    CONV4 : 384 3x3 filters at stride 1, pad 1 -> (13 + 2*1 - 3)/1 + 1 -> 13 -> [13 x 13 x 384], p=(3x3x384)x384
    CONV5 : 256 3x3 filters at stride 1, pad 1 -> (13 + 2*1 - 3)/1 + 1 -> 13 -> [13 x 13 x 256], p=(3x3x384)x256
    MAX POOL3 : 3x3 filters at stride 2 -> (13 -3)/2 + 1 = 6 -> [6 x 6 x 256], p=0
    FC1 : p=4096
    FC2 : p=4096
    FC3 : p=1000

위의 그림은 AlexNet의 전체 구조를 나타낸 것이다. 모델의 끝에는 3 개의 FC-Layer가 있다. 2개의 FC-layers는 4096개의 노드를 가진 레이어이고 FC8에서 Softmax를 통과하여 1000개의 ImageNet 클래스를 분류한다.

자세히 살펴보면 AlexNet는 우선 활성화 함수로 ReLU를 사용한다. (처음으로 ReLU를 사용했고, AlexNet으로 인해 ReLU 사용이 일반화되었음) local response normalization layer는 채널간의 normalization을 위한 것이지만 효과가 없음이 알려져 잘 사용하지 않는다. (Batch Normalization과는 다름. 당시에는 BN이 없었음.) flipping, jittering, color norm 등의 data augumentation을 많이 했다. AlexNet은 Dropout도 사용했다. 학습 시 Batch size는 128였으며 Optimization은 SGD momentum을 사용했다. 초기 Learning rate는 1e-2이었고 val accuracy가 올라가지 않는 지점에서부터 학습이 종료되는 시점까지 Learning rate를 1e-10까지 줄였다. weight decay를 사용했고, 마지막에는 모델 앙상블로 성능을 향상시켰다. (에러: 18.2% -> 15.4%)

주의해서 봐야할 것은 AlexNet에서는 모델이 두개로 나눠져서 서로 교차하고 있다는 점이다. 그 당시 AlexNet을 GTX850으로 학습시켰는데, 이 GPU의 메모리는 3GB 뿐이었다. 전체 레이어를 하나의 GPU에 넣을 수 없어 네트워크를 GPU에 분산시켜 넣었다. 각 GPU가 모델의 뉴런과 Feature Map을 반씩 나눠 가진다. 그래서 첫 번째 레이어의 출력은 55 x 55 x 96이지만 각 GPU에서의 Depth는 48이다. (각각 48씩 총 96. 이 때 처음으로 GPU를 사용했다.)

AlexNet의 Conv 1,2,4,5 에서는 같은 GPU 내에 있는 Feature Map만 사용하기 때문에 48개의 Feature Map만 사용한다.

Conv 3와 FC 6, 7, 8는 이전 계층의 "전체 Feature map"과 연결되어 있다. 이 레이어들에서는 GPU간 통신을 하므로 이전 입력 레이어의 전체 Depth를 전부 가져올 수 있기 때문이다.


AlexNet은 Image Classification Benchmark의 2012년도에 우승한 모델이다. AlexNet은 최초의 CNN 기반 우승 모델이고 수년 전까지 대부분의 CNN 아키텍쳐의 기본 모델로 사용되었다. AlexNet은 다양한 Task의 transfer learning에 많이 사용되었지만 지금은 AlexNet보다 성능이 더 뛰어난 최신 아키텍처가 많이 나왔다.

Q. AlexNet이 기존의 모델들보다 뛰어났던 이유가 무엇인가?
기존의 방법과는 달리 최초로 딥러닝와 Conv Net을 사용하였기 때문이다.

ZFNet


2013년의 ImageNet Challange의 승자는 ZFNet이다.

ZFNet은 AlexNet과 같은 레이어 수를 가지고 기존적인 구조가 같았다. stride size, 필터 수 같은 하이퍼파라미터를 조절해서 AlexNet의 Error rate를 개선시킨 것이다.

VGGNet


2014년에는 많은 변화가 있었다. 아키텍쳐도 변하고 성능도 훨씬 향상되었다. 가장 큰 차이점은 "네트워크가 훨씬 깊어졌다"는 것이다. 이전의 8개의 레이어에서 19개의 레이어와 22개의 레이어로 늘어났다. 2014년도의 우승자는 Google의 GoogLenet이었고 Oxford의 VGGNet이 2등이었다. VGGNet은 Localization Challenge 등 다른 트랙에서는 1위를 차지했다.


우선 VGG을 살펴보자. VGGNet은 네트워크가 훨씬 더 깊어졌고 더 작은 필터를 사용했다. AlexNet에서는 8개의 레이어를 사용했지만 VGGNet에서는 16-19개의 레이어를 사용했다. 또한 VGGNet은 3 x 3 필터만 사용했다. 가까이 있는 픽셀을 포함하는 가장 작은 필터이다. 그리고 주기적으로 Pooling을 수행하면서 전체 네트워크를 구성한다. VGGNet은 아주 간단하면서도 고급진 아키텍쳐이고, ImageNet에서 7.3%의 Top 5 Error(5개 안에 답이 있는 경우)를 기록했다.

그렇다면 VGGNet은 왜 더 작은 필터를 사용했을까?

작은 필터를 사용하면 큰 필터를 사용한 것과 성능은 비슷하나 파라미터의 수가 작아지기 때문이다. 그래서 큰 필터에 비해 레이어를 조금 더 많이 쌓을 수 있다. 즉 작은 필터를 사용하면 Depth를 더 키울 수 있다. 그렇다면 3 x 3 필터를 여러 개 쌓은 것의 실질적인 Receptive Field는 무엇일까? 여기서 Receptive Field은 filter가 한번에 볼 수 있는 입력의 영역이다.


첫 번째 레이어의 Receptive Field는 3 x 3이다. 두 번째 레이어는 각 뉴런이 첫 번째 레이어 출력의 3 x 3 만큼 보고, 3 x 3 중에 각 사이드는 한 픽셀씩 더 볼 수 있다. 따라서 두번째 레이어는 실제로 5 x 5의 receptive filed를 가진다. 세 번째 레이어는 두 번째 레이어의 3 x 3 을 보게 되므로 결국 입력 레이어의 7 x 7을 보게 된다. (아래 그림 참고) 따라서 3 x 3 필터를 여러 개 쌓은 것은 하나의 7 x 7 필터를 사용하는 것과 동일하다.

<출처: https://www.slideshare.net/leeseungeun/cnn-vgg-72164295>


따라서 3 x 3 필터를 여러 개 쌓은 것은 7 x 7 필터와 실질적으로 동일한 receptive field를 가지면서 더 깊은 레이어를 쌓을 수 있다. 더 깊게 쌓기 때문에 Non-Linearity를 더 추가할 수 있고 파라미터 수도 적어진다. 3 x 3 필터를 3개 쌓은 것의 전체 파라미터의 갯수를 살펴보자.

  • 3 x 3 필터의 파라미터의 수: 3 x 3 = 9
  • depth C: 3 x 3 x C
  • 출력 Feature Map(= Depth = C) : 3 x 3 x C x C
  • 레이어를 3개 쌓음: 3 x (3 x 3 x C x C) = 27C227C^2

위와 같은 방식으로 계산하면 7 x 7 필터의 파라미터의 갯수는 7 x 7 x C x C = 49C2C^2이다(레이어는 1개). 따라서 3 x 3필터를 3개 쌓은 것이 7 x 7필터보다 파라미터의 수가 더 적다.


전체 네트워크는 위와 같다. 여기서도 파라미터의 크기와 수를 계산해 보자.

  • 계산(pad=1, stride=1로 설정)
    INPUT: [224 x 224 x 3], p=0
  1. CONV3-64: 64 3x3x3 filters -> (224 + 2*1 - 3)/1 +1 = 224 ->[224 x 224 x 64], p=(3x3x3)x64
  2. CONV3-64: 64 3x3x64 filters -> (224 + 2*1 - 3)/1 +1 = 224 ->[224 x 224 x 64], p=(3x3x64)x64
  • POOL2: 2x2 filters at stride 2 pad 0 -> (224 - 2)/2 + 1 = 112 -> [112 x 112 x 64], p=0
  1. CONV3-128: 128 3x3x64 filters -> (112 + 2*1 - 3)/1 + 1 = 112 -> [112 x 112 x 128], p=(3x3x64)x128
  2. CONV3-128: 128 3x3x128 filters -> (112 + 2*1 - 3)/1 + 1 = 112 -> [112 x 112 x 128], p=(3x3x128)x128
  • POOL2: 2x2 filters at stride 2 pad 0 -> (112 - 2)/2 + 1 = 56 -> [56 x 56 x 256], p=0
  1. CONV3-256: 256 3x3x128 filters -> (56 + 2*1 - 3)/1 + 1 -> 56 -> [56 x 56 x 256], p=(3x3x128)x256
  2. CONV3-256: 256 3x3x256 filters -> (56 + 2*1 - 3)/1 + 1 -> 56 -> [56 x 56 x 256], p=(3x3x256)x256
  3. CONV3-256: 256 3x3x256 filters -> (56 + 2*1 - 3)/1 + 1 -> 56 -> [56 x 56 x 256], p=(3x3x256)x256
  • POOL2: 2x2 filters at stride 2 pad 0 -> (56 -2)/2 + 1 = 28-> [28 x 28 x 256], p=0
  1. CONV3-512: 512 3x3x256 filters -> (28 + 2*1 - 3)/1 + 1 -> 28 -> [28 x 28 x 512], p=(3x3x256)x512
  2. CONV3-512: 512 3x3x512 filters -> (28 + 2*1 - 3)/1 + 1 -> 28 -> [28 x 28 x 512], p=(3x3x512)x512
  3. CONV3-512: 512 3x3x512 filters -> (28 + 2*1 - 3)/1 + 1 -> 28 -> [28 x 28 x 512], p=(3x3x512)x512
  • POOL2: 2x2 filters at stride 2 pad 0 -> (28 -2)/2 + 1 = 14-> [14 x 14 x 512], p=0
  1. CONV3-512: 512 3x3x512 filters -> (14 + 2*1 - 3)/1 + 1 -> 14 -> [14 x 14 x 512], p=(3x3x256)x512
  2. CONV3-512: 512 3x3x512 filters -> (14 + 2*1 - 3)/1 + 1 -> 14 -> [14 x 14 x 512], p=(3x3x512)x512
  3. CONV3-512: 512 3x3x512 filters -> (14 + 2*1 - 3)/1 + 1 -> 14 -> [14 x 14 x 512], p=(3x3x512)x512
  • POOL2: 2x2 filters at stride 2 pad 0 -> (14 -2)/2 + 1 = 7-> [7 x 7 x 512], p=0
  1. FC1: [1x1x4096] p=7x7x512x4096
  2. FC2: [1x1x4096] p=4096x4096
  3. FC3: [1x1x1000] p=4096x1000

(CONV layer에서는 활성화 함수로 RELU, FC layer에서 regularization으로 dropout을 사용하였다. 계산 및 위의 내용 참고: [CNN 알고리즘들] VGGNet의 구조 (VGG16).txt)

구조를 보면 Conv Layer와 Pooling Layer가 반복적으로 진행되고, VGG16에서 모든 Layer의 수는 16개이다. VGG19의 경우 유사한 아키텍쳐이지만 Conv Layer가 조금 더 추가되어 layer가 19개이다.

네트워크의 전체 메모리 사용량은 Forward pass 시 필요한 전체 메모리를 계산한 것이다. 각 노드가 4 bytes의 메모리를 차지하므로 전체는 약 100 MB의 메모리가 필요하다. Backward Pass를 고려하면 2배의 메모리가 더 필요하다. 만약 전체 메모리가 5GB이면 이미지 하나당 100MB이므로 50장 밖에 처리할 수 없다. 전체 파라미터의 갯수는 138M개이다. 참고로 AlexNet는 60M개였다.

Q. 네트워크가 더 깊다는 뜻은 무엇인가?
레이어의 갯수가 더 많다는 뜻이다. Depth라는 용어는 두 가지 의미가 있다. 첫번째 뜻은 채널의
Depth이다. 두번째로 "네트워크의 깊이(Depth)"에 쓰일 때는 네트워크의 전체 레이어(학습가능한 가중치를 가진 레이어, CONV, FC)의 갯수를 뜻하며 이 뜻이 일반적으로 쓰인다.

Q. 하나의 Conv Layer 내에 여러 개의 필터가 존재하는 이유는 무엇인가?
3 x 3 Conv 필터가 있다면 필터는 한 번에 3 x 3 x Depth를 보고 하나의 Feature Map을 만든다. 96개의 필터가 있다면 각 필터당 하나의 Feature Map을 만들고 96개의 Feature Map이 합쳐져 하나의 이미지를 출력한다. 각 필터마다 하나의 다른 특징을 추출한다.

Q. 네트워크가 깊어질수록 레이어의 필터 갯수를 늘려야 하는가? (Channel Depth를 늘려야 하는가? 64->128->512)
반드시 그럴 필요는 없지만 Depth를 많이 늘리는 경우가 많다. Depth를 늘리는 이유 중 하나는 계산량을 일정하게 유지시키기 위해서이다. 보통 네트워크가 깊어질수록 각 레이어의 입력을 pooling을 통해서 Downsampling한다. Width와 Height가 작아져 Depth를 늘려도 부담이 없기 때문에 필터의 depth를 조금씩 늘려준다.

Q. 네트워크에 SoftMax Loss 대신 SVM Loss를 사용해도 되는가?
둘 다 사용할 수 있지만 보통 SoftMax Loss를 사용한다.

Q. 계산한 메모리 중에 굳이 가지고 있지 않고 버려도 되는 부분이 있는가?
일부는 가지고 있지 않아도 된다. 그러나 Backword pass시 chain rule을 계산할 때 대부분 이용되므로 그 부분은 가지고 있어야 한다.

파라미터가 존재하는 곳들의 메모리 사용분포를 살펴보면 초기 레이어에서 많은 메모리를 사용하는 것을 알 수 있다. Spatial dimention이 큰 곳(필터의 크기가 큰 곳)이 메모리를 더 많이 사용한다. 가장 많은 파라미터를 사용하는 레이어는 마지막 레이어 FC layer이다. 그 이유는 FC layer가 fully connected(dense connection)되었기 때문이다. 최근 일부 네트워크들은 파라미터를 줄이기 위해 FC Layer를 없애버리기도 한다.


각 레이어들을 부르는 명칭이 있다. CONV3-64는 64개의 필터를 가진 3 x 3 CONV 필터이다. 다이어그램의 오른쪽을 보면 각 필터를 묶어놓았다. 오렌지색 블록을 보면 첫 번째 그룹의 conv를 conv1-1, conv1-2 이런 식으로 표현한다.


VGGNet은 ImageNet 2014 Classification Challenge에서 2등을 했고, Localization에서는 1등을 했다. 학습 과정은 AlexNet과 유사하나 Local response normalization은 도움이 되지 않아서 사용하지 않았다. VGG16과 VGG19은 아주 유사하고 VGG19가 조금 더 깊다. (CONV 레이어가 더 많다.) 따라서 VGG19가 성능이 아주 조금 더 좋으며, 메모리도 조금 더 쓴다. AlexNet처럼 모델 성능을 위해서 앙상블 기법을 사용했다. VGG의 마지막 FC-Layer인 FC7은 이미지넷 1000 class의 바로 직전에 위치한 레이어이다. 이 FC7은 4096 사이즈의 레이어이며, 아주 좋은 feature represetation을 가지고 있는 것으로 알려져 있다. 다른 데이터에서도 특징 추출이 잘되며 다른 Task에서도 일반화 능력이 뛰어나다. 그래서 VGG16을 더 많이 사용한다.

Q. localization이 무엇인가? (VGG가 localization task에서 우승)
localization은 task이며, 나중에 다룰 예정이다. 간단히 설명하면 "이미지에 고양이가 있는지" 를 분류하는 것 뿐 아니라 고양이가 어디에 있는지 네모박스를 그리는 것이다. Detection은 이미지 내에 다수의 객체가 존재할 수 있으나 localization은 이미지에 객체가 하나만 있다고 가정하고 이미지를 분류한다.

0개의 댓글