<jupyter_start><jupyter_text>transforms.Compose()* ToTensor() : Converts PIL Image to a tensor. Value range [0, 255] --> [0, 1]* Normalize(mean , std) : Normalizes data of each channel according to mean and standard deviation provided<jupyter_code>class Classifier(nn.Module):
    
  def __init__(self):
    
    super().__init__()
    self.fc1 = nn.Linear(784, 512)
    self.fc2 = nn.Linear(512, 256)
    self.fc3 = nn.Linear(256, 128)
    self.fc4 = nn.Linear(128, 64)
    self.fc5 = nn.Linear(64, 10)
  
    self.dropout = nn.Dropout(p=0.3)
  def forward(self, x):
    
    x = x.view(x.shape[0], -1)
    x = self.dropout(F.relu(self.fc1(x)))
    x = self.dropout(F.relu(self.fc2(x)))
    x = self.dropout(F.relu(self.fc3(x)))
    x = self.dropout(F.relu(self.fc4(x)))
    x = F.log_softmax(self.fc5(x), dim=1)

    return x
model = Classifier()

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adagrad(model.parameters(), lr = 0.01, lr_decay = 1e-3)
images, labels = next(iter(trainloader))

epochs = 15
train_log, test_log = [], []

for epoch in range(epochs):
  running_loss = 0
  
  for images, labels in trainloader:
    # Flatten the images
    images = images.view(images.shape[0], -1)
    
    optimizer.zero_grad()
    scores = model(images)
    loss = criterion(scores, labels)
    loss.backward()
    optimizer.step()
    
    running_loss += loss.item()
  else:
    test_loss = 0
    accuracy = 0
    
    with torch.no_grad():
      
      # Set the model to eval mode. Dropout = 0
      model.eval()
      
      for images, labels in testloader:
        scores = model(images)
        test_loss += criterion(scores, labels)
        
        ps = torch.exp(scores)
        top_p, top_class = ps.topk(1, dim=1)
        equals = top_class == labels.view(*top_class.shape)
        accuracy += torch.mean(equals.type(torch.FloatTensor))
    
    train_log.append(running_loss/len(trainloader))
    test_log.append(test_loss/len(testloader))
    print("Epoch: {}/{}  |".format(epoch+1, epochs),
              "Training Loss: {:.3f}  |".format(running_loss/len(trainloader)),
              "Test Loss: {:.3f}  |".format(test_loss/len(testloader)),
              "Test Accuracy: {:.3f}".format(accuracy/len(testloader)))
    
    # Set the model back to train mode. Dropout value restored
    model.train()

    
  
    

plt.plot(train_log, label='Training loss')
plt.plot(test_log, label='Validation loss')
plt.legend(frameon=False)
%config InlineBackend.figure_format = 'retina'

def view_classify(img, ps, version="MNIST"):
    ''' Function for viewing an image and it's predicted classes.
    '''
    ps = ps.data.numpy().squeeze()

    fig, (ax1, ax2) = plt.subplots(figsize=(6,9), ncols=2)
    ax1.imshow(img.resize_(1, 28, 28).numpy().squeeze())
    ax1.axis('off')
    ax2.barh(np.arange(10), ps)
    ax2.set_aspect(0.1)
    ax2.set_yticks(np.arange(10))
    if version == "MNIST":
        ax2.set_yticklabels(np.arange(10))
    elif version == "Fashion":
        ax2.set_yticklabels(['T-shirt/top',
                            'Trouser',
                            'Pullover',
                            'Dress',
                            'Coat',
                            'Sandal',
                            'Shirt',
                            'Sneaker',
                            'Bag',
                            'Ankle Boot'], size='small');
    ax2.set_title('Class Probability')
    ax2.set_xlim(0, 1.1)

    plt.tight_layout()

model.eval()

images, labels = next(iter(trainloader))
img = images[1].view(1, 784)

with torch.no_grad():
  output = model.forward(img)
  
ps = torch.exp(output)
view_classify(img.view(1, 28, 28), ps, version="Fashion")<jupyter_output><empty_output><jupyter_text>Saving & loading a model* Save the architecture + weights + biases in a dictionary<jupyter_code># Saving a model
# print(model.state_dict().keys())

checkpoint = {'input_size': 784,
              'output_size': 10,
              'hidden_layers': [each.out_features for each in model.hidden_layers],
              'state_dict': model.state_dict()}

torch.save(checkpoint, 'checkpoint.pth')

# Load a model 
# checkpoint = torch.load(filepath)
# model = fc_model.Network(checkpoint['input_size'], checkpoint['output_size'],
#                              checkpoint['hidden_layers'])
# model.load_state_dict(checkpoint['state_dict'])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1449044585987261, 'fraction_numerical': 0.025477707006369428, 'mean_word_length': 2.595257563368765, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '395727', 'license': 'MIT', 'n_tokens_mistral': 1596, 'n_tokens_neox': 1522, 'n_words': 296, 'path': 'Pytorch notebooks/Intro_DL_Pytorch_MNIST.ipynb', 'repo_name': 'RohanChacko/CVIT-Summer-School', 'size': '4396'}