CNN으로 MNIST 분류

zoya·2024년 5월 2일

인공지능 공부

목록 보기
17/19

합성곱 신경망은 합성곱 층을 부르는 단위가 통합이 되어있지는 않습니다.

1. 첫번째 표기 방법

합성곱(nn.Conv2d) + 활성화 함수(nn.ReLU)를 하나의 합성곱 층으로 보고 최대 풀링(nn.MaxPool2d)은 풀링 층으로 별도로 명명합니다.

2. 두번째 표기 방법

합성곱(nn.Conv2d) + 활성화 함수(nn.ReLU) + 최대 풀링(nn.MaxPool2d)을 하나의 합성곱 층으로 봅니다.


풀링도 하나의 층으로 보느냐 아니냐에 따라서 표기 방법에 달라지는데 편의를 위해서 최대 풀링까지 포함해 하나의 합성곱 층으로 판단하고 정리하겠습니다.

MNIST 분류를 하기 전에 기본적인 모델 구조를 구현하겠습니다.

기본적인 모델 구조 구현

import torch
import torch.nn as nn

#배치크기 x 채널 x 높이 x 너비
inputs = torch.Tensor(1, 1, 28, 28)

#입력채널 1, 출력채널 32, 필터크기 3, 패딩 1
conv1 = nn.Conv2d(1, 32, 3, padding=1)
conv2 = nn.Conv2d(32, 64, 3, padding=1)

#인자에 정수 하나를 넣으면
#커널 사이즈와 스트라이드가 정수의 값으로 지정됩니다.
pool = nn.MaxPool2d(2)

MNIST 분류

import torch
import torchvision.datasets as datasets
import torchvision.transforms as transforms
import torch.nn.init
import torch.utils.data.DataLoader as DataLoader

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

#parameters
lr = 0.001
epochs = 10
batch_size = 100

mnist_train = datasets.MNIST(root='MNIST_data/', train=True, transform=transforms.ToTensor(), download=True)
mnist_test = datasets.MNINST(root='MNIST_data/', train=False, transform=transforms.ToTensor(), download=True)

data_loader = DataLoader(dataset=mnist_train, batch_size=batch_size, shuffle=True, drop_last=True)

#class로 모델 설계
class CNN(torch.nn.Module):
	def __init__(self):
    	super(CNN, self).__init__()
        #첫번째 층
        self.layer1 = torch.nn.Sequential(
        	torch.nn.Conv2d(1, 32, 3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2, stride=2))
       	
        self.layer2 = torch.nn.Sequential(
        	torch.nn.Conv2d(32, 64, 3, stride=21, padding=1),
            torch.nn.ReLU(),
            torch.nn.Maxpool2d(kernel_size=2, stride=2))
         
        self.fc =torch.nn.Linear(7*7*64, 10, bias=True)
        torch.nn.init.xavier_uniform_(self.fc.weight)
        
    def forward(self, x):
    	out = self.layer(x)
        out = self.layer2(out)
        out = out.view(out.size(0), -1)
        out = self.fc(out)
        return out
 
 
model = CNN()
loss_fn = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
total_batch = len(data_loader)

for epoch in range(epochs):
	avg_loss = 0
    for X, Y in data_loader:
    	optimizer.zero_grad()
        predicted = model(X)
        loss = loss_fn(predicted, Y)
        loss.backward()
        optimizer.step()
        
        avg_loss += loss / total_batch
    
    print('[Epoch: {:>4}] cost = {:>.9}'.format(epoch + 1, avg_cost))


[Epoch:    1] cost = 0.224006683
[Epoch:    2] cost = 0.062186949
[Epoch:    3] cost = 0.0449030139
[Epoch:    4] cost = 0.0355709828
[Epoch:    5] cost = 0.0290450025
[Epoch:    6] cost = 0.0248527844
[Epoch:    7] cost = 0.0207189098
[Epoch:    8] cost = 0.0181982815
[Epoch:    9] cost = 0.0153046707
[Epoch:   10] cost = 0.0124179339

테스트

# 학습을 진행하지 않을 것이므로 torch.no_grad()
with torch.no_grad():
    X_test = mnist_test.test_data.view(len(mnist_test), 1, 28, 28).float().to(device)
    Y_test = mnist_test.test_labels.to(device)

    prediction = model(X_test)
    correct_prediction = torch.argmax(prediction, 1) == Y_test
    accuracy = correct_prediction.float().mean()
    print('Accuracy:', accuracy.item())
    
Accuracy: 0.9883000254631042
profile
동물을 좋아하는 개발자(희망)의 저장소

0개의 댓글