<jupyter_start><jupyter_text><jupyter_code># import libraries
import torch
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
from torchvision import datasets
import torchvision.transforms as transforms

# how many samples per batch to load
batch_size = 20

# convert data to torch.FloatTensor
transform = transforms.ToTensor()

# choose the training and test datasets
train_data = datasets.MNIST(root='data', train=True, download=True, transform=transform)
test_data = datasets.MNIST(root='data', train=False, download=True, transform=transform)
print(f'Train: X - {train_data.data.shape}, y - {train_data.targets.shape}')
print(f'Test: X - {test_data.data.shape}, y - {test_data.targets.shape}')
unique, counts = np.unique(train_data.targets, return_counts=True)
print(np.asarray((unique, counts)).T)
plt.imshow(train_data.data[31],cmap='gray')
plt.show()
print(f"\n\nLabel in dataset: {train_data.targets[31]}")
# Sample images for all digits

digits = np.unique(train_data.targets)
M = 30
dim = 28
fig, axs = plt.subplots(len(digits), M, figsize=(18,6))

for i,d in enumerate(digits):
    for j in range(M):
        axs[i,j].imshow(train_data.data[train_data.targets==d][j].reshape((dim,dim)), cmap='gray')
        axs[i,j].axis('off')
train_data.data[31]<jupyter_output><empty_output><jupyter_text>Normalization<jupyter_code>train_data.data = np.round(train_data.data/255, 3)
test_data.data = np.round(test_data.data/255, 3)
plt.imshow(train_data.data[31],cmap='gray')
plt.show()<jupyter_output><empty_output><jupyter_text>As you can see, normalizing doesn't affect the nature of image. It all depends on the relative values. So now we will use this flattened input layer and proceed for the next step. Creating datasets for multi-class Classification: Multi-class Classification Problem<jupyter_code># how many samples per batch to load
batch_size = 20

# convert data to torch.FloatTensor
transform = transforms.ToTensor()
# prepare data loaders
train_loader_multi = torch.utils.data.DataLoader(train_data, batch_size=batch_size)
test_loader_multi = torch.utils.data.DataLoader(test_data, batch_size=batch_size)
## Define the NN architecture
import torch.nn as nn

class MLP_multi(nn.Module):
    def __init__(self):
        super(MLP_multi, self).__init__()
        self.fc1 = nn.Linear(28 * 28, 512)
        # linear layer (n_hidden -> hidden_2)
        self.fc2 = nn.Linear(512, 512)
        # linear layer (n_hidden -> 1)
        self.fc3 = nn.Linear(512, 10)

    def forward(self, x):
        # flatten image input
        x = x.view(-1, 28 * 28)
        # add hidden layer, with relu activation function
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# initialize the MLP
model_multi = MLP_multi()
print(model_multi)
## Specify loss and optimization functions

# specify loss function
criterion_multi = nn.CrossEntropyLoss()

# specify optimizer
optimizer = torch.optim.SGD(model_multi.parameters(), lr=0.001)
# number of epochs to train the model
n_epochs = 200

model_multi.train() # prep model for training
errors = np.zeros(n_epochs)
for epoch in range(n_epochs):
    train_loss = 0.0
    # train the model
    for data, target in train_loader_multi:
        # clear the gradients of all optimized variables
        optimizer.zero_grad()
        # forward pass: compute predicted outputs by passing inputs to the model
        output = model_multi(data)
        # calculate the loss
        loss_multi = criterion_multi(output, target)
        # backward pass: compute gradient of the loss with respect to model parameters
        loss_multi.backward()
        # perform the optimization step (parameter update)
        optimizer.step()
        # update running training loss
        train_loss += loss_multi.item()*data.size(0)
        
    # print training statistics 
    # calculate average loss over an epoch
    train_loss = train_loss/len(train_loader_multi.dataset)
    errors[epoch] = train_loss
    if (epoch+1)%10 == 0:
      print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch+1, train_loss))
x = np.arange(1, len(errors)+1)
plt.plot(x, errors, label="Loss on Train set")
plt.legend()
plt.title('CE - Learning Rate = 0.001')
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.show()
test_loss = 0.0
class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))

model_multi.eval() # prep model for *evaluation*

for data, target in test_loader_multi:
    # forward pass: compute predicted outputs by passing inputs to the model
    output = model_multi(data)
    output = output.squeeze()
    # calculate the loss
    loss = criterion_multi(output, target)
    # update test loss 
    test_loss += loss.item()*data.size(0)
    # convert output probabilities to predicted class
    _, pred = torch.max(output, 1)
    # compare predictions to true label
    correct = np.squeeze(pred.eq(target.data.view_as(pred)))
    # calculate test accuracy for each object class
    for i in range(batch_size):
        label = target.data[i]
        class_correct[label] += correct[i].item()
        class_total[label] += 1

# calculate and print avg test loss
test_loss = test_loss/len(test_loader_multi.dataset)
print('Test Loss: {:.6f}\n'.format(test_loss))

for i in range(10):
    if class_total[i] > 0:
        print('Test Accuracy of %5s: %2d%% (%2d/%2d)' % (str(i), 100 * class_correct[i] / class_total[i], np.sum(class_correct[i]), np.sum(class_total[i])))
    else:
        print('Test Accuracy of %5s: N/A (no training examples)' % str(i))

print('\nTest Accuracy (Overall): %2d%% (%2d/%2d)' % (100. * np.sum(class_correct) / np.sum(class_total), np.sum(class_correct), np.sum(class_total)))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12100139082058414, 'fraction_numerical': 0.01912378303198887, 'mean_word_length': 4.037653239929948, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '149980', 'license': 'CC0-1.0', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1874, 'n_words': 506, 'path': 'Multi Layer Perceptron/Multi_class_MNIST_MLP_TA_session_Nov_27.ipynb', 'repo_name': 'arvind-maurya/AIML_CEP_2021', 'size': '5752'}