ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [논문] CNN - AlexNet, 2012
    개발/머신러닝-딥러닝 2022. 3. 8. 18:01

    제가 이해한 내용을 정리한 글입니다. 오류가 있으면 고쳐주세요!

    2012년에 CNN을 사용해 ILSVRC에서 압도적으로 1등한 모델.

    기반이 되는 논문은 AlexNet 이다.

     

    배경

    기계학습의 성능을 높이기 위해서는 큰 데이터셋이 필요하다.

    큰 데이터를 잘 학습하기 위해서는 용량이 큰 모델이 필요하다.

    CNN은 비슷한 규모의 피드포워드 신경망보다 간선과 파라미터가 적으므로 학습이 쉽다. (물론 best-perfomance는 조금 떨어질 수 있다.)

     

    모델 특징

    모델은 이미지의 속성을 찾는 5개의 Conv층과 속성으로 이미지를 분류하는 3개의 FC층이 있다.

    여기서 Conv층을 조금이라도 제거한다면 성능이 떨어짐을 확인했다.

    • 두 개의 GPU - 피드포워드 신경망보다 적지만 여전히 GPU로 학습하기에는 용량이 부족하기 때문에 두 대의 GPU를 사용해 파라미터를 분산시켜서 학습했다. 각각의 GPU는 기본적으로 다른 파라미터를 학습하지만 몇개의 층(3번째 Conv, FC층)에서 파라미터들을 공유한다. 이는 서로 다른 특징에 특화 되기 때문에 하나의 GPU에서 학습한 것보다 성능이 좋음을 확인했다.
    • ReLU 사용: ReLU를 사용했을 때 tanh와 같은 포화 비선형 함수를 사용했을 때보다 학습이 빨랐다. 빠른 속도는 큰 데이터로 큰 모델을 만드는데 영향을 끼친다.
    • Local Response Normalization: ReLU는 활성화 된 값이 포화되지 않으므로 하나의 큰 파라미터가 다른 파라미터에 영향이 안가도록 억제할 필요가 있다. tanh를 위해 입력을 정규화 하는 대신 LRN을 사용해 ReLU의 출력을 억제하여 파라미터의 일반화를 줄인다.

    LRN의 계산 식

    • Overlapping Pooling: 커널의 크기를 Stride보다 크게하여 조금씩 겹쳐서 학습이 되도록 한다. 이는 과적합 방지에 도움이 되었다.
    • 데이터 확대 1: 256x256으로 다운 샘플링 된 이미지를 224x224 크기로 5장으로 자르고, 이를 수평 반전시켜서 총 10장의 이미지를 만들어 학습에 사용했다. 테스트 시에서는 이 10장의 이미지에 대한 예측값을 평균내어 최종 예측으로 사용했다.
    • 데이터 확대 2: 객체에서 중요한 속성은 빛이나 색에 영향을 덜 받을 것이라 판단해 RGB값을 PCA하여서 이미지를 추가했다.
    • 드롭아웃: 드롭아웃을 적용하면 저렴한 비용으로 여러 모델을 combine하는 효과와 비슷하므로 첫 두개의 FC층에서 드롭아웃을 적용했다.

     

    코드

    # code with Pytorch
    import torch
    import torch.nn as nn
    
    class AlexNet(nn.Module):
        def __init__(self):
            super().__init__()
            self.features = nn.Sequential(
                nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4, padding=2),
                nn.ReLU(inplace=True),
                nn.LocalResponseNorm(11),
                nn.MaxPool2d(kernel_size=3, stride=2),
                nn.Conv2d(in_channels=64, out_channels=192, kernel_size=5, stride=1, padding=2),
                nn.ReLU(inplace=True),
                nn.LocalResponseNorm(5),
                nn.MaxPool2d(kernel_size=3, stride=2),
                nn.Conv2d(in_channels=192, out_channels=384, kernel_size=5, stride=1, padding=2),
                nn.ReLU(inplace=True),
                nn.Conv2d(in_channels=384, out_channels=256, kernel_size=5, stride=1, padding=2),
                nn.ReLU(inplace=True),
                nn.Conv2d(in_channels=256, out_channels=256, kernel_size=5, stride=1, padding=2),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(kernel_size=3, stride=2),
            )
            self.classifier = nn.Sequential(
                nn.Dropout(0.5),
                nn.Linear(256*6*6, 4096),
                nn.ReLU(inplace=True),
                nn.Linear(4096, 4096),
                nn.ReLU(inplace=True),
                nn.Linear(4096, 6)
            )
        def forward(self, x):
            x = self.features(x)
            x = torch.flatten(x,1)
            x = self.classifier(x)
            return x

    한 대의 GPU를 사용하여 학습하는 코드.

    이는 224x224사이즈의 데이터에 맞춰져 있으므로,

    다른 사이즈의 이미지에 대해서는 각 층의 하이퍼 파라미터의 조정이 필요하다.

     

    기타

    • Pytorch의 AlexNet코드를 참고했다. Pytorch에서는 LRN을 적용하지 않았는데, 큰 차이가 없다고 한다. 링크 
    • 이 모델을 시작으로 이미지 분류에 CNN을 활용하기 시작했다고 한다.
    • 두 개의 GPU가 다른 파라미터를 학습하면서 하나는 색에 특화되고, 하나는 색과 무관한 부분에 특화된다.
    • 학습은 GPU에서 진행하지만 이미지를 늘리는 작업은 CPU환경으로 진행해 동시에 진행 가능하다.
    • LRN은 요즘은 안쓰고 Batch Normalization을 쓴다고 한다.

    댓글

Designed by Tistory.