728x90
반응형

 

 

 

AlexNet

 

AlexNet은 무려 2012년에 개최된 ILSVRC(ImageNet Large Scale Visual Recognition Challenge) 대회의 우승을 차지한 컨볼루션 신경망(CNN) 구조입니다. AlexNet 논문명은 "ImageNet Classification with Deep Convolutional Neural Networks"이고, 이 논문의 첫번째 저자가 Alex Khrizevsky이기 때문에 그의 이름을 따서 AlexNet이라고 부른다고 합니다.

 

 

무려 현재 기준 130,639회 인용이네요. 후덜덜... 저자 Alex를 Google Scholar에 쳐보니 간간히 논문이 나오고 있습니다. Image Classification task에서 유명한 데이터세트인 CIFAR-10 dataset의 저자기도 하네요. 역시 backbone 만 잘 만들어둬도 잘 먹고 잘 사는 것 같습니다. 

 

 

 

 

 

 

AlexNet 모델 구조 

모델 구조는 아래와 같습니다. AlexNet의 기본구조는 1998년에 나온 LeNet-5와 크게 다르지 않습니다. 2개의 GPU로 병렬연산을 수행하기 위해서 병렬적인 구조로 설계되었다는 점이 가장 큰 변화라고 하네요. (GTX-580 3GB 2개로 90 epoch 돌리는데 5~6일 소요) 

 

 

우선 입력 사이즈가 그림에는 224로 되어있는데, 그 뒤에 구현으로 이어지려면 227이 되어야 한다고 합니다. 그림이 잘못되었다고 하네요. 모델 구조는 8개의 Layer로 구성되어 있으며, 5개의 Conv layer, 3개의 fully-connected layer로 구성되어 있습니다. LeNet 과는 다르게 활성화 함수로는 Tanh가 아닌 ReLU를 사용하였습니다. 이는 같은 정확도를 유지하면서 Tanh을 사용하는 것 보다 학습 속도가 6배나 빠르다고 하네요. 

 

 

 

또한 과적합 방지를 위해 Dropout이 적용되었고, Average Pooling이 아닌 Max-pooling을 사용합니다. 

 

torchsummary

torchsummary 로 나타내면 아래와 같습니다. 

 

PyTorch Implementation

아래와 같이 torchvision 라이브러리를 이용하여 쉽게 모델을 불러올 수 있습니다. 

https://pytorch.org/vision/stable/models/alexnet.html

import torch
import torchvision
from torchvision import models, transforms
from torchsummary import summary

alexnet = models.alexnet(pretrained=use_pretrained)
alexnet.eval()
summary(alexnet, (3, 227, 227))

 

PyTorch 구현은 아래와 같습니다. 

class AlexNet(nn.Module):
    def __init__(self, num_classes: int = 1000, init_weights: bool = True):
        super(AlexNet, self).__init__()
        
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, padding=1, stride=4),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            
            nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, padding=2, stride=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            
            nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, padding=1, stride=1),
            nn.ReLU(inplace=True),
            
            nn.Conv2d(in_channels=384, out_channels=384, kernel_size=3, padding=1, stride=1),
            nn.ReLU(inplace=True),
            
            nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, padding=1, stride=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),

        )

        self.fc_layer = nn.Sequential(
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(4096, num_classes)
        )
    
    def forward(self, x:torch.Tensor):
        x = self.conv(x)
        x = x.view(x.size(0), -1)
        x = self.fc_layer(x)
        return x

 

 

Dataset

데이터세트는 ImageNet 데이터세트를 사용했다고 합니다. 22,000개 카테고리로 구성되어 있고 1500만개의 고해상도 이미지가 포함되어있는 data set입니다. ILSVRC 대회는 ImageNet dataset의 subset을 이용하며, 각 카테고리 당 1000개의 이미지가 포함되어 있는 1000개 카테고리를 이용합니다. 따라서, 약 120만개의 training 이미지와 50,000개의 validation 이미지, 150,000개의 testing 이미지로 구성 되어있습니다.

 

논문을 보시면 256x256 크기의 이미지로 만들고, 각 이미지 pixel에서 traning set의 mean을 빼서 normalization 해줬다고 합니다. 

728x90
반응형