일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- LSTM
- machine learning
- PANDAS
- C++
- 국민대
- db
- 국민대학교
- googleapiclient
- gan
- programmers
- 재귀
- GIT
- Python
- python3
- 정렬
- 스택
- 운영체제
- kmu
- instaloader
- Seq2Seq
- Stack
- 파이썬
- Regression
- 머신 러닝
- SQL
- 프로그래머스
- OS
- 데이터베이스
- Heap
- 회귀
- Today
- Total
정리 노트
AlexNet with Pytorch 본문
이 글에서는 pytorch를 이용해서 AlexNet을 구현해보려 합니다. 모델을 학습시키고 평가하는 과정은 제가 저번에 적었던 글에 있는 것을 그대로 다시 사용합니다.
2022.11.14 - [구현] - CNN with Pytorch
CNN with Pytorch
CNN의 개념을 알고 싶은 분들은 제가 저번에 적어놓은 글을 읽어보셔도 됩니다. CNN이란 무엇인가? 2022.08.29 - [개념 정리/머신러닝 & A.I] - CNN(Convolutional Neural Network) 여기서 작성된 코드는 거의 Pytorc
study-note-99.tistory.com
AlexNet 구조 알아보기
Pytorch에서는 수많은 CNN 구조의 딥러닝 모델들을 제공하고 있습니다. AlexNet 모델 역시 pytorch에서 제공하고 있습니다.
import torchvision
alexnet = torchvision.models.alexnet(pretrained=True)
print(alexnet)
pretrained를 True 값으로 하면 ImageNet 데이터셋으로 학습이 미리 진행된 모델을 불러올 수 있습니다. 구조를 보면 아래와 같습니다.

크게 3가지로 나눠서 볼 수 있을 것 같습니다.
- features: convolution과 activation fucntion, pooling layer를 연속적으로 거치며 이미지의 특징을 학습하는 구간
- avgpool: output_size만큼의 출력이 나오도록 average pooling 작업을 거치는 layer
- classifier: dropout과, linear 연산, activation function을 연속적으로 거치며 이미지를 분류하는 구간
Convolution층들을 거칠 때는 kernel size를 11부터 시작해서 절반씩 줄이다가 3으로 유지하는 것을 볼 수 있고, 활성화 함수로는 ReLU, max pooling 기법을 사용하고 있음을 알 수 있습니다. 사실 이 구조에서 마지막 out_features 1000에 대해 softmax 함수가 적용되는 레이어도 있어야 합니다. 하지만 위의 구조를 보면 softmax 레이어를 딱히 정의하지 않았습니다. 이에 대한 답변은 아래의 사이트에서 찾을 수 있었습니다.
https://discuss.pytorch.org/t/torchvision-models-dont-have-softmax-layer/18071
Torchvision models dont have softmax layer?
In the torchvision models vgg code:https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py there is not a softmax layer in this code ,but in the original paper the last layer is a softmax layer,why dose it happen? if I use pretrained
discuss.pytorch.org
Torchvisioin의 모델들은 모두 nn.CrossEntropyLoss()를 사용해 학습된다고 합니다. nn.CrossEntropyLoss()를 보면 log softmax가 포함되어 있습니다. 따라서 모델의 구조를 정의할 때 softmax 층이 없습니다. 그래서 모델을 학습시킬 때 cross entropy loss를 사용해야 합니다.
AlexNet 구조를 변경하고 싶은 경우
torchvision에서 제공하는 모델들은 ImageNet 데이터셋에 대해 학습하는 모델들이기 때문에 최종적으로 1000개의 class에 대한 분류를 진행합니다. 만약, 이 모델을 CIFAR-10 데이터셋에 대해 학습을 진행해야 하는 상황이 온다면 classifier의 마지막 구조를 바꿔야 합니다. 이러한 경우 torchvision에서 가져온 모델의 구조를 바꾸는 방법이 있습니다.
import torchvision
import torch.nn as nn
alexnet = torchvision.models.alexnet(pretrained=True)
in_features = alexnet.classifier[6].in_features
alexnet.classifier[6] = nn.Linear(in_features, 10)
AlexNet에서 사용되는 파라미터의 수
AlexNet에서 사용될 파라미터의 수를 살펴봅시다. Input의 size가 227 * 227로 생각하고 model이 만들어졌기 때문에 이를 생각하시면서 output shape의 변화를 보시면 됩니다.

합성곱 층들에서 사용된 파라미터의 수는 (23,296 + 307,392 + 663,936 + 884,992 + 590,080) = 2,469,696개입니다. 얼추 반올림하면 247만 개나 되어 많아 보입니다. 하지만 fully-connected layer들에서 사용되는 파라미터 수는 (37,352,832 + 16,781,312 + 4,097,000) = 58,231,144개로 약 23.58배 많은 것을 알 수 있습니다.
Pytorch로 AlexNet 구조 따라 만들어보기
import torch
import torch.nn as nn
import torch.nn.functional as F
class AlexNet(nn.Module):
def __init__(self):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, stride=1, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2)
)
self.avg_pool = nn.AdaptiveAvgPool2d(output_size=6)
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256 * 6 * 6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, 1000)
)
def forward(self, x):
x = self.features(x)
x = self.avg_pool(x)
x = x.view(-1, 256 * 6 * 6)
x = self.classifier(x)
return x
nn.Sequential을 통해 여러 레이어들을 묶어서 저장할 수 있습니다. 따라서 forward 함수를 작성할 때 이전 글처럼
x = self.pooling(self.relu(self.conv1(x))), x = self.pooling(self.relu(self.conv2(x))),... 형태로 작성할 필요 없이
x = self.features(x) 한 줄로 코드를 깔끔하게 작성할 수 있게 됩니다.
'구현' 카테고리의 다른 글
CNN with Pytorch (0) | 2022.11.14 |
---|