본문 바로가기
Computer Science/Deep Learning

CNN(합성곱 신경망) ④ [Digits]

by BaekDaBang 2024. 4. 17.

CNN을 사용한 이미지 분류

인공지능 분류 문제에 대표적으로 사용되는 MNIST 손글씨 데이터셋을 사용
본 데이터셋은 28x28 형태의 이미지 데이터를 1D로 펼친, 총 784차원의 1D vector 형태로 표현
CNN 학습을 위해서는 1D 형태의 데이터를 2D형태로 변환
0~9, 총 10개 class 중 하나로 분류

 

Baseline 정보

epochs = 1
batch_size = 128
lr=1e-3
optimizer: Adam

 

0. 필요한 함수 Import

import numpy as np
import pandas as pd
import torch
from tqdm import tqdm
import random
import os

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.iloc[:,0]
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,1,28,28)
x_test = x_test.reshape(-1,1,28,28)

 

2. Model

import torch.nn as nn

class CNN(nn.Module):
    def __init__(self, out_ch):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1,32,3,1,1)
        self.conv2 = nn.Conv2d(32,64,3,1,1)
        self.pool = nn.MaxPool2d(2, 2)
        self.relu = nn.ReLU()
        
        self.fc1 = nn.Linear(7*7*64, 1024)
        self.fc2 = nn.Linear(1024, out_ch)
        
        self.layers = nn.Sequential(self.conv1, 
                                    self.pool, 
                                    self.relu, 
                                    self.conv2, 
                                    self.pool, 
                                    self.relu)
        
    def forward(self, x):
        out = self.layers(x)
        out = out.reshape(out.shape[0], -1)
        out = self.fc1(out)
        out = self.fc2(out)
        return out
# 하이퍼파라미터
import torch.nn as nn
import torch.optim as optim

device = 'cuda' if torch.cuda.is_available() else 'cpu'

epochs = 1
batch_size = 128
lr = 1e-3

model = CNN(out_ch=10)
model = model.to(device)

optimizer = optim.Adam(model.parameters(), lr=lr)
loss_fn = nn.CrossEntropyLoss()

 

3. Train

# Dataset & Dataloader
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)
model.train()

for epoch in range(epochs):
    avg_loss = 0
    
    for x, y in tqdm(train_dataloader):
        x = x.to(device)
        y = y.to(device)
        
        pred = model(x)
        
        loss = loss_fn(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        avg_loss += loss
        
    print(f'epoch:{epoch+1}, avg_loss:{avg_loss/len(train_dataloader)}')

 

4. Eval

model.eval()
preds = []

with torch.no_grad():
    for x in tqdm(test_dataloader):
        x = x[0].to(device)
        pred = model(x)
        pred = torch.argmax(torch.softmax(pred, dim=1), dim=1)
        preds.extend(pred.detach().cpu().numpy())

 

5. Submit

submit = pd.read_csv('')
submit['label'] = preds
submit.to_csv("submission.csv",index=False)