Part 1 Import Libraries

In [ ]:
# Part 1
import numpy as np                            # numpy for numerical computation
import torch                                  # Torch for Pytorch base (for deep learning)
import torchvision                            # TorchVision for image processing
import matplotlib.pyplot as plt               # Plotting tools
from time import time                         # Timing tools
from torchvision import datasets, transforms  # Import dataset and transform functions
from torch import nn, optim                   # Import neural network and optimization classes
import cv2                                    # Import computer vision tools

Part 2 Data Pre-processing Transform

In [ ]:
transform = transforms.Compose([transforms.ToTensor(),
                              transforms.Normalize((0.5,), (0.5,)),
                              ])
# transform is a global class object that does the transform for you.

Part 3 Download Data

In [ ]:
# Download the training data and the validation data
trainset    = datasets.MNIST('C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/', download=True, train=True, transform=transform)
valset      = datasets.MNIST('C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/', download=True, train=False, transform=transform)

# Define the loader that loads images into the correct format
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
valloader   = torch.utils.data.DataLoader(valset, batch_size=64, shuffle=True)

# Create iteration objection, images, and labels
dataiter = iter(trainloader)
images, labels = dataiter.next()
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Failed to download (trying next):
HTTP Error 503: Service Unavailable

Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/train-images-idx3-ubyte.gz
Extracting C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/train-images-idx3-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Failed to download (trying next):
HTTP Error 503: Service Unavailable

Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/train-labels-idx1-ubyte.gz
Extracting C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/train-labels-idx1-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Failed to download (trying next):
HTTP Error 503: Service Unavailable

Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/t10k-images-idx3-ubyte.gz
Extracting C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/t10k-images-idx3-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
Failed to download (trying next):
HTTP Error 503: Service Unavailable

Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz
Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/t10k-labels-idx1-ubyte.gz
Extracting C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw/t10k-labels-idx1-ubyte.gz to C:/Users/Stanley Chan/Dropbox/Python/ColorSpace/MNIST/raw

Processing...
/usr/local/lib/python3.7/dist-packages/torchvision/datasets/mnist.py:502: 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:143.)
  return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)
Done!

Part 4 Construct Your Model

In [ ]:
# Here we construct the neural network. There is no training involved yet. We are only defining the model.
input_size = 784
hidden_sizes = [128, 64, 32]
output_size = 10

model = nn.Sequential(nn.Linear(input_size, hidden_sizes[0]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[0], hidden_sizes[1]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[1], hidden_sizes[2]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[2], output_size),
                      nn.LogSoftmax(dim=1))

Part 5 Construct the training loss

In [ ]:
criterion = nn.NLLLoss()
images, labels = next(iter(trainloader))
images = images.view(images.shape[0], -1)

logps = model(images)                 #log probabilities
loss = criterion(logps, labels)       #calculate the NLL loss

Part 6 Main Training Loop

In [ ]:
optimizer = optim.SGD(model.parameters(), lr=0.003, momentum=0.9)
time0 = time()
epochs = 2
for e in range(epochs):
    running_loss = 0
    for images, labels in trainloader:
        # Flatten MNIST images into a 784 long vector
        images = images.view(images.shape[0], -1)
    
        # Training pass
        optimizer.zero_grad()
        
        output = model(images)
        loss = criterion(output, labels)
        
        #This is where the model learns by backpropagating
        loss.backward()
        
        #And optimizes its weights here
        optimizer.step()
        
        running_loss += loss.item()
    else:
        print("Epoch {} - Training loss: {}".format(e, running_loss/len(trainloader)))
print("\nTraining Time (in minutes) =",(time()-time0)/60)
Epoch 0 - Training loss: 0.8765342464325017
Epoch 1 - Training loss: 0.3012712801903931

Training Time (in minutes) = 0.31863880157470703

Part 7 Testing

(This code uses the validation dataset)

In [ ]:
images, labels = next(iter(valloader))
img = images[0].view(1, 784)
with torch.no_grad():
    logps = model(img)
ps = torch.exp(logps)
probab = list(ps.numpy()[0])
print("Predicted Digit =", probab.index(max(probab)))
plt.imshow(images[0].numpy().squeeze(), cmap='gray_r');
Predicted Digit = 6

Part 8 Testing

(This code uses real data)

In [ ]:
# Using cv2.imread() method 
# Using 0 to read image in grayscale mode 
img = cv2.imread('digit_2.png', 0)  # You will need to change the filename

# resize image to 28x28
img = cv2.resize(img, (28,28))

# flip the image color
# this is optional; and feel free to change it
for i in range(0,img.shape[0]):
  for j in range(0,img.shape[1]):
    if img[i,j]>125:
      img[i,j] = 0
    else:
      img[i,j] = 255 - img[i,j]

# plot the processed image
plt.imshow(img, cmap='gray_r')

# input the processed image to the network and make prediction
img = transform(img).view(1, 784)
with torch.no_grad():
    logps = model(img)
ps = torch.exp(logps)
probab = list(ps.numpy()[0])
print("Predicted Hand-written Digit =", probab.index(max(probab)))
Predicted Hand-written Digit = 2
In [ ]:
%%shell
jupyter nbconvert --to html /content/ECE595_Demo_deeplearn.ipynb
[NbConvertApp] Converting notebook /content/HighSchool_Lecture9.ipynb to html
[NbConvertApp] Writing 338884 bytes to /content/HighSchool_Lecture9.html
Out[ ]: