This notebook demonstrates how to train a deep learning model on SystemML for the classic MNIST problem of mapping images of single digit numbers to their corresponding numeric representations, using a classic LeNet-like convolutional neural network model. See Neural Networks and Deep Learning for more information on neural networks and deep learning.
The downloaded MNIST dataset contains labeled images of handwritten digits, where each example is a 28x28 pixel image of grayscale values in the range [0,255] stretched out as 784 pixels, and each label is one of 10 possible digits in [0,9]. We download 60,000 training examples, and 10,000 test examples, where the images and labels are stored in separate matrices. We then train a SystemML LeNet-like convolutional neural network (i.e. "convnet", "CNN") model. The resulting trained model has an accuracy of 98.6% on the test dataset.
In [ ]:
!pip show systemml
In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.cross_validation import train_test_split # module deprecated in 0.18
#from sklearn.model_selection import train_test_split # use this module for >=0.18
from sklearn import metrics
from systemml import MLContext, dml
In [ ]:
ml = MLContext(sc)
print("Spark Version: {}".format(sc.version))
print("SystemML Version: {}".format(ml.version()))
print("SystemML Built-Time: {}".format(ml.buildTime()))
In [ ]:
mnist = datasets.fetch_mldata("MNIST Original")
print("MNIST data features: {}".format(mnist.data.shape))
print("MNIST data labels: {}".format(mnist.target.shape))
X_train, X_test, y_train, y_test = train_test_split(
mnist.data, mnist.target.astype(np.uint8).reshape(-1, 1),
test_size = 10000)
print("Training images, labels: {}, {}".format(X_train.shape, y_train.shape))
print("Testing images, labels: {}, {}".format(X_test.shape, y_test.shape))
print("Each image is: {0:d}x{0:d} pixels".format(int(np.sqrt(X_train.shape[1]))))
In [ ]:
!svn --force export https://github.com/apache/incubator-systemml/trunk/scripts/nn
In [ ]:
script = """
source("nn/examples/mnist_lenet.dml") as mnist_lenet
# Scale images to [-1,1], and one-hot encode the labels
images = (images / 255) * 2 - 1
n = nrow(images)
labels = table(seq(1, n), labels+1, n, 10)
# Split into training (55,000 examples) and validation (5,000 examples)
X = images[5001:nrow(images),]
X_val = images[1:5000,]
y = labels[5001:nrow(images),]
y_val = labels[1:5000,]
# Train the model to produce weights & biases.
[W1, b1, W2, b2, W3, b3, W4, b4] = mnist_lenet::train(X, y, X_val, y_val, C, Hin, Win, epochs)
"""
out = ('W1', 'b1', 'W2', 'b2', 'W3', 'b3', 'W4', 'b4')
prog = (dml(script).input(images=X_train, labels=y_train, epochs=1, C=1, Hin=28, Win=28)
.output(*out))
W1, b1, W2, b2, W3, b3, W4, b4 = ml.execute(prog).get(*out)
Use the trained model to make predictions for the test data, and evaluate the quality of the predictions.
In [ ]:
script_predict = """
source("nn/examples/mnist_lenet.dml") as mnist_lenet
# Scale images to [-1,1]
X_test = (X_test / 255) * 2 - 1
# Predict
y_prob = mnist_lenet::predict(X_test, C, Hin, Win, W1, b1, W2, b2, W3, b3, W4, b4)
y_pred = rowIndexMax(y_prob) - 1
"""
prog = (dml(script_predict).input(X_test=X_test, C=1, Hin=28, Win=28, W1=W1, b1=b1,
W2=W2, b2=b2, W3=W3, b3=b3, W4=W4, b4=b4)
.output("y_pred"))
y_pred = ml.execute(prog).get("y_pred").toNumPy()
In [ ]:
print(metrics.accuracy_score(y_test, y_pred))
print(metrics.classification_report(y_test, y_pred))
Define a function that randomly selects a test image, displays the image, and scores it.
In [ ]:
img_size = int(np.sqrt(X_test.shape[1]))
def displayImage(i):
image = (X_test[i]).reshape(img_size, img_size).astype(np.uint8)
imgplot = plt.imshow(image, cmap='gray')
In [ ]:
def predictImage(i):
image = X_test[i].reshape(1, -1)
out = "y_pred"
prog = (dml(script_predict).input(X_test=image, C=1, Hin=28, Win=28, W1=W1, b1=b1,
W2=W2, b2=b2, W3=W3, b3=b3, W4=W4, b4=b4)
.output(out))
pred = int(ml.execute(prog).get(out).toNumPy())
return pred
In [ ]:
i = np.random.randint(len(X_test))
p = predictImage(i)
print("Image {}\nPredicted digit: {}\nActual digit: {}\nResult: {}".format(
i, p, int(y_test[i]), p == int(y_test[i])))
displayImage(i)
In [ ]:
pd.set_option('display.max_columns', 28)
pd.DataFrame((X_test[i]).reshape(img_size, img_size), dtype='uint')