[CV] AlexNet(2012) 논문을 code로 구현 해보자 (Keras, PyTorch)

2021. 6. 25. 02:50·Computer Vision💖/Basic
반응형

이번 포스팅에서는 지난번 포스팅했던 AlexNet을 Keras와 PyTorch로 각각 구현하고 적용해보고자 합니다. 사실 저는 Keras에 훨씬 익숙하기에, 메인 code들은 Keras로 작성하겠습니다. 이론 설명은 지난번 포스팅을 참고해주세요!

2021.06.23 - [딥러닝(DL) 📈/CV] - [Vision] AlexNet(2012)의 구조와 논문 리뷰

 

[Vision] AlexNet(2012)의 구조와 논문 리뷰

오늘은 Deep한 CNN의 발전에 가장 큰 영향을 준 AlexNet(2012)에 대해 포스팅하고자 합니다. AlexNet은 2012년에 개최된 ILSVRC(ImageNet Large Scale Visual Recognition Challenge) 에서 우승을 차지한 아키텍처..

daeun-computer-uneasy.tistory.com

 

기본 아키텍처 파악

우선 구현 전에 논문에 소개된 AlexNet의 아키텍처를 살펴보겠습니다. 

AlexNet의 아키텍처

AlexNet은 [Input layer - Conv1 - MaxPool1 - Norm1 - Conv2 - MaxPool2 - Norm2 - Conv3 - Conv4 - Conv5 - Maxpool3 - FC1- FC2 - Output layer] 으로 구성되어 있습니다. 논문의 dataset은 1000개의 class를 분류하는 것이었기 때문에 output node는 1000이 됩니다. 이러한 아키텍처를 각각 PyTorch와 Keras로 바로 구현해보겠습니다. 

 

PyTorch 구현

class AlexNet(nn.Module):
  def __init__(self, num_classes=1000):
    super().__init__()
    ##### CNN layers 
    self.net = nn.Sequential(
        # conv1
        nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4),
        nn.ReLU(inplace=True),  # non-saturating function
        nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),  # 논문의 LRN 파라미터 그대로 지정
        nn.MaxPool2d(kernel_size=3, stride=2),
        # conv2
        nn.Conv2d(96, 256, kernel_size=5, padding=2), 
        nn.ReLU(inplace=True),
        nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),
        nn.MaxPool2d(kernel_size=3, stride=2),
        # conv3
        nn.Conv2d(256, 384, 3, padding=1),
        nn.ReLU(inplace=True),
        # conv4
        nn.Conv2d(384, 384, 3, padding=1),
        nn.ReLU(inplace=True),
        # conv5
        nn.Conv2d(384, 256, 3, padding=1),
        nn.ReLU(inplace=True),
        nn.MaxPool2d(kernel_size=3, stride=2),

    )

    ##### FC layers
    self.classifier = nn.Sequential(
        # fc1
        nn.Dropout(p=0.5, inplace=True),
        nn.Linear(in_features=(256 * 6 * 6), out_features=4096),
        nn.ReLU(inplace=True).
        # fc2
        nn.Dropout(p=0.5, inplace=True),
        nn.Linear(4096, 4096),
        nn.ReLU(inplace=True),
        nn.Linear(4096, num_classes),
    )
    # bias, weight 초기화 
    def init_bias_weights(self):
      for layer in self.net:
        if isinstance(layer, nn.Conv2d):
          nn.init.normal_(layer.weight, mean=0, std=0.01)   # weight 초기화
          nn.init.constant_(layer.bias, 0)   # bias 초기화
      # conv 2, 4, 5는 bias 1로 초기화 
      nn.init.constant_(self.net[4].bias, 1)
      nn.init.constant_(self.net[10].bias, 1)
      nn.init.constant_(self.net[12].bias, 1)
    # modeling 
    def forward(self, x):
      x = self.net(x)   # conv
      x = x.view(-1, 256*6*6)   # keras의 reshape (텐서 크기 2d 변경)
      return self.classifier(x)   # fc   

 

Keras 구현

Functional API를 사용하였습니다. Keras에는 LRN 모듈을 사용하는데에 이슈가 있어 BatchNormalization을 사용하였습니다. 

# modeling(functional API)
input_shape = (224, 224, 3)  # 논문에서 제시된 shape
x = Input(shape = input_shape, name='INPUT')

# CONV
conv1 = Conv2D(filters=96, kernel_size=11, activation='relu', strides=4, name='CONV_1')(x)
pool1 = MaxPooling2D((3,3), strides=2, name='POOL_1')(conv1)  # overlapped pooling
# lrn1 = local_response_normalization(conv1,depth_radius=5, bias=2, alpha=0.0001, beta=0.75) 
lrn1 = BatchNormalization(name='LRN_1')(pool1)

conv2 = Conv2D(filters=256, kernel_size=5, activation='relu', strides=1, padding='same', name='CONV_2')(lrn1)
pool2 = MaxPooling2D((3,3), strides=2, name='POOL_2')(conv2)
# lrn2 = local_response_normalization(conv2,depth_radius=5, bias=2,  alpha=0.0001, beta=0.75)
lrn2 = BatchNormalization(name='LRN_2')(pool2)

conv3 = Conv2D(filters=384, kernel_size=3, activation='relu', strides=1, padding='same', name='CONV_3')(lrn2)
conv4 = Conv2D(filters=384, kernel_size=3, activation='relu', strides=1, padding='same', name='CONV_4')(conv3)
conv5 = Conv2D(filters=256, kernel_size=3, activation='relu', strides=1, padding='same', name='CONV_5')(conv4)
pool3 = MaxPooling2D((3,3), strides=2, name='POOL_3')(conv5)

# FC
f = Flatten()(pool3)
f = Dense(4096, activation='relu', name='FC_1')(f)
f = Dropout(0.5)(f)  # 논문 parameter 0.5 이용
f = Dense(4096, activation='relu', name='FC_2')(f)
f = Dropout(0.5)(f)
out = Dense(1000, activation='softmax', name='OUTPUT')(f)

model = Model(inputs=x, outputs=out)
model.summary()

 

CIFAR10 data 적용

이제는 CIFAR10 data에 적용해보겠습니다. keras 내장 데이터를 이용하였습니다. 50000개와 10가지 종류의 라벨로 이루어진 내장데이터입니다. 10개의 라벨의 종류는 비행기, 자동차, 새, 고양이, 사슴, 개, 개구리, 말, 배, 트럭이 있습니다. 내장데이터의 픽셀은 224*224*3 대신 32*32*3이기 때문에, 위 아키텍처를 그대로 적용하기에는 파라미터가 너무 많아지는 이슈가 있었습니다. 따라서 약간의 모델 파라미터 수정 후 적용하였습니다. 자세한 code는 아래 colab 링크를 참고해주세요. 

model.compile(loss='categorical_crossentropy',
              optimizer=Adam(),
              metrics=['accuracy'])

history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=10, 
                    verbose=1,
                    validation_data=(x_test, y_test))

모델링 후 다음과 같이 학습한 결과 Test Acc 약 0.71정도를 얻었습니다. 너무 적은 데이터이고, overfitting이 유발된 듯 합니다. 

AlexNet 예측 결과 

 

그래도 다음과 같이 논문에 나와있는 그래프를 그려보면, 꽤 잘 예측하고 있는 것을 확인할 수 있습니다. 자세한 code는 제 github 링크를 올려두겠습니다. 

https://github.com/daeunni/Vision_models/blob/main/AlexNet(2012).ipynb 

 

daeunni/Vision_models

CNN 기반 모델 codes 모음. Contribute to daeunni/Vision_models development by creating an account on GitHub.

github.com

 

 

 

반응형
저작자표시 (새창열림)

'Computer Vision💖 > Basic' 카테고리의 다른 글

[CV] Adversarial Learning(적대적 학습)이란? + 응용  (0) 2022.04.24
[CV] Self-supervised learning(자기주도학습)과 Contrastive learning - 스스로 학습하는 알고리즘  (4) 2021.07.02
[CV] AlexNet(2012)의 구조와 논문 리뷰  (0) 2021.06.23
[CV] ResNet - Residual Connection(잔차연결)  (0) 2021.05.04
[STAT & DL] 딥러닝의 전반적 구조에 대한 통계적 해석  (0) 2021.03.05
'Computer Vision💖/Basic' 카테고리의 다른 글
  • [CV] Adversarial Learning(적대적 학습)이란? + 응용
  • [CV] Self-supervised learning(자기주도학습)과 Contrastive learning - 스스로 학습하는 알고리즘
  • [CV] AlexNet(2012)의 구조와 논문 리뷰
  • [CV] ResNet - Residual Connection(잔차연결)
당니이
당니이
씩씩하게 공부하기 📚💻
  • 당니이
    다은이의 컴퓨터 공부
    당니이
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • Achieved 👩🏻 (14)
        • 생각들 (2)
        • TIL (6)
        • Trial and Error (1)
        • Inspiration ✨ (0)
        • 미국 박사 준비 🎓 (1)
      • Computer Vision💖 (39)
        • Basic (9)
        • Video (5)
        • Continual Learning (7)
        • Generative model (2)
        • Domain (DA & DG) (5)
        • Multimodal (8)
        • Multitask Learning (1)
        • Segmentation (1)
        • Colorization (1)
      • RL 🤖 (1)
      • Autonomous Driving 🚙 (11)
        • Geometry (4)
        • LiDAR 3D Detection (1)
        • Trajectory prediction (2)
        • Lane Detection (1)
        • HDmap (3)
      • Linux (15)
      • PyTorch👩🏻‍💻 (10)
      • Linear Algebra (2)
      • Python (5)
      • NLP (10)
        • Article 📑 (1)
      • Algorithms 💻 (22)
        • Basic (8)
        • BAEKJOON (8)
        • Programmers (2)
      • ML (1)
        • 통계적 머신러닝(20-2) (1)
      • SQL (3)
      • 기초금융 💵 (1)
  • 블로그 메뉴

    • 홈
    • About me
  • 링크

    • 나의 소박한 github
    • Naver 블로그
  • 공지사항

  • 인기 글

  • 태그

    CV
    conda
    pytorch
    Incremental Learning
    알고리즘
    til
    LLM
    domain generalization
    CL
    dfs
    코딩테스트
    자료구조
    domain adaptation
    백준
    백트래킹
    Python
    continual learning
    리눅스
    NLP
    Linux
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
당니이
[CV] AlexNet(2012) 논문을 code로 구현 해보자 (Keras, PyTorch)
상단으로

티스토리툴바