본문 바로가기

[Pytorch] MNIST 데이터셋으로 간단한 MLP구현하기 본문

AI/Pytorch

[Pytorch] MNIST 데이터셋으로 간단한 MLP구현하기

점핑노루 2021. 7. 26. 11:46

이번 글에서는 파이토치를 활용하여 MNIST dataset을 불러들인 다음, 간단한 MLP(Multi Layer Perceptron)를 생성해보도록 할 것이다. 

 

먼저 필요한 패키지들을 불러들이고 시드 설정을 한다.

import torch
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import random

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

# 시드설정
random.seed(777)
torch.manual_seed(777)
if device == 'cuda':
    torch.cuda.manual_seed_all(777)

parameter 설정도 진행한다.

epoch를 15로 설정하고, batch_size를 100으로 설정하였다. 

# parameters
training_epochs = 15
batch_size = 100

이제 MNIST 데이터셋을 training set, test set으로 각각 다운로드한다.

# MNIST dataset
mnist_train = dsets.MNIST(root='MNIST_data/',
                          train=True,
                          transform=transforms.ToTensor(), 
                          #transform은 이미지를 tensor에 맞게 조정하기 위하여 생성
                          download=True)

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

데이터셋을 다운로드한 다음 본격적으로 데이터셋을 불러들인다.

# dataset loader
data_loader = torch.utils.data.DataLoader(dataset=mnist_train, #어떤 데이터 로드할거냐
                                          batch_size=batch_size, #몇개씩 잘라서 들고올래
                                          shuffle=True, #100개 불러올 때 무작위로 불러올래?
                                          drop_last=True 
                                          #100개 씩 불러올 때 남는 게 있는데 남는 것 버릴래?)

여담으로 epoch, batch size, iteration에 대한 설명을 하고 넘어가고자 한다.

 

epoch: 모든 training example에 대한 forward pass랑 backward pass을 진행한 것.

batch size: 한 번 forward pass / backward pass할 때 사용하는 training example의 개수. MNIST의 경우 60,000개의 dataset이 있는데 이를 한 번에 forward pass / backward pass하려면 수많은 연산이 필요하기 때문에 batch size를 설정하여 나눈다.

Iteration: batch size를 기준으로 한 epoch을 진행할 때 몇 번을 반복해야 하는지에 대한 값.

 

예를 들어 내가 50,000개의 training example이 있고 batch size가 100이라면, 한 번의 epoch를 진행하기 위하여 500번의 iteration이 필요하다.

 

 

다음으로 layer 하나를 생성한다. 총 28*28 = 784개의 input값을 가지고 0-9의 총 10개의 output을 출력해야 한다. 그것을 구현하는 코드는 아래와 같다.

#MNIST data image of shape 28 * 28 = 784

linear = torch.nn.Linear(784, 10, bias = True).to(device)

cost, loss, optimizer에 대한 설정도 진행한다. Learning rate은 0.1로 설정되어 있고, stochastic gradient descent를 사용하였다.

#cost & loss 명시하기 & optimizer
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.SGD(linear.parameters(), lr = 0.1)

이제 실제로 training set을 15번 학습시켜 보자. 

for epoch in range(training_epochs):
    avg_cost = 0
    total_batch = len(data_loader)

    for X, Y in data_loader: #X에는 이미지, Y에는 0-9 숫자
        # reshape input image into [batch_size by 784]
        # label is not one-hot encoded
        X = X.view(-1, 28 * 28).to(device) #처음 크기는 B, 1, 28, 28 / 이걸 B, 784로 변환
        Y = Y.to(device)

        optimizer.zero_grad()
        hypothesis = linear(X)
        cost = criterion(hypothesis, Y)
        cost.backward()
        optimizer.step()

        avg_cost += cost / total_batch

    print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))

결과값으로 아래의 문구가 생성되는 것을 확인할 수 있다.

Epoch: 0001 cost = 0.535150588

Epoch: 0002 cost = 0.359577715

Epoch: 0003 cost = 0.331264287

Epoch: 0004 cost = 0.316404700

Epoch: 0005 cost = 0.307107002

Epoch: 0006 cost = 0.300456524

Epoch: 0007 cost = 0.294933408

Epoch: 0008 cost = 0.290956199

Epoch: 0009 cost = 0.287074119

Epoch: 0010 cost = 0.284515619

Epoch: 0011 cost = 0.281914055

Epoch: 0012 cost = 0.279526860

Epoch: 0013 cost = 0.277636588

Epoch: 0014 cost = 0.275874794

Epoch: 0015 cost = 0.274422765

 

epoch가 진행될수록 그 cost가 계속 감소한다. 모델이 올바르게 학습을 하는 것을 확인할 수 있다.

 

마지막으로 실제 데이터셋에 모델을 적용시키고 정확도를 알아보자.

# test model using test sets
with torch.no_grad(): #test set으로 데이터를 다룰 때에는 gradient를 주면 안된다.
    X_test = mnist_test.data.view(-1, 28 * 28).float().to(device)
    Y_test = mnist_test.targets.to(device)
    
    prediction = linear(X_test)
    correct_prediction = torch.argmax(prediction, 1) == Y_test #결과값이랑 실제값이랑 같은지 확인
    accuracy = correct_prediction.float().mean() #평균으로 전체 정확도 확인
    print('accuracy:', accuracy.item())

accuracy: 0.8883000016212463

로 약 88%의 정확도를 얻었다.

 

출처: GitHub - deeplearningzerotoall/PyTorch: Deep Learning Zero to All - Pytorch

 

GitHub - deeplearningzerotoall/PyTorch: Deep Learning Zero to All - Pytorch

Deep Learning Zero to All - Pytorch. Contribute to deeplearningzerotoall/PyTorch development by creating an account on GitHub.

github.com

 

Comments