Baseline 정보
GPU : T4x2
모델
- resnet50 사용
- IMAGENET1K_V1 으로 가중치 초기화
- 최종 분류기의 output 차원을 class 수에 맞게 변경
from torchvision.models import resnet50, ResNet50_Weights
# ImageNet 데이터로 사전학습시킨 가중치를 불러오기.
model = resnet50(weights=ResNet50_Weights.IMAGENET1K_V1)
epochs = 3
batch_size = 128
lr=1e-3
optimizer: SGD
데이터 증강 기법
우선 255로 나눠서 0~1 범위로 만들기
아래 Data Augmentation 기법을 사용하였으며, pytorch 공식 documentation을 참고
https://pytorch.org/vision/stable/transforms.html
<학습>
i) Resize(224x224) & Random Crop
ii) Horizontal Flip (p=0.5)
iii) Dtype torch.float32로 변경
iv) mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225]
<평가>
i) Resize(224x224)
ii) Dtype torch.float32로 변경
iii) mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225]
유의사항
기존 32x32 의 이미지를 224x224로 interpolation 후 학습을 진행하다 보니 학습 시간이 3epoch 기준 약 30분정도 소요
data의 차원 순서를 고려
- 기존 3072 차원의 1D data는 (Width, Height, Channel) - (32,32,3) 을 펼친 형태
- 이를 torch의 이미지 형태인 (Channel, Height, Width) - (3,32,32) 꼴로 변경해야 함
0. 필요한 함수 Import
import numpy as np
import pandas as pd
import torch
from tqdm import tqdm
import random
import os
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 램덤시드 고정
random_seed= 42
random.seed(random_seed)
np.random.seed(random_seed)
os.environ["PYTHONHASHSEED"] = str(random_seed)
torch.manual_seed(random_seed)
torch.cuda.manual_seed(random_seed)
torch.cuda.manual_seed_all(random_seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
torch.use_deterministic_algorithms(False)
1. Dataset
# Load Dataset
train = pd.read_csv('')
test = pd.read_csv('')
# Preprocessing
x_train = train.iloc[:,:-1]
y_train = train['label']
x_test = test
x_train = torch.FloatTensor(np.array(x_train))
y_train = torch.LongTensor(np.array(y_train))
x_test = torch.FloatTensor(np.array(x_test))
x_train = x_train.reshape(-1,3,32,32) # (50000,3,32,32)
x_test = x_test.reshape(-1,3,32,32) # (10000,3,32,32)
2. Model
%pip install torchsummary
import torch.nn as nn
from torchvision.models import resnet50, ResNet50_Weights
from torchsummary import summary as summary_
model = resnet50(weights=ResNet50_Weights.IMAGENET1K_V1)
model.fc = nn.Linear(2048,10)
model = model.to(device)
summary_(model,(3,224,224))
# 하이퍼파라미터
import torch.optim as optim
from torch.nn import CrossEntropyLoss
epochs = 1
batch_size = 128
lr = 1e-3
optimizer = optim.SGD(model.parameters(), lr=lr)
loss_fn = CrossEntropyLoss().to(device)
3. Train
# Transformation
from torchvision.transforms import v2
train_transform = v2.Compose([
v2.RandomResizedCrop(size=(224, 224), antialias=True),
v2.RandomHorizontalFlip(p=0.5),
v2.ToDtype(torch.float32, scale=True),
v2.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
test_transform = v2.Compose([
v2.Resize(size=(224, 224)),
v2.ToDtype(torch.float32, scale=True),
v2.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# 데이터를 배치 단위로 불러오기 위한 dataset과 dataloader 정의
from torchvision.transforms import transforms
from torchvision import utils
from torch.utils.data import TensorDataset, DataLoader
train_dataset = TensorDataset(x_train, y_train)
test_dataset = TensorDataset(x_test)
train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=1, shuffle=False)
# Train
model.train()
display_freq = 100
for epoch in range(epochs):
train_loss = 0
correct = 0
avg_loss = 0
for x,y in tqdm(train_dataloader):
x = train_transform(x)
x = x.to(device)
y = y.to(device)
pred = model(x)
loss = loss_fn(pred, y.squeeze(-1))
optimizer.zero_grad()
loss.backward()
optimizer.step()
pred = pred.data.max(1, keepdim=True)[1]
correct += pred.cpu().eq(label.data.view_as(pred)).sum()
if i % display_freq == 0:
print(f'iter:{i}, loss:%.3f' %(loss))
avg_loss += loss
train_loss /= len(train_dataloader)
train_accuracy = correct / len(train_dataloader.dataset)
print(f'epoch:{epoch+1}, train_loss:{}, avg_loss:{avg_loss/len(train_dataloader)}')
print(f'loss: {train_loss: .5f} - acc: {train_accuracy: .5f}')
4. Eval
# Eval
preds = list()
with torch.no_grad():
model.eval()
for x in tqdm(test_dataloader):
x = preprocess(x[0])
x = x.to(device)
pred = ((model(x).softmax(dim=-1)).argmax(dim=-1))[0]
preds.append(pred.cpu())
5. Submit
submit = pd.read_csv('')
submit['label'] = np.array(preds)
submit.to_csv('submission.csv', index=False)
'Computer Science > Deep Learning' 카테고리의 다른 글
고급 합성곱 신경망 ② (0) | 2024.04.17 |
---|---|
고급 합성곱 신경망 ① (0) | 2024.04.17 |
하이퍼파라미터 튜닝 ① (1) | 2024.04.17 |
CNN(합성곱 신경망) ④ [Digits] (0) | 2024.04.17 |
CNN(합성곱 신경망) ③ [CIFAR-10] (0) | 2024.04.14 |