반응형
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')
반응형