top of page

Alex-net 설명, 간단한 코드

최종 수정일: 2023년 3월 27일

1. AlexNet 이란?


AlexNet은 인공지능의 ILSVRC에서 2012년에 당시 오차율 16.4%로 다른 모델보다 압도적으로 우승한 모델입니다. 현재 시점에서 수치를 보면 그렇게 좋은 정확도가 아니지만, 대회 당시에는 굉장한 정확도였다고 합니다. 2011년에 우승했던 모델의 오차율이 25.8%였으니, 오차율 성능이 40% 만큼 좋아졌습니다.

AlexNet의 'Alex'는 모델 논문의 저자인 Alex Khrizevsky의 이름 입니다.


2. AlexNet 구조


ree

AlexNet은 위의 그림과 같은 구조입니다.

순서대로 나열하면 아래와 같습니다.


  • Input layer

  • Conv1 - MaxPool1 - Norm1

  • Conv2 - MaxPool2 - Norm2

  • Conv3 - Conv4 - Conv5 - Maxpooling

  • FC1- FC2

  • Output layer

Input layer

224x224x3 크기의 이미지


Conv_1

11x11(stride=4, padding=0)의 Kernel (filter) 96개

Input : 224x224x3

Output : 55x55x96


MaxPooling_1

3x3(stride=2, padding=0) Kernel (filter)

Input : 55x55x96

Output: 27x27x96


Norm_1

LRN을 사용한 Normalization layer 이며, 자세한 내용은 아래에 있습니다.

Input : 27x27x96

Output : 27x27x96



Conv_2

5x5(Stride=1, Padding=2) Kernel(filter) 256개

Input : 27x27x96

Output : 27x27x256


MaxPooling_2

3x3(stride=2, padding=0) Kernel

input : 27x27x256

output : 13x13x256


Norm_2

LRN을 사용한 Normalization layer

Input : 13x13x256

Output : 13x13x256


Conv_3

3x3(Stride=1, Padding=1) Kernel(filter) 384개

Input : 13x13x256

Output : 13x13x384


Conv_4

3x3(Stride=1, Padding=1) Kernel(filter) 384개

Input : 13x13x384

Output : 13x13x256


Conv_5

3x3(Stride=1, Padding=1) Kernel(filter) 256개

Input : 13x13x384

Output : 13x13x256


MaxPooling_3

3x3(stride=2, padding=0) Kernel

Input : 13x13x256

Output : 6x6x256


FC_1

FCL 4096개

Input : 6x6x256

Output : 4096


FC_2

FCL 4096개

Input : 4096

Output : 4096


Output layer

FCL 1000 Softmax

Input : 4096

Output : 1000



3. AlexNet 특징



1. Relu 함수


활성화 함수로 Relu 함수를 사용 했습니다.

이전까지는 Tanh 함수를 사용했는데, 두 함수의 차이점은 어떤 것이 있을까요?

우선 두 함수의 생김새는 아래와 같습니다.

ree

가장 큰 차이점은 tanh함수는 [-1, 1] 범위에서 존재하지만,

ReLU함수는 [0, ∞] 범위에 존재한다는 점입니다.


이러한 범위는 논문의 'Saturating(포화상태)' 개념과 관련이 있습니다.

tanh 함수가 saturating function이기 때문에 non saturating 한 ReLU보다 훨씬 느리다는 것이

Alex net 논문의 주장입니다. 그러면 Saturating function이란 무엇일까요?


쉽게 생각하자면 -∞ 또는 +∞ 범위로 국한되지 않고 발산하는 함수를 non-saturating 함수라고 정의합니다.

ReLU함수는 +∞ 범위로 계속 무한대로 나아가고 있기에 non-saturating 함수이고,

반면 tanh함수는 [-1, 1]의 범위로 되어있기 때문에 saturating 함수입니다.

이러한 saturating 함수의 완만한 기울기는 Gradient의 Update를 느리게 만든다고 알려져 있습니다.

ree

실제로 논문에서 제시한 위 그래프를 보시면,

실선인 ReLU 함수가 적은 epoch에도 빠른 Error rate 감소를 보이고 있습니다.

실제로 6배 정도 더 빠른 성능을 보였다고 합니다.

따라서 Alexnet 에서는 Relu 활성화 함수를 채택했습니다.



2. Local Responce Normalization(LRN) 의 사용


Batch normalization으로 잘 알려진 정규화 계열의 방법입니다.

이 방법은 인체의 현상 중 lateral inhibition(측면 억제)에서 영감을 받아 만들어졌습니다.


LRN은 일반화(generalizaion) 목적으로 사용합니다.

위의 설명과 같이 ReLU는 non-saturating 함수이기 때문에 saturating을 예방하기 위한 입력 normalizaion이 필요로 하지 않는 성질을 갖고 있습니다. ReLU는 양수 값을 받으면 그 값을 그대로 neuron에 전달하기 때문에 너무 큰 값이 전달되어 주변의 낮은 값이 neuron에 전달되는 것을 막을 수 있습니다. 이것을 예방하기 위한 normalization이 LRN 입니다.

ree

위 그림은 측면 억제의 유명한 그림인 헤르만 격자입니다. 검은 사각 형안에 흰색의 선이 지나가고 있습니다. 신기한 것은 흰색의 선에 집중하지 않을 때 회색 점이 보이는데 이러한 현상이 측면 억제에 의해 발생하는 것입니다. 이는 흰색으로 둘러싸인 측면에서 억제를 발생시키기 때문에 흰색이 더 반감되어 보입니다.

AlexNet에서 LRN을 구현한 수식을 살펴보겠습니다.

ree

a는 x, y 위치에 적용된 i번째 Kernel의 Output을 의미하고

a를 normalization 하여 큰 값이 주변의 약한 값에 영향을 주는 것을 최소화했다고 합니다.

이러한 기법으로 top-1와 top-5 error를 각각 1.4%, 1.2% 감소시켰다고 합니다.

하지만 AlexNet 이후 현재 CNN에서는 LPR 대신 Batch normalization 기법이 많이 쓰입니다.



3. Overlapping Pooling


Pooling을 'Overlap(중첩)' 하여 사용한 것입니다.

아래 그림은 기존 방식과 중첩 방식을 보여줍니다.

ree

기존에는 위 그림의 상단처럼 Overlap 하지 않은 pooling을 사용했습니다.

하단 그림은 stride를 조절하여 Overlappling pooling을 사용했습니다.

이는 기존의 방법보다 약간 더 overfitting의 해결에 효과적이라는 점을 Error rates를 통해 알 수 있습니다.




3. Overfiting 해결


AlexNet에는 6천만 개의 parameters가 있습니다. 이미지 1000개 classes로 분류하기 위해서는 상당한 overfitting 없이 수많은 parameters를 학습시키는 것은 어렵다고 말합니다.

AlexNet 논문에서는 overfitting을 해결하기 위해 적용한 두 가지 기법을 사용합니다.

첫 번째는 Augmentation 이고, 두 번째는 Dropout입니다.

1. Data Augmentation

Augmentation은 CNN 모델에서 데이터를 다양하게 증대시키는 방법입니다.

데이터 증대는 두 가지 방법을 사용하는데,

첫 번째는 단순 '수평반전'

두 번째는 RGB 픽셀 값을 변화


ree

쉽게 설명하면 1개의 이미지를 수평으로 뒤집고,

이를 랜덤으로 crop 해서 이미지를 증대시키는 방법입니다.

이렇게 전환한다면 더 많은 학습 이미지를 형성하고 다양한 학습이 가능합니다.



2. Drop out


Dropout이란 말 그대로 네트워크의 일부를 생략하는 것입니다.

아래 그림처럼 네트워크의 일부를 생략하고 학습을 진행하게 되면,

생략한 네트워크는 학습에 영향을 끼치기 않게 됩니다.

ree



4. AlexNet 간단한 코드


맨 처음 소개드렸던 AlexNet 구조입니다.

아래 그림 구조에 따라서 구현되는 간단한 class 코드입니다.


ree



import torch import torch.nn as nn import torchvision from torchsummary import summary class AlexNet(nn.Module): def __init__(self,num_classes=1000): super(AlexNet,self).__init__() self.feature_extraction = nn.Sequential( nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=2,bias=False), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3,stride=2,padding=0), nn.Conv2d(in_channels=96,out_channels=192,kernel_size=5,stride=1,padding=2,bias=False), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3,stride=2,padding=0), nn.Conv2d(in_channels=192,out_channels=384,kernel_size=3,stride=1,padding=1,bias=False), nn.ReLU(inplace=True), nn.Conv2d(in_channels=384,out_channels=256,kernel_size=3,stride=1,padding=1,bias=False), nn.ReLU(inplace=True), nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1,bias=False), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2, padding=0), ) self.classifier = nn.Sequential( nn.Dropout(p=0.5), nn.Linear(in_features=256*6*6,out_features=4096), nn.ReLU(inplace=True), nn.Dropout(p=0.5), nn.Linear(in_features=4096, out_features=4096), nn.ReLU(inplace=True), nn.Linear(in_features=4096, out_features=num_classes), ) def forward(self, x): x = self.feature_extraction(x) x = x.view(x.size(0),256*6*6) # 8, 9216 x = self.classifier(x) return x if __name__ =='__main__': model = AlexNet() alex = model.cuda() summary(alex, (3,224,224))



아래는 위의 코드 summary 출력 결과입니다.

ree

이상으로 AlexNet 리뷰를 마치겠습니다.

AlexNet 으로 학습하는 코드는 추후 업데이트하겠습니다.

감사합니다.


댓글


​주식회사 파이미디어랩

sales@paimedialab.com

본사 : 서울시 강남구 역삼로 160 803호

사업자 등록 번호 156-86-01908

​연구소 :서울시 서초구 매헌로16, 1304호

bottom of page