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')
# 모델 파라미터 저장
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}")