본문 바로가기
CV/Coding

AlexNet

by BaekDaBang 2024. 4. 22.

1. Introduction

AlexNet은 복잡도가 높은 이미지넷 문제 해결을 위해 제안된 신경망으로, 2012년 ILSVRC 이미지 분류 콘테스트에서 우승을 차지했다. 120만장의 이미지, 1000가지 클래스로 구성된 ImageNet 데이터셋으로 학습시켰다. AlexNet은 발표 당시 세계 최고의 성능을 자랑하며, 컴퓨터비전분야에서 본격적인 딥러닝을 최초로 도입하여 합성곱 신경망의 응용이 확산되는 계기를 만들었다.

 

  • AlexNet은 LeNet과 구조가 유사하지만 훨씬 층수가 많고, 규모가 큼(한 층당 필터 수가 많음)
  • 일력의 합성곱층과 풀링층의 조합이 이루어진 후 전결합층이 이어지다 소프트맥스 함수를 활성화 함수로 사용하는 출력층 기본 구조는 LeNet과 비슷
  • AlexNet은 65만개 뉴런과 6천만개의 파라미터를 가졌음

 

  • 합성곱층의 필터 크기: 11x11, 5x5, 3x3
  • Max Pooling 사용
  • 과적합 방지를 위한 dropout 적용
  • 은닉층의 활성화 함수는 ReLU, 출력층의 활성화 함수는 SoftMax 함수 사용
  • 입력이미지 => Conv1 => Pool2 => Conv3 => Pool4 => Conv5 => Conv6 => Conv7 => Po ol8 => FC9 => FC10 => SOFTMAX7

 

ReLU를 활성화 함수로 사용

ReLU를 은닉층의 활성화 함수로 활용해서 학습 시간을 크게 단축 시켰음

기울기 소실 문제vanishing gradient problem로 시그모이드/tanh 함수의 경우 빠른 학습에 어려움이 있었음

 

Dropout Layer

드롭아웃층은 신경망 모델의 과적합을 방지하기 위한 것

드롭아웃을 통해 비활성화된 뉴런은 순방향 계산과 역전파 계산에서 모두 배제됨

같은 입력을 가중치를 공유하는 매번 다른 구조의 신경망으로 학습하는 것과 같은 효과

드롭아웃은 뉴런 간의 상호 적응을 방지하고 다양한 조합의 뉴런에 도움을 주는 유용한 특징을 학습하게 됨

AlexNet에는 두 전결합층에서 0.5의 드롭아웃 비율이 적용되었음

 

Data Augmentation

레이블값을 변화시키지 않고 원 데이터만 변형하는 방식으로 데이터 양을 늘리는 기법도 과적합 방지에 효율적

원데이터를 변형하는 방법으로는 이미지 회전, 반전, 배율 조절 등이 있음

 

Local Response Normalization (국소 응답 정규화)

AlexNet 에는 국소 응답 정규화가 적용되어 있음

국소 응답 정규화는 배치 정규화와 다른 기법임

정규화는 가중치가 빨리 수렴되도록 하는 것이 목적으로 현재는 국소 응답 정규화 대신 배치 정규화가 많이 사용됨

 

가중치 규제화

AlexNet은 0.00005의 가중치 감쇠가 적용되었음

가중치 규제화는 L2 규제화와 같은 개념

 

다중 GPU 사용

신경망을 2개의 GPU에 나눠 담아 학습하는 방식(각 층을 두 GPU 메모리에 분리하고 GPU가 서로 통신하는 것)을 개발

오늘날에는 분산 GPU 환경에서 딥러닝 모델을 학습하는 기법 발전

 

2. Code

import torch
import torch.nn as nn

class AlexNet(nn.Module):
    def __init__(self, num_classes: int = 1000, dropout: float = 0.5) -> None:
        super().__init__()
        # input size : (b x 3 x 227 x 227)
        # 논문에는 image 크기가 224 pixel이라고 나와 있지만, conv1d 이후에
        # 차원은 55x55를 따르지 않습니다. 따라서 227x227로 변경해줍니다
        self.features = nn.Sequential(
            nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2), # (b x 96 x 55 x 55)
            nn.ReLU(inplace=True),
            nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),
            nn.MaxPool2d(kernel_size=3, stride=2), # (b x 96 x 27 x 27)
   
            
            nn.Conv2d(96, 256, kernel_size=5, padding=2),# (b x 256 x 27 x 27)
            nn.ReLU(inplace=True),
            nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),
            nn.MaxPool2d(kernel_size=3, stride=2), # (b x 256 x 13 x 13)
            
            nn.Conv2d(256, 384, kernel_size=3, padding=1),# (b x 384 x 13 x 13)
            nn.ReLU(inplace=True),
            
            nn.Conv2d(384, 384, kernel_size=3, padding=1), # (b x 384 x 13 x 13)
            nn.ReLU(inplace=True),
            
            nn.Conv2d(384, 256, kernel_size=3, padding=1), # (b x 256 x 13 x 13)
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2), # (b x 256 x 6 x 6)
        )
        
        # FC layer
        self.classifier = nn.Sequential(
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(p=dropout),
            
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(p=dropout),
            
            nn.Linear(4096, num_classes)
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.features(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

'CV > Coding' 카테고리의 다른 글

ResNet  (0) 2024.04.22
GoogLeNet  (0) 2024.04.22
VGG  (0) 2024.04.22
LeNet  (0) 2024.04.17