| { |
| "cells": [ |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "# Deep Learning Image Classification\n", |
| "\n", |
| "This notebook shows SystemML Deep Learning functionality to map images of single digit numbers to their corresponding numeric representations. See [Getting Started with Deep Learning and Python](http://www.pyimagesearch.com/2014/09/22/getting-started-deep-learning-python/) for an explanation of the used deep learning concepts and assumptions.\n", |
| "\n", |
| "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 format is \"label, pixel_1, pixel_2, ..., pixel_n\". We train a SystemML LeNet model. The results of the learning algorithms have an accuracy of 98 percent.\n", |
| "\n", |
| "1. [Install and load SystemML and other libraries](#load_systemml)\n", |
| "1. [Download and Access MNIST data](#access_data)\n", |
| "1. [Train a CNN classifier for MNIST handwritten digits](#train)\n", |
| "1. [Detect handwritten Digits](#predict)\n" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": { |
| "collapsed": true |
| }, |
| "source": [ |
| "<div style=\"text-align:center\" markdown=\"1\">\n", |
| "![Image of Image to Digit](https://www.wolfram.com/mathematica/new-in-10/enhanced-image-processing/HTMLImages.en/handwritten-digits-classification/smallthumb_10.gif)\n", |
| "Mapping images of numbers to numbers\n", |
| "</div>" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<a id=\"load_systemml\"></a>\n", |
| "## Install and load SystemML and other libraries" |
| ] |
| }, |
| { |
| "cell_type": "raw", |
| "metadata": { |
| "scrolled": true |
| }, |
| "source": [ |
| "!pip uninstall systemml --y\n", |
| "!pip install --user https://repository.apache.org/content/groups/snapshots/org/apache/systemml/systemml/1.0.0-SNAPSHOT/systemml-1.0.0-20171201.070207-23-python.tar.gz" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false |
| }, |
| "outputs": [], |
| "source": [ |
| "from systemml import MLContext, dml\n", |
| "\n", |
| "ml = MLContext(sc)\n", |
| "\n", |
| "print \"Spark Version:\", sc.version\n", |
| "print \"SystemML Version:\", ml.version()\n", |
| "print \"SystemML Built-Time:\", ml.buildTime()" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": true |
| }, |
| "outputs": [], |
| "source": [ |
| "from sklearn import datasets\n", |
| "from sklearn.cross_validation import train_test_split\n", |
| "from sklearn.metrics import classification_report\n", |
| "import pandas as pd\n", |
| "import numpy as np\n", |
| "import matplotlib.pyplot as plt\n", |
| "%matplotlib inline\n", |
| "import warnings\n", |
| "warnings.filterwarnings(\"ignore\")" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<a id=\"access_data\"></a>\n", |
| "## Download and Access MNIST data\n", |
| "\n", |
| "Download the [MNIST data from the MLData repository](http://mldata.org/repository/data/viewslug/mnist-original/), and then split and save." |
| ] |
| }, |
| { |
| "cell_type": "raw", |
| "metadata": { |
| "scrolled": false |
| }, |
| "source": [ |
| "mnist = datasets.fetch_mldata(\"MNIST Original\")\n", |
| "\n", |
| "print \"Mnist data features:\", mnist.data.shape\n", |
| "print \"Mnist data label:\", mnist.target.shape\n", |
| "\n", |
| "trainX, testX, trainY, testY = train_test_split(mnist.data, mnist.target.astype(\"int0\"), test_size = 0.142857)\n", |
| "\n", |
| "trainD = np.concatenate((trainY.reshape(trainY.size, 1), trainX),axis=1)\n", |
| "testD = np.concatenate((testY.reshape (testY.size, 1), testX),axis=1)\n", |
| "\n", |
| "print \"Images for training:\", trainD.shape\n", |
| "print \"Images used for testing:\", testD.shape\n", |
| "pix = int(np.sqrt(trainD.shape[1]))\n", |
| "print \"Each image is:\", pix, \"by\", pix, \"pixels\"\n", |
| "\n", |
| "np.savetxt('mnist/mnist_train.csv', trainD, fmt='%u', delimiter=\",\")\n", |
| "np.savetxt('mnist/mnist_test.csv', testD, fmt='%u', delimiter=\",\")" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "### Read the data." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false |
| }, |
| "outputs": [], |
| "source": [ |
| "trainData = np.genfromtxt('mnist/mnist_train.csv', delimiter=\",\")\n", |
| "testData = np.genfromtxt('mnist/mnist_test.csv', delimiter=\",\")\n", |
| "\n", |
| "print \"Training data: \", trainData.shape\n", |
| "print \"Test data: \", testData.shape" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false |
| }, |
| "outputs": [], |
| "source": [ |
| "pd.set_option('display.max_columns', 200)\n", |
| "pd.DataFrame(testData[1:10,],dtype='uint')" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<a id=\"train\"></a>\n", |
| "## Develop LeNet CNN classifier on Training Data" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<div style=\"text-align:center\" markdown=\"1\">\n", |
| "![Image of Image to Digit](http://www.ommegaonline.org/admin/journalassistance/picturegallery/896.jpg)\n", |
| "MNIST digit recognition – LeNet architecture\n", |
| "</div>" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "### (Optional) Display SystemML LeNet Implementation" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false |
| }, |
| "outputs": [], |
| "source": [ |
| "!jar -xf ~/.local/lib/python2.7/site-packages/systemml/systemml-java/systemml*.jar scripts/nn/examples/mnist_lenet.dml\n", |
| "!cat scripts/nn/examples/mnist_lenet.dml" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "### Train Model using SystemML LeNet CNN." |
| ] |
| }, |
| { |
| "cell_type": "raw", |
| "metadata": {}, |
| "source": [ |
| "ml.setGPU(True).setForceGPU(True)" |
| ] |
| }, |
| { |
| "cell_type": "raw", |
| "metadata": {}, |
| "source": [ |
| "ml.setStatistics(False)" |
| ] |
| }, |
| { |
| "cell_type": "raw", |
| "metadata": {}, |
| "source": [ |
| "ml.setExplain(True).setExplainLevel('runtime')" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false, |
| "scrolled": false |
| }, |
| "outputs": [], |
| "source": [ |
| "script = \"\"\"\n", |
| " source(\"scripts/nn/examples/mnist_lenet.dml\") as mnist_lenet\n", |
| " # Bind data; Extract images and labels\n", |
| " n = nrow(data)\n", |
| " images = data[,2:ncol(data)]\n", |
| " labels = data[,1]\n", |
| "\n", |
| " # Scale images to [-1,1], and one-hot encode the labels\n", |
| " images = (images / 255.0) * 2 - 1\n", |
| " labels = table(seq(1, n), labels+1, n, 10)\n", |
| "\n", |
| " # Split data into training (55,000 examples) and validation (5,000 examples)\n", |
| " X = images[5001:nrow(images),]\n", |
| " X_val = images[1:5000,]\n", |
| " y = labels[5001:nrow(images),]\n", |
| " y_val = labels[1:5000,]\n", |
| "\n", |
| " # Train the model using channel, height, and width to produce weights/biases.\n", |
| " [W1, b1, W2, b2, W3, b3, W4, b4] = mnist_lenet::train(X, y, X_val, y_val, C, Hin, Win, epochs)\n", |
| "\"\"\"\n", |
| "rets = ('W1', 'b1','W2','b2','W3','b3','W4','b4')\n", |
| "\n", |
| "script = (dml(script).input(data=trainData, epochs=1, C=1, Hin=28, Win=28)\n", |
| " .output(*rets)) \n", |
| "\n", |
| "W1, b1, W2, b2, W3, b3, W4, b4 = ml.execute(script).get(*rets)" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": { |
| "collapsed": true |
| }, |
| "source": [ |
| "Use trained model and predict on test data, and evaluate the quality of the predictions for each digit." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false |
| }, |
| "outputs": [], |
| "source": [ |
| "scriptPredict = \"\"\"\n", |
| " source(\"scripts/nn/examples/mnist_lenet.dml\") as mnist_lenet\n", |
| "\n", |
| " # Separate images from lables and scale images to [-1,1]\n", |
| " X_test = data[,2:ncol(data)]\n", |
| " X_test = (X_test / 255.0) * 2 - 1\n", |
| "\n", |
| " # Predict\n", |
| " probs = mnist_lenet::predict(X_test, C, Hin, Win, W1, b1, W2, b2, W3, b3, W4, b4)\n", |
| " predictions = rowIndexMax(probs) - 1\n", |
| "\"\"\"\n", |
| "script = (dml(scriptPredict).input(data=testData, C=1, Hin=28, Win=28, W1=W1, b1=b1, W2=W2, b2=b2, W3=W3, b3=b3, W4=W4, b4=b4)\n", |
| " .output(\"predictions\"))\n", |
| "\n", |
| "predictions = ml.execute(script).get(\"predictions\").toNumPy()\n", |
| "\n", |
| "print classification_report(testData[:,0], predictions)" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<a id=\"predict\"></a>\n", |
| "## Detect handwritten Digits" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "Define a function that randomly selects a test image, display the image, and scores it." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": true |
| }, |
| "outputs": [], |
| "source": [ |
| "img_size = np.sqrt(testData.shape[1] - 1).astype(\"uint8\")\n", |
| "\n", |
| "def displayImage(i):\n", |
| " image = testData[i,1:].reshape((img_size, img_size)).astype(\"uint8\")\n", |
| " imgplot = plt.imshow(image, cmap='gray') " |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": true |
| }, |
| "outputs": [], |
| "source": [ |
| "def predictImage(i):\n", |
| " image = testData[i,:].reshape(1,testData.shape[1])\n", |
| " prog = dml(scriptPredict).input(data=image, C=1, Hin=28, Win=28, W1=W1, b1=b1, W2=W2, b2=b2, W3=W3, b3=b3, W4=W4, b4=b4) \\\n", |
| " .output(\"predictions\")\n", |
| " result = ml.execute(prog)\n", |
| " return (result.get(\"predictions\").toNumPy())[0]" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": false, |
| "scrolled": false |
| }, |
| "outputs": [], |
| "source": [ |
| "i = np.random.choice(np.arange(0, len(testData)), size = (1,))\n", |
| "\n", |
| "p = predictImage(i)\n", |
| "\n", |
| "print \"Image\", i, \"\\nPredicted digit:\", p, \"\\nActual digit: \", testData[i,0], \"\\nResult: \", (p == testData[i,0])\n", |
| "\n", |
| "displayImage(i)" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": true |
| }, |
| "outputs": [], |
| "source": [] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": true |
| }, |
| "outputs": [], |
| "source": [ |
| "pd.set_option('display.max_columns', 28)\n", |
| "pd.DataFrame((testData[i,1:]).reshape(img_size, img_size),dtype='uint')" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": { |
| "collapsed": true |
| }, |
| "outputs": [], |
| "source": [] |
| } |
| ], |
| "metadata": { |
| "kernelspec": { |
| "display_name": "Python 2", |
| "language": "python", |
| "name": "python2" |
| }, |
| "language_info": { |
| "codemirror_mode": { |
| "name": "ipython", |
| "version": 2 |
| }, |
| "file_extension": ".py", |
| "mimetype": "text/x-python", |
| "name": "python", |
| "nbconvert_exporter": "python", |
| "pygments_lexer": "ipython2", |
| "version": "2.7.11" |
| } |
| }, |
| "nbformat": 4, |
| "nbformat_minor": 1 |
| } |