새소식

딥러닝/이미지 처리

AlexNet

  • -

AlexNet 

AlexNet은 ILSVRC 2012 대회에서 우승을 차지한 합성곱 신경망이다.

 

 

 

CIFAR10 데이터를 적용할 AlexNet 구현

AlexNet은 1000개의 클래스로 분류되어 있는 227X227의 크기를 갖는 이미지로 이루어진 ImageNet 데이터를 위해 만들어졌다.
따라서 CIFAR10 이미지 데이터에 맞게 Filter의 크기와 Stride를 조정해 모델을 구축하였다.

 

라이브러리 로드

import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import matplotlib.pyplot as plt

 

데이터 세트 로드

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])
# transforms.Normalize()는 특정 평균과 표준편차를 따르는 정규분포를 통해 이미지를 표준화하는 방법
# CIFAR은 3채널 컬러 이미지이므로 각 채널의 평균과 표준편차를 정한다.
# 평균과 표준편차는 학습 전에 갖고 있는 이미지로부터 계산한다.
# ImageNet Pytorch 공식 정규화 값을 사용하였다.

train_set = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_set, batch_size=32, shuffle=True)

test_set = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
test_loader = DataLoader(test_set, batch_size=32, shuffle=False)

 

GPU 체크

device = torch.device("cuda:0" if torch.cuda.is_available() else "CPU")
print(f'{device} is available now')

 

AlexNet 구축

class AlexNet(nn.Module):
  def __init__(self):
    super(AlexNet, self).__init__()
    self.features = nn.Sequential(
       nn.Conv2d(3, 64, kernel_size=3), nn.ReLU(inplace=True),
       nn.MaxPool2d(kernel_size=2, stride=2),
       nn.Conv2d(64, 192, kernel_size=3, padding=1), nn.ReLU(inplace=True),
       nn.MaxPool2d(kernel_size=3, stride=2), 
       nn.Conv2d(192, 384, kernel_size=3, padding=1), nn.ReLU(inplace=True),
       nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True),
       nn.Conv2d(256, 256, kernel_size=1), nn.ReLU(inplace=True),
       nn.MaxPool2d(kernel_size=2, stride=2) 
    )

    self.classifier = nn.Sequential(
        nn.Dropout(0.5),
        nn.Linear(256*3*3, 1024), nn.ReLU(inplace=True),
        nn.Dropout(0.5),
        nn.Linear(1024,512),nn.ReLU(inplace=True),
        nn.Linear(512,10)
    )

  def forward(self,x):
    x = self.features(x)
    x = x.view(-1,256*3*3)
    x = self.classifier(x)
    return x

from torchsummary import summary 

summary(alexnet, (3,32,32), batch_size=32) # (channel, H, W)

 

Cost Function과 Optimizer 정의

criterion = nn.CrossEntropyLoss()
alexnet = AlexNet().to(device)
optimizer = optim.Adam(alexnet.parameters(), lr=1e-3)

 

모델 학습

loss_ = []

n = len(train_loader) # 배치 개수
for epoch in range(50):
  running_loss = 0.0
  for data in train_loader:
    inputs, labels = data[0].to(device), data[1].to(device)
    optimizer.zero_grad()

    outputs = alexnet(inputs)
    loss = criterion(outputs, labels)

    loss.backward() 
    optimizer.step()
    running_loss += loss.item()

  loss_.append(running_loss/n)
  print(f'{epoch+1} loss: {running_loss / n}')

 

Training Loss 시각화

plt.plot(loss_)
plt.title("Training Loss")
plt.xlabel("epoch")
plt.show()

모델 저장 및 불러오기

# 모델 파라미터 저장
PATH = './models/cifar_alexnet.pth'
torch.save(alexnet.state_dict(), PATH)
# 모델 불러오기
alexnet = AlexNet().to(device) # 모델을 우선 선행적으로 선언
alexnet.load_state_dict(torch.load(PATH)) # 모델 파라미터 로드

 

평가

correct = 0
total = 0

with torch.no_grad():
  alexnet.eval()
  for data in test_loader:
    images, labels = data[0].to(device), data[1].to(device)
    outputs = alexnet(images)
    # outputs이 (배치 크기)X10인 벡터 형태로 나오기 때문에 최댓값을 열(1) 기준으로 계산
    _, predicted = torch.max(outputs,1) # torch.max는 최댓값과 최댓값의 위치를 반환하는데, 최댓값은 필요없으므로 _로 처리
    total += labels.size(0)
    correct += (predicted == labels).sum().item()

print(f"Test Accuracy: {100 * correct / total}")

Test Accuracy: 74.88

728x90

'딥러닝 > 이미지 처리' 카테고리의 다른 글

Prototypcial Networks for Few-shot Learning  (0) 2023.06.22
DenseNet  (0) 2022.07.16
ResNet  (0) 2022.07.16
GoogLeNet  (0) 2022.07.16
VGGNet  (0) 2022.06.25
Contents