티스토리 뷰
목차
이번에는 MobileNet V1을 직접 구현해보았다. 확실히 ResNet, VGGNet보다 학습속도가 빠르다는 것을 확인할 수 있었다.
1. Setup
이전 구현과 똑같이 세팅을 했다.
import torch.nn as nn
import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import torch.optim as optim
import time
import numpy as np
import random
import torch.backends.cudnn as cudnn
seed = 2022
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
np.random.seed(seed)
cudnn.benchmark = False
cudnn.deterministic = True
random.seed(seed)
2. Depthwise Separable Conv
Pytorch에서는 nn.Conv2d 의 parameter로 groups가 있으며 친절하게 Depthwise Conv를 적용하는 방법까지 공식문서에서 제공해준다 다음 링크를 참고해서 작성했다.
Separable은 Pointwise Conv이므로 1x1 Conv로 처리했다.
참고로 torch버전은 1.10.1으로 구현했다.
https://pytorch.org/docs/1.10.1/generated/torch.nn.Conv2d.html?highlight=depthwise
class DWConv(nn.Module):
def __init__(self, in_channels, multiplier, stride, padding = 1):
super(DWConv, self).__init__()
self.stride = stride
self.padding = padding
self.in_channels = in_channels
self.multiplier = multiplier
self.out_channels = self.in_channels * self.multiplier
self.DW = nn.Sequential(
nn.Conv2d(in_channels=self.in_channels,
out_channels=self.out_channels,
groups=self.in_channels,
kernel_size = 3,
stride = self.stride,
padding = self.padding),
nn.BatchNorm2d(self.out_channels),
nn.ReLU(),
nn.Conv2d(in_channels = self.out_channels,
out_channels=self.out_channels,
kernel_size=1,
stride=1),
nn.BatchNorm2d(self.out_channels),
nn.ReLU()
)
def forward(self, x):
x = self.DW(x)
return x
3. Conv 3x3
MobileNet v1 전체 아키텍쳐에는 일반 Conv 3x3도 적용되므로 class로 선언해주었다.
class conv3x3(nn.Module):
def __init__(self, in_channels, out_channels, stride, padding):
super(conv3x3, self).__init__()
self.in_channels = in_channels
self.out_channels = out_channels
self.net = nn.Sequential(
nn.Conv2d(
in_channels=self.in_channels,
out_channels=self.out_channels,
stride = stride,
padding = padding,
kernel_size=3
),
nn.BatchNorm2d(self.out_channels),
nn.ReLU()
)
def forward(self, x):
x = self.net(x)
return x
4. MobileNet v1
깔끔하지는 않지만 논문에 제시한대로 그대로 구현하려고 노력했다.
class MobileNetV1(nn.Module):
def __init__(self, in_channels, num_classes):
super(MobileNetV1, self).__init__()
self.features = nn.Sequential(
conv3x3(in_channels, 32, 2, 1),
DWConv(32, 1, 1),
conv3x3(32, 64, 1, 1),
DWConv(64, 1, 2),
conv3x3(64, 128, 1, 1),
DWConv(128, 1, 2),
conv3x3(128, 256, 1, 1),
DWConv(256, 1, 1),
conv3x3(256, 256, 1, 1),
DWConv(256, 1, 2),
conv3x3(256, 512, 1, 1),
DWConv(512, 1, 1),
conv3x3(512, 512, 1, 1),
DWConv(512, 1, 1),
conv3x3(512, 512, 1, 1),
DWConv(512, 1, 1),
conv3x3(512, 512, 1, 1),
DWConv(512, 1, 1),
conv3x3(512, 512, 1, 1),
DWConv(512, 1, 1),
conv3x3(512, 512, 1, 1),
DWConv(512, 1, 2),
conv3x3(512, 1024, 1, 1),
DWConv(1024, 1, 2),
conv3x3(1024, 1024, 1, 1)
)
self.avgpool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Linear(in_features=1024, out_features=num_classes)
self.softmax = nn.Softmax(dim = 1)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = x.squeeze()
x = self.fc(x)
x = self.softmax(x)
return x
이후 CIFAR-10 으로 테스트 했을 때 0.553으로 그리 높지는 않으나 epoch을 20으로 했던 점과 학습속도가 빠르다는 점에서 의의가 있다는 것을 직접 확인할 수 있었다.
전체 코드는 다음 github 링크를 참고하면 된다.
참고논문 - https://arxiv.org/abs/1704.04861
'AI' 카테고리의 다른 글
[논문 리뷰] MobileNet V2 간단 리뷰!! (0) | 2022.08.25 |
---|---|
[논문 구현] ShuffleNet v1 직접 구현해보기 (0) | 2022.08.24 |
[논문 리뷰] ShuffleNet v1에 대해서 간단하게 알아보기 (0) | 2022.08.23 |
[논문 리뷰] MobileNet v1에 대해서 간단하게 알아보기 (0) | 2022.08.22 |
[논문 리뷰] EfficientNet 간단하게 리뷰하기! (0) | 2022.08.02 |