AlexNet: ImageNet Classification with Deep Convolutional Neural Networks

ImageNet Classification with Deep Convolutional Neural Networks: 논문AlexNet을 소개한 논문으로 CNN 모델의 각 레이어가 어떤 역할을 하는지 잘 분석했다.

논문을 정리한 글이며, CNN의 기본적인 개념을 생략하고 정리했다. 자세한 부분은 BLOG: CNN에 볼 수 있다.

본 글에서 분석을 위해 사용한 코드는 Github에서 볼 수 있다.

Abstract

  • ImageNet LSVRC-2012 대회에서 SOTA를 달성
  • 모델은 6000만 개의 파라미터와 650,000개 뉴런으로 구성
  • 5개의 convolutional layer + 3개의 fully-connected layer + 1000-way softmax
  • non-saturating activation과 효율적인 GPU 연산을 통한 빠른 학습
  • Dropout을 통한 overfitting 방지

Introduction

현실 세계의 객체는 다양한 모습을 띄기 때문에 다량의 학습 데이터가 필요하다. CNN은 이미지 데이터에 대해 기본적인 feedforward network보다 좋은 성능을 보인다.

본 논문의 주요한 특징은 다음과 같다.

  • (ILSVRC-2012:) ImageNet(데이터)를 이용한 가장 큰 CNN 모델이자 가장 높은 성능을 보임
  • GPU 연산 최적화를 통한 2D Convolution 구현
  • 성능 향상 및 학습 시간 단축
  • overfitting 방지 기법 적용
  • layer depth(개수)가 중요함 (convolutional 5개, fully-connected 3개)

2개의 GTX 580 3GB GPU로 5 ~ 6일 간 학습했다.

The Dataset

ImageNet은 22,000개 카테고리로 레이블된 1,500만개 고화질 이미지다. ILSVRC는 ImageNet의 일부를 사용했으며, 1000개 카테고리에 대해 각 1000장 정도의 이미지를 사용했다.

  • training: 약 120만개 이미지
  • validation: 약 50,000개 이미지
  • testing: 약 150,000개 이미지

원본 데이터는 고화질 이미지이다. 하지만 본 연구는 크기를 256 x 256로 고정하고 down-sampling해 사용했다. 이미지의 짧은 쪽 길이를 256으로 두고, 중앙을 256 x 256 크기로 잘라냈다. 다른 전처리는 하지 않았기 때문에 RGB 픽셀 값을 그대로 사용했다고 할 수 있다.

The Architecture

8개 layer로 구성되어 있으며, 각 부분 특징을 설명한다.

ReLU Nonlinearity

saturating nonlinearity는 non-saturating nonlinearity에 비해 학습이 느리다.

saturating nonlinearity는 유한한 범위의 함수(tanh)를 말하며, non-saturating nonlinearity는 무한한 범위의 함수(ReLU)를 말한다.

본 논문에서 nonlinearity는 Rectified Linear Units(ReLU)를 뜻한다.

CIFAR-10 데이터에서 ReLU(실선)는 tanh(점선)에 비해 약 6배 정도 빠르게 학습했다.

Training on Multiple GPUs

GTX 580 GPU는 3GB의 메모리 밖에 없기 때문에 데이터를 완전히 학습할 수 없었다. 따라서 2개의 GPU를 병렬로 처리했다. 각 GPU에 kernel을 절반 씩 나누었으며, 일부 layer에서만 두 GPU가 상호 작용한다.

1개의 GPU를 최대로 활용했을 때보다 성능이 좋았으며 학습 속도도 약간 더 빨랐다.

Local Response Normalization

ReLU는 saturating을 막기 위해 입력을 정규화하지 않아도 된다고 알려져 있다. 하지만 여전히 아래 정규화 방법은 일부 데이터에서 긍정적인 효과를 보였다.

Convolution + ReLU를 거친 벡터를 $a^i_{x,y}$, 정규화를 거친 벡터를 $b^i_{x,y}$라 할 때:

$$b^i_{x,y}=a^i_{x,y}/(k+\alpha \sum^{min(N-1,i+n/2)}_{j=max(0,i-n/2)}(a^j_{x,y})^2)^{\beta}$$

논문에서 사용한 파라미터는 다음과 같다.

  • $k=2$
  • $n=5$
  • $\alpha=10^{-4}$
  • $\beta=0.75$

$N$은 전체 feature map 개수이며, $n$은 합산할 인접한 feature map 개수다.

위 예시는 $n=5$일 때, $a^j_{x,y}$를 선택하는 모습이다.

이러한 정규화를 "brightness normalization"라고 부른다.

Overlapping Pooling

$z$ x $z$ 범위에 대해 stride $s$만큼 공간을 두고 pooling을 진행한다. 일반적으로 $s=z$로 겹치는 부분 없이 pooling한다.

우리는 $s=2$와 $z=3$으로 overlapping pooling을 진행했다. 이러한 방식은 약간의 overfitting 방지 효과가 있다.

Overall Architecture

AlexNet(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (4): ReLU(inplace=True)
    (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): ReLU(inplace=True)
    (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (9): ReLU(inplace=True)
    (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
  (classifier): Sequential(
    (0): Dropout(p=0.5, inplace=False)
    (1): Linear(in_features=9216, out_features=4096, bias=True)
    (2): ReLU(inplace=True)
    (3): Dropout(p=0.5, inplace=False)
    (4): Linear(in_features=4096, out_features=4096, bias=True)
    (5): ReLU(inplace=True)
    (6): Linear(in_features=4096, out_features=1000, bias=True)
  )
)

총 8개 layer 구성으로, 5개 convolutional3개 fully-connected로 이루어져 있다. 최종 출력은 1000-way softmax로 1000개 class label을 생성한다.

모델 최적화는 multinomial logistic regression objective를 최대화하며, 이는 예측이 맞은 레이블에 대한 log-probability를 최대화하는 문제와 동일하다.

쉽게 말해 Cross-Entropy를 적용하면 된다.

일부 convolutional layer만 GPU 간 연결이 있으며, 정규화는 처음 2개의 convolutional layer에서 진행한다.

Reducing Overfitting

많은 파라미터와 1000개의 class를 가지기 때문에 overfitting에 취약하다. 따라서 overfitting 방지를 위한 기법을 소개한다.

Data Augmentation

가장 쉬운 방법은 데이터를 증강하는 방식이다. 변환된 이미지는 저장할 필요 없으며, GPU가 학습을 진행하는 동안 CPU에서 생성할 수 있다.

빠른 이해를 위해 샘플 이미지를 이용해 변환을 진행해봤다. 현재 챕터에서 나오는 이미지는 실제 논문에서 사용한 이미지가 아닌 필자가 임의로 선택한 이미지다.

첫 번째 방법은 256 x 256 이미지에서 랜덤한 224 x 224 패치를 만들고 랜덤하게 가로 방향으로 뒤집는다.

테스트 단계에서는 10개의 랜덤 변환(5개 랜덤 패치 + 가로 뒤집기)한 이미지를 넣고, softmax 출력을 평균내 사용했다.

두 번째 방법은 RGB 채널의 강도를 활용하는 방법이다.

RGB 각 채널의 3 x 3 공분산 행렬에 대해 PCA를 진행한다. eigenvector를 $p_i$, eigenvalue를 $\lambda_i$, 랜덤한 값을 $\alpha\sim N(0, 0.1^2)$라 할 때;

$$[p_1,p_2,p_3][\alpha_1 \lambda_1,\alpha_2 \lambda_2,\alpha_3 \lambda_3]^T$$

이렇게 계산된 값을 이미지 픽셀에 더한다.

시각적으로 큰 차이는 없어 보이지만, 코드로 비교했을 때 약간의 색상 차이를 보인다.

Dropout

Dropout은 일부 뉴런의 출력을 0으로 만든다. 이러한 기법은 네트워크가 특정 뉴런에 의존하는 현상을 방지한다. 따라서 다른 뉴런이 모델 수렴에 필요한 특징을 학습할 수 있도록 도와준다.

Dropout을 사용하지 않을 때 강한 overfitting을 보였으며, dropout을 적용하면 수렴하는데 2배 정도의 반복(iteration)이 필요했다.

Details of learning

  • stochastic gradient descent
  • batch size: 128
  • momentum: 0.9
  • weight decay: 0.0005

작은 weight decay가 모델 학습에 중요하다는 것을 발견했다.

모델 가중치는 $N(0, 0.01^2)$인 Gaussian 분포로부터 초기화했으며, 일부 convolutional layer와 fully-connected layer의 bias는 1로, 나머지는 0으로 초기화했다.

learning rate는 0.01로 초기화하고, validation error가 수렴하지 않을 때마다 10을 나누어주었다. 이 방법으로 약 90번 정도 반복했다.

Qualitative Evaluation

앞서 GPU 2개를 병렬로 사용한다고 언급했다. 학습된 kernel을 확인하니 GPU1은 색상과 연관 없는, GPU2는 색상과 밀접한 관련이 있는 정보를 학습했다. 이러한 특징은 학습마다 나타났으며, 가중치 초기화와 연관이 없다.

모델을 거친 벡터 간 Euclidean 거리가 가깝다면, 두 이미지가 비슷하다고 할 수 있다. 참고로 이미지 픽셀 간 L2 거리가 가까운 것은 아니다.

[1]Pomeranian - [2]Pomeranian: 63.81385
[1]Pomeranian - [3]streetcar: 107.640816

필자가 확인을 위해 벡터 사이 거리를 계산해봤다. 같은 카테고리의 벡터가 더 가까운 것을 볼 수 있다.

이런 특징은 image retrieval에도 적용할 수 있다. 모델을 거친 특징 벡터를 Auto-encoder를 통해 binary code로 압축한다. binary code 비교를 이용하는 방법은 원본 이미지를 활용하는 것보다 효율적인 retrieval이 가능하다.