Deep Learning/Pytorch

[Pytorch] Implementation of neural network - MNIST

jstar0525 2022. 1. 18. 23:44
반응형

Implementation of neural network - MNIST


 

 

Test on Google colab

 

import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
device = torch.device("cuda:0")

 

 

Data preparation

train_data = datasets.MNIST(root="data", train=True, download=True, transform=ToTensor())
test_data = datasets.MNIST(root="data", train=False, download=True, transform=ToTensor())
'''
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to data/MNIST/raw/train-images-idx3-ubyte.gz
9913344/? [00:00<00:00, 49053701.97it/s]
Extracting data/MNIST/raw/train-images-idx3-ubyte.gz to data/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to data/MNIST/raw/train-labels-idx1-ubyte.gz
  0%|          | 0/28881 [00:00<?, ?it/s]
Extracting data/MNIST/raw/train-labels-idx1-ubyte.gz to data/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to data/MNIST/raw/t10k-images-idx3-ubyte.gz
  0%|          | 0/1648877 [00:00<?, ?it/s]
Extracting data/MNIST/raw/t10k-images-idx3-ubyte.gz to data/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to data/MNIST/raw/t10k-labels-idx1-ubyte.gz
  0%|          | 0/4542 [00:00<?, ?it/s]
Extracting data/MNIST/raw/t10k-labels-idx1-ubyte.gz to data/MNIST/raw

/usr/local/lib/python3.7/dist-packages/torchvision/datasets/mnist.py:498: UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at  /pytorch/torch/csrc/utils/tensor_numpy.cpp:180.)
  return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)
'''
print('Train data')
print(train_data)
print('\nTest data')
print(test_data)
'''
Train data
Dataset MNIST
    Number of datapoints: 60000
    Root location: data
    Split: Train
    StandardTransform
Transform: ToTensor()

Test data
Dataset MNIST
    Number of datapoints: 10000
    Root location: data
    Split: Test
    StandardTransform
Transform: ToTensor()
'''
figure = plt.figure(figsize=(8,8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):
    sample_idx = torch.randint(len(train_data), size=(1,)).item()
    img, label = train_data[sample_idx]
    figure.add_subplot(rows, cols, i)
    plt.title(label)
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
plt.show()

 

 

 

Data handling

from torch.utils.data import DataLoader
train_loader = DataLoader(dataset=train_data, batch_size=64, shuffle=True)
for itr, data in enumerate(train_loader):
    inputs, labels = data
    if itr < 3:
        print(inputs.shape)
        print(labels)
    else:
        break
'''
torch.Size([64, 1, 28, 28])
tensor([9, 8, 8, 2, 1, 5, 1, 5, 0, 3, 5, 3, 7, 6, 7, 9, 5, 3, 9, 1, 8, 3, 1, 4,
        4, 2, 1, 0, 8, 0, 5, 3, 6, 2, 1, 8, 1, 8, 5, 1, 7, 4, 1, 6, 0, 6, 8, 8,
        3, 3, 6, 5, 6, 4, 3, 6, 4, 5, 8, 0, 2, 4, 6, 7])
torch.Size([64, 1, 28, 28])
tensor([8, 0, 9, 3, 5, 8, 0, 9, 4, 2, 4, 1, 4, 6, 7, 3, 6, 1, 4, 3, 9, 4, 7, 6,
        9, 5, 3, 2, 9, 7, 5, 4, 1, 2, 1, 9, 7, 6, 0, 7, 3, 2, 7, 6, 0, 2, 3, 6,
        9, 4, 6, 5, 0, 4, 5, 2, 0, 7, 7, 7, 6, 9, 4, 7])
torch.Size([64, 1, 28, 28])
tensor([0, 4, 6, 8, 7, 6, 0, 1, 9, 8, 8, 7, 9, 9, 8, 5, 2, 3, 6, 6, 3, 6, 8, 5,
        4, 5, 4, 4, 6, 1, 9, 2, 8, 1, 0, 3, 6, 4, 9, 3, 1, 9, 5, 6, 9, 5, 2, 3,
        1, 5, 8, 8, 9, 4, 9, 8, 1, 8, 1, 7, 7, 2, 6, 5])
'''

 

 

Defining a neural network architecture

import torch.nn as nn
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(28*28, 256)
        self.fc2 = nn.Linear(256, 64)
        self.fc3 = nn.Linear(64, 10)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = x.view(-1, 28*28)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.fc3(x)
        return x
net = Net().to(device)

 

 

 

Loss function and optimization method

loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)

 

 

 

Training of the neural network

epochs = 20
for epoch in range(epochs):
    loss_val = 0
    for itr, data in enumerate(train_loader):
        optimizer.zero_grad()

        inputs, labels = data
        inputs = inputs.to(device)
        labels = labels.to(device)

        pred = net(inputs)
        loss = loss_function(pred, labels)

        loss.backward()
        optimizer.step()

        loss_val += loss.item()

    print("Loss: ", loss_val)
'''
Loss:  291.23475413396955
Loss:  110.66450749710202
Loss:  73.69272309355438
Loss:  53.92451313463971
Loss:  40.2492032176815
Loss:  31.88669986347668
Loss:  24.2587858219631
Loss:  20.282621471909806
Loss:  17.285471402545227
Loss:  13.22620633563929
Loss:  12.68102501820249
Loss:  11.48952171529163
Loss:  11.357580995196258
Loss:  7.689835874407436
Loss:  7.60085178202462
Loss:  9.695819585568643
Loss:  7.592285992230245
Loss:  8.172642898866798
Loss:  6.829944440782583
Loss:  7.903863435974017
'''

 

 

 

Prediction and Evaluation for test dataset

input_test = test_data.data.float().to(device)
pred_test = net(input_test/255)
pred_test
'''
tensor([[-18.1005,  -6.5428,  -5.7429,  ...,  20.9222, -16.0087,  -5.9107],
        [-14.4440,  -0.6475,  27.4582,  ..., -13.4923, -11.0311, -33.6244],
        [-17.8230,  15.2050,  -3.6073,  ...,  -3.8482,  -0.4223, -15.9623],
        ...,
        [-28.4406, -10.7480, -23.2694,  ...,  -4.6167, -10.4216,   2.0327],
        [-17.3524, -14.6312, -24.4655,  ...,  -9.3538,   1.8884, -15.0334],
        [ -5.1409, -15.0703,  -7.9359,  ..., -26.5572,  -9.7768, -16.2914]],
       device='cuda:0', grad_fn=<AddmmBackward>)
'''
pred_category = torch.argmax(pred_test, dim=1)
pred_category  # tensor([7, 2, 1,  ..., 4, 5, 6], device='cuda:0')
label_test = test_data.targets.to(device)
accuracy = torch.mean((pred_category == label_test).float())
accuracy  # tensor(0.9812, device='cuda:0')
반응형