친구 과제로 나온 cifar10 acc > 0.9를 시험삼아 해봤다.
cifar10이야 클래스가 10개밖에 되지 않고 쉬운 과제라고 생각해 금방 결과가 나올 것이라 생각했다.
# -*- coding: utf-8 -*-
"""cifar10.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1vz-O_IbWNJ3gSbCdjbhB-zRbpVs8ZHf3
"""
# GPU 스펙 확인
!nvidia-smi -L
import warnings
warnings.filterwarnings("ignore")
import os
from collections import Counter
import albumentations as A
import albumentations.pytorch as AP
import cv2
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import torch
import torch. nn as nn
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms as T
from torchvision.datasets import CIFAR10
from tqdm import tqdm
"""# Sample in dataset"""
ds = CIFAR10(root='./data', train=True, download=True)
ds
# 이미지 확인
sample = ds[0][0]
print(sample.size)
plt.imshow(sample)
plt.axis(False)
plt.show()
# 이미지 사이즈가 32로 유일한 지 체크
set([img[0].size for img in ds])
# 레이블 분포가 균등한 지 확인
Counter([label[1] for label in ds])
"""# Load dataset
## Dataset
"""
def transform(img):
img = np.array(img) / 255.
t = A.Compose([
A.OneOf([
A.VerticalFlip(),
A.HorizontalFlip()]),
A.Rotate(limit=45),
A.ShiftScaleRotate(rotate_limit=20),
A.Cutout(num_holes=5, max_h_size=4, max_w_size=4, fill_value=0),
AP.ToTensorV2()
])
transformed = t(image=img)
return transformed['image']
def transform_test(img):
img = np.array(img) / 255.
t = A.Compose([
AP.ToTensorV2()
])
transformed = t(image=img)
return transformed['image']
trainds = CIFAR10(root='./data', train=True, download=True, transform=transform)
trainds
"""## DataLoader
### parameter
"""
# parameter
assert torch.cuda.is_available() # highly recommend GPU environment
device = 'cuda'
num_cls = 10
val_size = len(trainds) // 5 # 20% validation size
batch_size = 256
lr = 1e-3
epochs = 100
random_indices = np.random.randint(len(trainds), size=(len(trainds), ))
train_idx = random_indices[val_size:]
val_idx = random_indices[:val_size]
len(train_idx), len(val_idx)
train_loader = DataLoader(trainds, batch_size, num_workers=2, sampler=train_idx)
val_loader = DataLoader(trainds, batch_size, num_workers=2, sampler=val_idx)
len(train_loader), len(val_loader)
"""# Model"""
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', weights='ResNet50_Weights.IMAGENET1K_V1')
model.fc = nn.Linear(2048, num_cls)
model = model.to(device, dtype=torch.double)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
"""# Train"""
patience = 0
for epoch in range(1, epochs+1):
with tqdm(train_loader, total=len(train_loader), desc='Train ') as iterator:
num_iter = len(train_loader)
current_total_loss = 0.
model.train()
for idx, (X, y) in enumerate(iterator, start=1):
X, y = X.to(device), y.to(device)
output = model(X)
loss = loss_fn(output, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
current_total_loss += loss
loss_mean = current_total_loss / idx
log = f'loss: {loss_mean:.4f} epoch: {epoch}'
iterator.set_postfix_str(log)
best_val_loss = np.Inf
model.eval()
with torch.no_grad():
with tqdm(val_loader, total=len(val_loader), desc='Validation ') as iterator:
num_iter = len(val_loader)
num_ds = len(val_idx)
total_loss = 0.
acc = 0.
model.train()
for X, y in iterator:
X, y = X.to(device), y.to(device)
output = model(X)
acc += (output.argmax(1) == y).cpu().sum().item()
loss = loss_fn(output, y)
total_loss += loss
log = f'loss: {total_loss/num_iter:.4f} accuracy: {acc/num_ds*100:.2f}%'
iterator.set_postfix_str(log)
if best_val_loss > total_loss:
patience = 0
best_val_loss = total_loss
if best_val_loss <= total_loss:
patience += 1
if patience > 4:
break
scheduler.step()
print()
testds = CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testds
test_loader = DataLoader(testds, batch_size)
len(test_loader)
Test dataset Accuracy : 0.8304
acc = 0.
model.eval()
with torch.no_grad():
for X, y in test_loader:
X, y = X.to(device), y.to(device)
output = model(X)
acc += (output.argmax(1)==y).cpu().sum().item()
acc /= len(test_loader.dataset)
acc # 0.8304
Why is my validation loss lower than my training loss?
loss function & optimization & regularization의 관계
이 셋의 관계가 뚜렷하게 머리에 그려지지 않는다.
crossentropy loss in pytorch
수식으로 이해하고 싶은 것
최종적으로 완성할 것