Repository: incubator-systemml
Updated Branches:
  refs/heads/master d8a8c3b69 -> 3a3c16599


[SYSTEMML-618] SystemML-NN: Adding an MNIST softmax classifier example, 
including a DML script and a Jupyter PySpark notebook.


Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/60f3fe60
Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/60f3fe60
Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/60f3fe60

Branch: refs/heads/master
Commit: 60f3fe607ac609576579202a9bca3a2723f1e6e2
Parents: d8a8c3b
Author: Mike Dusenberry <[email protected]>
Authored: Fri Jun 24 17:28:43 2016 -0700
Committer: Mike Dusenberry <[email protected]>
Committed: Fri Jun 24 17:28:43 2016 -0700

----------------------------------------------------------------------
 scripts/staging/SystemML-NN/.gitignore          |   2 -
 .../Example - MNIST Softmax Classifier.ipynb    | 207 +++++++++++++++++++
 .../SystemML-NN/examples/mnist_softmax.dml      | 203 ++++++++++++++++++
 3 files changed, 410 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/60f3fe60/scripts/staging/SystemML-NN/.gitignore
----------------------------------------------------------------------
diff --git a/scripts/staging/SystemML-NN/.gitignore 
b/scripts/staging/SystemML-NN/.gitignore
deleted file mode 100644
index a1b402b..0000000
--- a/scripts/staging/SystemML-NN/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-scratch_space
-*.ipynb

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/60f3fe60/scripts/staging/SystemML-NN/Example
 - MNIST Softmax Classifier.ipynb
----------------------------------------------------------------------
diff --git a/scripts/staging/SystemML-NN/Example - MNIST Softmax 
Classifier.ipynb b/scripts/staging/SystemML-NN/Example - MNIST Softmax 
Classifier.ipynb
new file mode 100644
index 0000000..5c1de15
--- /dev/null
+++ b/scripts/staging/SystemML-NN/Example - MNIST Softmax Classifier.ipynb      
@@ -0,0 +1,207 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Quick Setup"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "\n",
+    "# Add SystemML PySpark API file.\n",
+    
"sc.addPyFile(\"https://raw.githubusercontent.com/apache/incubator-systemml/3d5f9b11741f6d6ecc6af7cbaa1069cde32be838/src/main/java/org/apache/sysml/api/python/SystemML.py\";)\n",
+    "\n",
+    "# Create a SystemML MLContext object\n",
+    "from SystemML import MLContext\n",
+    "ml = MLContext(sc)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Download Data - MNIST"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The MNIST dataset contains labeled images of handwritten digits, where 
each example is a 28x28 pixel image of grayscale values scaled to [0,1] and 
stretched out as 784 pixels, and each label is a one-hot encoding over 10 
possible digits.  Here, we use TensorFlow's API for accessing the data, and 
retrieve 50,000 training examples, 5,000 validation examples, and 10,000 test 
examples.  [Note: TensorFlow can easily be installed via [these 
instructions](https://www.tensorflow.org/versions/r0.9/get_started/os_setup.html#pip-installation).]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "%%sh\n",
+    "mkdir -p examples/data/mnist/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "import tensorflow as tf\n",
+    "from tensorflow.examples.tutorials.mnist import input_data\n",
+    "\n",
+    "# Get MNIST data\n",
+    "mnist = input_data.read_data_sets('MNIST_data', one_hot=True)\n",
+    "\n",
+    "# Save to CSV\n",
+    "np.savetxt(\"examples/data/mnist/train_images.csv\", mnist.train.images, 
delimiter=\",\")\n",
+    "np.savetxt(\"examples/data/mnist/train_labels.csv\", mnist.train.labels, 
delimiter=\",\")\n",
+    "np.savetxt(\"examples/data/mnist/val_images.csv\", 
mnist.validation.images, delimiter=\",\")\n",
+    "np.savetxt(\"examples/data/mnist/val_labels.csv\", 
mnist.validation.labels, delimiter=\",\")\n",
+    "np.savetxt(\"examples/data/mnist/test_images.csv\", mnist.test.images, 
delimiter=\",\")\n",
+    "np.savetxt(\"examples/data/mnist/test_labels.csv\", mnist.test.labels, 
delimiter=\",\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## SystemML Softmax Model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 1. Train"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "script = \"\"\"\n",
+    "source(\"examples/mnist_softmax.dml\") as mnist_softmax\n",
+    "\n",
+    "# Read data\n",
+    "X = read($X, format=\"csv\")\n",
+    "y = read($y, format=\"csv\")\n",
+    "\n",
+    "X_val = read($X_val, format=\"csv\")\n",
+    "y_val = read($y_val, format=\"csv\")\n",
+    "\n",
+    "# Train\n",
+    "[W, b] = mnist_softmax::train(X, y, X_val, y_val)\n",
+    "\n",
+    "# Write model out\n",
+    "write(W, $Wout)\n",
+    "write(b, $bout)\n",
+    "\n",
+    "print(\"\")\n",
+    "print(\"\")\n",
+    "\"\"\"\n",
+    "ml.reset()\n",
+    "out = ml.executeScript(script, {\"X\": 
\"examples/data/mnist/train_images.csv\", \n",
+    "                                \"y\": 
\"examples/data/mnist/train_labels.csv\",\n",
+    "                                \"X_val\": 
\"examples/data/mnist/val_images.csv\", \n",
+    "                                \"y_val\": 
\"examples/data/mnist/val_labels.csv\"},\n",
+    "                       outputs=[\"W\", \"b\"])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 2. Extract model from SystemML back into PySpark"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "W = out.getDF(sqlContext, \"W\").sort(\"ID\").drop(\"ID\")\n",
+    "b = out.getDF(sqlContext, \"b\").sort(\"ID\").drop(\"ID\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 3. Compute Test Accuracy"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "script = \"\"\"\n",
+    "source(\"examples/mnist_softmax.dml\") as mnist_softmax\n",
+    "\n",
+    "# Read data & coefficients\n",
+    "X_test = read($X_test, format=\"csv\")\n",
+    "y_test = read($y_test, format=\"csv\")\n",
+    "W = read($W)\n",
+    "b = read($b)\n",
+    "\n",
+    "# Eval on test set\n",
+    "[loss, accuracy] = mnist_softmax::eval(X_test, y_test, W, b)\n",
+    "\n",
+    "print(\"Accuracy: \" + accuracy)\n",
+    "\n",
+    "print(\"\")\n",
+    "print(\"\")\n",
+    "\"\"\"\n",
+    "ml.reset()\n",
+    "out = ml.executeScript(script, {\"X_test\": 
\"examples/data/mnist/test_images.csv\",\n",
+    "                                \"y_test\": 
\"examples/data/mnist/test_labels.csv\",\n",
+    "                                \"W\": W, \"b\": b})"
+   ]
+  }
+ ],
+ "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": 0
+}

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/60f3fe60/scripts/staging/SystemML-NN/examples/mnist_softmax.dml
----------------------------------------------------------------------
diff --git a/scripts/staging/SystemML-NN/examples/mnist_softmax.dml 
b/scripts/staging/SystemML-NN/examples/mnist_softmax.dml
new file mode 100644
index 0000000..f3c47e9
--- /dev/null
+++ b/scripts/staging/SystemML-NN/examples/mnist_softmax.dml
@@ -0,0 +1,203 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#-------------------------------------------------------------
+
+/*
+ * MNIST Softmax Example
+ */
+# Imports
+source("nn/layers/affine.dml") as affine
+source("nn/layers/cross_entropy_loss.dml") as cross_entropy_loss
+source("nn/layers/softmax.dml") as softmax
+source("nn/optim/sgd_nesterov.dml") as sgd_nesterov
+
+train = function(matrix[double] X, matrix[double] y,
+                 matrix[double] X_val, matrix[double] y_val)
+    return (matrix[double] W, matrix[double] b) {
+  /*
+   * Trains a softmax classifier.  The input matrix, X, has N examples,
+   * each with D features.  The targets, y, have K classes.
+   *
+   * Inputs:
+   *  - X: Input data matrix, of shape (N, D).
+   *  - y: Target matrix, of shape (N, K).
+   *  - X_val: Input validation data matrix, of shape (N, C*Hin*Win).
+   *  - y_val: Target validation matrix, of shape (N, K).
+   *
+   * Outputs:
+   *  - W: Weights (parameters) matrix, of shape (D, M).
+   *  - b: Biases vector, of shape (1, M).
+   */
+  N = nrow(X)  # num examples
+  D = ncol(X)  # num features
+  K = ncol(y)  # num classes
+
+  # Create softmax classifier:
+  # affine -> softmax
+  [W, b] = affine::init(D, K)
+  W = W / sqrt(2.0/(D)) * sqrt(1/(D))
+
+  # Initialize SGD w/ Nesterov momentum optimizer
+  lr = 0.2  # learning rate
+  mu = 0  # momentum
+  decay = 0.99  # learning rate decay constant
+  vW = sgd_nesterov::init(W)  # optimizer momentum state for W
+  vb = sgd_nesterov::init(b)  # optimizer momentum state for b
+
+  # Optimize
+  print("Starting optimization")
+  batch_size = 50
+  epochs = 1
+  iters = 1000 #ceil(N / batch_size)
+  for (e in 1:epochs) {
+    for(i in 1:iters) {
+      # Get next batch
+      beg = ((i-1) * batch_size) %% N + 1
+      end = min(N, beg + batch_size - 1)
+      X_batch = X[beg:end,]
+      y_batch = y[beg:end,]
+
+      # Compute forward pass
+      ## affine & softmax:
+      out = affine::forward(X_batch, W, b)
+      probs = softmax::forward(out)
+
+      # Compute loss & accuracy for training & validation data
+      loss = cross_entropy_loss::forward(probs, y_batch)
+      accuracy = mean(rowIndexMax(probs) == rowIndexMax(y_batch))
+      [loss_val, accuracy_val] = eval(X_val, y_val, W, b)
+      print("Epoch: " + e + ", Iter: " + i + ", Train Loss: " + loss + ", 
Train Accuracy: " + accuracy + ", Val Loss: " + loss_val + ", Val Accuracy: " + 
accuracy_val)
+
+      # Compute backward pass
+      ## loss:
+      dprobs = cross_entropy_loss::backward(probs, y_batch)
+      ## affine & softmax:
+      dout = softmax::backward(dprobs, out)
+      [dX_batch, dW, db] = affine::backward(dout, X_batch, W, b)
+
+      # Optimize with SGD w/ Nesterov momentum
+      [W, vW] = sgd_nesterov::update(W, dW, lr, mu, vW)
+      [b, vb] = sgd_nesterov::update(b, db, lr, mu, vb)
+    }
+    # Anneal momentum towards 0.999
+    mu = mu + (0.999 - mu)/(1+epochs-e)
+    # Decay learning rate
+    lr = lr * decay
+  }
+}
+
+eval = function(matrix[double] X, matrix[double] y, matrix[double] W, 
matrix[double] b)
+    return (double loss, double accuracy) {
+  /*
+   * Evaluates a softmax classifier.  The input matrix, X, has N
+   * examples, each with D features.  The targets, y, have K classes.
+   *
+   * Inputs:
+   *  - X: Input data matrix, of shape (N, D).
+   *  - y: Target matrix, of shape (N, K).
+   *  - W: Weights (parameters) matrix, of shape (D, M).
+   *  - b: Biases vector, of shape (1, M).
+   *
+   * Outputs:
+   *  - loss: Scalar loss, of shape (1).
+   *  - accuracy: Scalar accuracy, of shape (1).
+   */
+  # Compute forward pass
+  ## affine & softmax:
+  out = affine::forward(X, W, b)
+  probs = softmax::forward(out)
+
+  # Compute loss & accuracy
+  loss = cross_entropy_loss::forward(probs, y)
+  correct_pred = rowIndexMax(probs) == rowIndexMax(y)
+  accuracy = mean(correct_pred)
+}
+
+generate_dummy_data = function()
+    return (matrix[double] X, matrix[double] y, int C, int Hin, int Win) {
+  /*
+   * Generate a dummy dataset similar to the MNIST dataset.
+   *
+   * Outputs:
+   *  - X: Input data matrix, of shape (N, D).
+   *  - y: Target matrix, of shape (N, K).
+   *  - C: Number of input channels (dimensionality of input depth).
+   *  - Hin: Input height.
+   *  - Win: Input width.
+   */
+  # Generate dummy input data
+  N = 1024  # num examples
+  C = 1  # num input channels
+  Hin = 28  # input height
+  Win = 28  # input width
+  T = 10  # num targets
+  X = rand(rows=N, cols=C*Hin*Win, pdf="normal")
+  classes = round(rand(rows=N, cols=1, min=1, max=T, pdf="uniform"))
+  y = table(seq(1, N), classes)  # one-hot encoding
+}
+
+
+#
+# Main
+#
+# This runs if called as a script.
+#
+# Ex:
+#   ```
+#   $SPARK_HOME/bin/spark-submit --master local[*] --driver-memory 5G
+#   --conf spark.driver.maxResultSize=0 --conf spark.akka.frameSize=128
+#   $SYSTEMML_HOME/target/SystemML.jar -f examples/mnist_softmax.dml
+#   -nvargs X=examples/data/mnist/train_images.csv 
y=examples/data/mnist/train_labels.csv
+#   X_val=examples/data/mnist/val_images.csv 
y_val=examples/data/mnist/val_labels.csv
+#   X_test=examples/data/mnist/test_images.csv 
y_test=examples/data/mnist/test_labels.csv
+#   out_dir=examples/model/mnist_softmax
+#   ```
+#
+# The MNIST dataset contains labeled images of handwritten digits,
+# where each example is a 28x28 pixel image of grayscale values
+# scaled to [0,1] and stretched out as 784 pixels, and each label
+# is a one-hot encoding over 10 possible digits.
+#
+
+# Read data
+X = read($X, format="csv")
+y = read($y, format="csv")
+X_val = read($X_val, format="csv")
+y_val = read($y_val, format="csv")
+X_test = read($X_test, format="csv")
+y_test = read($y_test, format="csv")
+
+# Train
+[W, b] = train(X, y, X_val, y_val)
+
+# Write model out
+write(W, $out_dir+"/W")
+write(b, $out_dir+"/b")
+
+# Eval on test set
+[loss, accuracy] = eval(X_test, y_test, W, b)
+
+# Output results
+print("Accuracy: " + accuracy)
+write(accuracy, $out_dir+"/accuracy")
+
+print("")
+print("")
+

Reply via email to