Notice
Recent Posts
Recent Comments
Link
12-20 19:48
AI 전문가가 되고싶은 사람
(구현) ImageNet Classification with Deep Convolutional Neural Networks (PyTorch) 본문
논문
(구현) ImageNet Classification with Deep Convolutional Neural Networks (PyTorch)
Kimseungwoo0407 2024. 9. 4. 15:47https://seungwoo0407.tistory.com/48
[1] ImageNet Classification with Deep Convolutional Neural Networks(AlexNet)
https://proceedings.neurips.cc/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf
[2] Github alexnet-pytorch
https://github.com/dansuh17/alexnet-pytorch
이 자료들을 참고하여 AlexNet을 구현하는 데 필요한 개념과 기술을 이해하고, 구현 방법을 배웠다.
# 텐서(tensor) 연산, 신경망 구성, GPU 연산 등을 위한 다양한 기능을 제공
import torch
# 신경망을 구성하기 위한 모듈
import torch.nn as nn
# torch.nn의 기능을 좀 더 유연하게 사용할 수 있도록 함수형 인터페이스를 제공
import torch.nn.functional as F
class AlexNet(nn.Module):
"""
AlexNet 논문에서 제안한 레이어로 구성된 신경망 모델
"""
def __init__(self, num_classes=1000):
"""
이 신경망에 대한 레이어를 정의하고 할당
Args: num_classes : 이 모델로 예측할 클래스 수 (기본값:1000, ImageNet 데이터셋에 맞춰짐)
"""
super().__init__()
# input size : b x 3 x 227 x 227
# 원본 논문에서는 너비와 높이가 224px라고 명시되어 있지만,
# 첫 컨볼루션 레이어를 통과한 후 크기가 55 x 55가 되지 않는다.
# 따라서, 227 x 227 크기의 입력을 사용하여 55 x 55 출력을 만들어준다.
# 구성
self.net = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4), # (b x 96 x 55 x 55)
nn.ReLU(),
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, 5, padding=2), # (b x 256 x 27 x 27)
nn.ReLU(),
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, 3, padding=1), # (b x 384 x 13 x 13)
nn.ReLU(),
nn.Conv2d(256, 384, 3, padding=1), # (b x 384 x 13 x 13)
nn.ReLU(),
nn.Conv2d(256, 256, 3, padding=1), # (b x 384 x 13 x 13)
nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2), # (b x 256 x 6 x 6)
)
# classifier는 선형 레이어의 이름일 뿐이다.
# 처음 두 레이어에만 Dropout 적용
self.classifier = nn.Sequential(
nn.Dropout(p=0.5, inplace=True),
nn.Linear(in_features=(256 * 6 * 6), out_features=4096),
nn.ReLU(),
nn.Dropout(p=0.5, inplace=True),
nn.Linear(in_features=4096, out_features=4096),
nn.ReLU(),
nn.Linear(in_features=4096, out_features=num_classes),
)
self.init_bias()
# Alexnet 모델에서 각 레이어의 가중치와 편향을 초기화하는 역할
# 초기화로 신경망이 더 빠르고 안정적으로 학습 가능
def init_bias(self):
for layer in self.net:
# 해당 레이어가 nn.Conv2d인지 확인 후 True라면 가중치와 편향 초기화
if isinstance(layer, nn.Conv2d):
# 평균이 0이고 표준편차가 0.01인 정규분포에서 샘플링된 값들로 초기화
nn.init.normal_(layer.weight, mean=0, std=0.01)
# 0으로 초기화
nn.init.constant_(layer.bias, 0)
# 논문에서 Conv2d layers의 2,4,5 번째 conv layer의 편향을 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)
def forward(self, x):
"""
입력 데이터 x를 네트워크(self.net)를 통해 통과시킨다.
이 과정에서 네트워크의 각 레이어를 차례로 통과하면서 데이터를 변형하고 최종적으로 예측 결과 생성
Args : x (Tensor) : input tensor
Returns : output(Tensor) : output tensor
"""
x = self.net(x) # 통과한 후 (b, 256, 6, 6) -> 4D 텐서
x = x.view(-1, 256 * 6 * 6) # 데이터의 차원을 줄여 전결합 레이어에 입력으로 제공 4D 텐서 -> 2D 텐서
return self.classifier(x)
입력이 (b, 3, 227, 227)로 주어졌을 때 첫 번째 컨볼루션 연산 후 출력 크기를 아래 공식을 사용하여 계산해보았다.
출력 채널 수가 96으로 바뀌고 커널 크기와 스트라이드를 대입해서 계산하면 코드 내용대로 (b,96,55,55)가 나오게된다.
첫 번째 maxpool 또한 계산해보았을 때, (b,96,27,27)로 코드 내용과 일치하게 된다.
'논문' 카테고리의 다른 글
(공부용) VERY DEEP CONVOLUTIONAL NETWORKSFOR LARGE-SCALE IMAGE RECOGNITION (2) | 2024.09.07 |
---|---|
(구현) Going deeper with convolutions (3) | 2024.09.06 |
(공부용) Going deeper with convolutions (0) | 2024.09.06 |
(공부용) ImageNet Classification with Deep Convolutional Neural Networks (4) | 2024.09.03 |
(공부용) SHAP: A Unified Approach to Interpreting Model Predictions (2) | 2024.08.30 |