CNN 아키텍쳐 리뷰 (AlexNet)

2012년 이미지넷 대회에서 gpu를 사용하여 괄목할 성과를 내서 CNN의 시대를 열어준 가장 유명한 네트워크 알렉스넷에 대해서 알아 보겠다.

알렉스넷이 이전의 네트워크와의 차이점을 가지는 점은 아래와 같다.

  • Relu Function
  • Momentum Function
  • Trainging on Multiple GPUs(50x than cpu using GTX580x2)
  • Local Normalization Response Normalization
  • Data Augmentation
  • Dropout
  •  Overlapping Pooling

Relu Function

f(x) = max(0, x) 이 Relu function이다. 일전의 activation function은  f(x) = tanh(x) or 시스모이드를 사용하였으나 layer가 deep 해질수록 gradient vanishing 현상이 발생하였다.

Relu는 도함수의 값이 0혹은 1 이므로 gradient vanising 현상에 강하며 계산속도면에서도 훨씬 강점을 나타낸다.

Momentum Function

Stocstochastic gradient descent을 일반적인 optimizer로 사용하였으나  local minima 문제 혹은 global minima에서 수렴이 상당히 늦어 지는 문제와 oscillation  을 막기위하여

learning late term에 momentum을 붙히는 momentum algorithm을 사용하였다.

Trainging on Multiple GPUs(50x than cpu using GTX580x2)

단순한 행렬연산이 많은 딥러닝의 특성상 GPU가 훨씬 유리하다. alexnet에서는 2개의 gpu를 이용하여 학습하였으며 공간적 특성 색감을 따로 학습하여 합치는 방법을 사용하였다.  (이미지 사이즈에 비하여 VRAM이 부족하여 당시에는 나누어서 Shuffle 하는 방법을 사용,Shuffle에서 이 방법이 다시 등장)

Local Normalization Response Normalization

Data skew와 internal covariance shift problem을 막기위하여 normalization을 한다.

Data Augmentation

데이터 argmentation을 진행하며 224×224로 crop 및 RGB 값의 PCA을 추출한다.

Dropout

Learning 시에 random하게 network를 drop시킨다. 조금더 sparse한 network를 만들어 non-linearity를 증가시키며 계산속도 또한 증가 시킨다.

Overlapping Pooling

Pooling을 overlapping 해서 시킨다. 이것은 downsampling 시킬때 너무나 많은 context가 없어지는 것을 방지 하는 것으로 추정된다.

Overall architecture

  • 8 layers

    • 5 convolutional

    • 3 fully-connected

Implementation

실제로 대회에서 사용된 alexnet은 gpu를 두개를 사용하였는데 그런 코드를 찾을 수 가 없었다.(그래서 논문의 결과를 동일하게 재현하는게 조금 힘들다)  아래는 pytorch-playground에 있는 alexnet의 코드중 일부이다.

Class AlexNet(nn.Module):

def init(self, num_classes=1000):
super(AlexNet, self).init()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256 * 6 * 6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)

def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), 256 * 6 * 6)
x = self.classifier(x)
return x

def alexnet(pretrained=False, model_root=None, kwargs):
model = AlexNet(kwargs)
if pretrained:
model.load_state_dict(model_zoo.load_url(model_urls['alexnet'], model_root))
return model

댓글 남기기