import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import torch
import torch.nn as nn
from torchvision import transforms, datasets
from torch.utils.data import DataLoader
from sklearn.metrics import confusion_matrix
plt.style.use('fivethirtyeight')
## Loading the data
ROOT_DIR = 'MNIST'
train_data = datasets.MNIST(
root = ROOT_DIR,
train = True,
transform = transforms.ToTensor(),
target_transform = None,
download = True
)
test_data = datasets.MNIST(
root = ROOT_DIR,
train = False,
transform = transforms.ToTensor(),
target_transform = None,
download = True
)
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
1.5%
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to MNIST\MNIST\raw\train-images-idx3-ubyte.gz
100.0%
Extracting MNIST\MNIST\raw\train-images-idx3-ubyte.gz to MNIST\MNIST\raw
102.8%
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 MNIST\MNIST\raw\train-labels-idx1-ubyte.gz Extracting MNIST\MNIST\raw\train-labels-idx1-ubyte.gz to MNIST\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 MNIST\MNIST\raw\t10k-images-idx3-ubyte.gz
100.0% 22.5%
Extracting MNIST\MNIST\raw\t10k-images-idx3-ubyte.gz to MNIST\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 MNIST\MNIST\raw\t10k-labels-idx1-ubyte.gz
112.7%
Extracting MNIST\MNIST\raw\t10k-labels-idx1-ubyte.gz to MNIST\MNIST\raw
train_data.data.dtype
torch.uint8
train_data.data[0]
tensor([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 18, 18, 126, 136, 175, 26, 166, 255, 247, 127, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 30, 36, 94, 154, 170, 253, 253, 253, 253, 253, 225, 172, 253, 242, 195, 64, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 49, 238, 253, 253, 253, 253, 253, 253, 253, 253, 251, 93, 82, 82, 56, 39, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 18, 219, 253, 253, 253, 253, 253, 198, 182, 247, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 80, 156, 107, 253, 253, 205, 11, 0, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 154, 253, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 253, 190, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 190, 253, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 241, 225, 160, 108, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 240, 253, 253, 119, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 186, 253, 253, 150, 27, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 93, 252, 253, 187, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 253, 249, 64, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 130, 183, 253, 253, 207, 2, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 148, 229, 253, 253, 253, 250, 182, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 114, 221, 253, 253, 253, 253, 201, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 23, 66, 213, 253, 253, 253, 253, 198, 81, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 18, 171, 219, 253, 253, 253, 253, 195, 80, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 55, 172, 226, 253, 253, 253, 253, 244, 133, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 136, 253, 253, 253, 212, 135, 132, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=torch.uint8)
plt.figure(figsize=(14,14))
sns.heatmap(train_data.data[0], annot=True,cmap="binary", fmt='d')
<AxesSubplot:>
train_data.data[0].shape
torch.Size([28, 28])
train_data.data[0].min().numpy(), train_data.data[0].max().numpy()
(array(0, dtype=uint8), array(255, dtype=uint8))
train_data.targets
tensor([5, 0, 4, ..., 5, 6, 8])
train_data.targets.dtype
torch.int64
train_data.data.shape
torch.Size([60000, 28, 28])
test_data.data.shape
torch.Size([10000, 28, 28])
BATCH=128
train_data_loader = DataLoader(dataset=train_data,
batch_size=BATCH,
shuffle=True)
test_data_loader = DataLoader(dataset=test_data,
batch_size=BATCH)
for x in test_data_loader:
print(x[0].shape)
print(x[1].shape)
break
torch.Size([128, 1, 28, 28]) torch.Size([128])
DEVICE = "cuda" if torch.cuda.is_available() else 'cpu'
DEVICE
'cuda'
# Lets define the model
class NeuralNetwork(nn.Module):
def __init__(self, in_, out_):
super(NeuralNetwork, self).__init__()
self.layers = nn.Sequential(
nn.Linear(in_, 256),
nn.ReLU(),
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, out_)
)
def forward(self, x):
return self.layers(x)
model = NeuralNetwork(784, 10)
model.to(DEVICE)
model
NeuralNetwork( (layers): Sequential( (0): Linear(in_features=784, out_features=256, bias=True) (1): ReLU() (2): Linear(in_features=256, out_features=128, bias=True) (3): ReLU() (4): Linear(in_features=128, out_features=10, bias=True) ) )
model.parameters()
<generator object Module.parameters at 0x0000012E6F8076C8>
CE_loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())
## Training loop
EPOCHS = 10
loss_ = list()
acc_ = list()
for epoch in range(EPOCHS):
print(f"Epoch: {epoch + 1}/{EPOCHS}")
for batch, data in enumerate(train_data_loader):
x = data[0].to(DEVICE)
y = data[1].to(DEVICE)
optimizer.zero_grad()
y_pred = model(x.reshape(-1, 784))
loss = CE_loss(y_pred, y)
loss_.append(loss.item())
loss.backward()
optimizer.step()
accuracy = torch.mean((torch.argmax(y_pred, 1) == y).float()).item()
acc_.append(accuracy)
if batch%100 == 0:
print(f" Batch: {batch}, Loss: {loss.item():.4f} Accuracy {accuracy:.4f}")
Epoch: 1/10 Batch: 0, Loss: 2.2782 Accuracy 0.1562 Batch: 100, Loss: 0.4222 Accuracy 0.8828 Batch: 200, Loss: 0.3204 Accuracy 0.9062 Batch: 300, Loss: 0.2486 Accuracy 0.9375 Batch: 400, Loss: 0.0994 Accuracy 0.9609 Epoch: 2/10 Batch: 0, Loss: 0.1223 Accuracy 0.9766 Batch: 100, Loss: 0.2410 Accuracy 0.9375 Batch: 200, Loss: 0.1310 Accuracy 0.9688 Batch: 300, Loss: 0.0857 Accuracy 0.9766 Batch: 400, Loss: 0.2689 Accuracy 0.9297 Epoch: 3/10 Batch: 0, Loss: 0.1029 Accuracy 0.9609 Batch: 100, Loss: 0.0605 Accuracy 0.9922 Batch: 200, Loss: 0.0692 Accuracy 0.9688 Batch: 300, Loss: 0.1476 Accuracy 0.9375 Batch: 400, Loss: 0.0451 Accuracy 0.9844 Epoch: 4/10 Batch: 0, Loss: 0.0210 Accuracy 1.0000 Batch: 100, Loss: 0.1263 Accuracy 0.9609 Batch: 200, Loss: 0.1378 Accuracy 0.9531 Batch: 300, Loss: 0.0634 Accuracy 0.9688 Batch: 400, Loss: 0.0503 Accuracy 0.9844 Epoch: 5/10 Batch: 0, Loss: 0.0268 Accuracy 0.9844 Batch: 100, Loss: 0.0760 Accuracy 0.9844 Batch: 200, Loss: 0.0117 Accuracy 1.0000 Batch: 300, Loss: 0.0502 Accuracy 0.9766 Batch: 400, Loss: 0.0473 Accuracy 0.9844 Epoch: 6/10 Batch: 0, Loss: 0.0262 Accuracy 0.9922 Batch: 100, Loss: 0.0283 Accuracy 0.9844 Batch: 200, Loss: 0.0182 Accuracy 1.0000 Batch: 300, Loss: 0.0399 Accuracy 0.9844 Batch: 400, Loss: 0.0199 Accuracy 0.9922 Epoch: 7/10 Batch: 0, Loss: 0.0311 Accuracy 0.9922 Batch: 100, Loss: 0.0423 Accuracy 0.9844 Batch: 200, Loss: 0.0331 Accuracy 0.9844 Batch: 300, Loss: 0.0391 Accuracy 0.9922 Batch: 400, Loss: 0.0644 Accuracy 0.9766 Epoch: 8/10 Batch: 0, Loss: 0.0017 Accuracy 1.0000 Batch: 100, Loss: 0.0111 Accuracy 1.0000 Batch: 200, Loss: 0.0039 Accuracy 1.0000 Batch: 300, Loss: 0.0253 Accuracy 0.9922 Batch: 400, Loss: 0.0436 Accuracy 0.9922 Epoch: 9/10 Batch: 0, Loss: 0.0477 Accuracy 0.9688 Batch: 100, Loss: 0.0091 Accuracy 1.0000 Batch: 200, Loss: 0.0116 Accuracy 0.9922 Batch: 300, Loss: 0.0184 Accuracy 0.9922 Batch: 400, Loss: 0.0287 Accuracy 0.9844 Epoch: 10/10 Batch: 0, Loss: 0.0038 Accuracy 1.0000 Batch: 100, Loss: 0.0092 Accuracy 1.0000 Batch: 200, Loss: 0.0074 Accuracy 1.0000 Batch: 300, Loss: 0.0030 Accuracy 1.0000 Batch: 400, Loss: 0.0103 Accuracy 1.0000
# plot the Train acc and loss
# plt.figure(figsize=(14,14))
pd.DataFrame(data={'loss': loss_, "Accuracy": acc_}).plot(figsize=(10,5))
<AxesSubplot:>
# testing over the test data
test_loss = 0
test_acc = 0
with torch.no_grad():
for batch, data in enumerate(test_data_loader):
x = data[0].to(DEVICE)
y = data[1].to(DEVICE)
y_pred = model(x.reshape(-1, 784))
loss = CE_loss(y_pred, y)
test_loss += loss.item()
test_acc += torch.mean((torch.argmax(y_pred, 1) == y).float()).item()
batch+=1
print(f"test loss: {test_loss/batch:.4f}, test accuracy: {test_acc/batch:.4f}")
test loss: 0.0729, test accuracy: 0.9812
pred = np.array([])
target = np.array([])
with torch.no_grad():
for batch, data in enumerate(test_data_loader):
x = data[0].to(DEVICE)
y = data[1].to(DEVICE)
y_pred = model(x.reshape(-1, 784))
loss = CE_loss(y_pred, y)
pred = np.concatenate((pred, torch.argmax(y_pred, 1).cpu().numpy()))
target = np.concatenate((target, y.cpu().numpy()))
cm = confusion_matrix(target, pred)
plt.figure(figsize=(12, 10))
sns.heatmap(cm, annot=True, fmt='d')
<AxesSubplot:>