A Simple Neural Network using the CNTK v2.0 Tool

The Microsoft CNTK code library is a very powerful machine learning system. Version 2.0 is a huge change from version 1.0. Version 2.0 is still in Beta mode but I’ve been experimenting with it anyway.

For me, the essential Hello World for any ML tool or library is doing a classification analysis on the famous Iris Data. I was able to put together such a demo by using various examples from the CNTK Web sites. I used the newer Python language interface rather than the older proprietary BrainScript interface.

irisdemocntkversion20

I started with the 150-item Iris data set (copy-pasted from Wikipedia) and created a 120-item training data file and a 30-item test data file. Each line of data looks like:

5.0,3.5,1.3,0.3,1,0,0

The first four values are the predictor variables: sepal length and width, and petal length and width. The last three values encode the thing to predict, where 1,0,0 = “setosa”; 0,1,0 = “versicolor”; 0,0,1 = “virginica”.

I used Notepad++ to edit my demo CNTK Python script. The first few lines import the CNTK packages needed:

# iris_demo.py
# Python 3.5
# CNTK 2.0 Beta 11

import numpy as np
from cntk import Trainer  # to train the NN
from cntk.learner import sgd, learning_rate_schedule,
  UnitType
from cntk.ops import * 
from cntk.utils import ProgressPrinter
from cntk.initializer import glorot_uniform 
from cntk.layers import default_options, Dense,
  Sequential # CNTK Layers library

The demo script has a total of about 120 lines of code — not many, but too many to present in this blog post so I’ll just show some key code.

I created a little helper function that defines a simple feed-forward NN with one hidden layer. The helper uses the CNTK “Layers Library” which greatly simplifies network creation.

def create_model(num_hidd_nodes, num_out_nodes,
  input_var):
  with default_options(init = glorot_uniform()):
    hLayer = Dense(num_hidd_nodes,
      activation=sigmoid)(input_var)  
    net = Dense(num_out_nodes,
      activation=softmax)(hLayer)
  return net

You can see the NN uses sigmoid activation in the hidden layer and softmax activation in the output layer.

Reading data is almost always mildly annoying. The CNTK has several built-in reader functions, but I preferred to write my own data reader. The goal is to read either the training or test data file into two matrices. The first matrix holds just predictor values and the second matrix holds just class label values.

def parse_datafile(td):
  # data line like: 5.1,3.5,1.4,0.2, 1,0,0
  # extract into ndarray of features using cols[0:3]
  # and ndarray of labels using cols[4:6]
  # . . . code, code, code
  return (np.asarray(ftrs), np.asarray(lbls)) 

It takes about 16 lines of code to prepare the NN for training. After prep, the training statements are:

pp = ProgressPrinter(training_progress_output_freq)
  for i in range(0, max_iter):
    indices = np.random.permutation(numTrain)
    for j in range(0, numTrain):
      idx = indices[j] 
      trainer.train_minibatch({input_Var :
        train_features[[idx]], label_Var :
          train_labels[[idx]]})
    pp.update_with_trainer(trainer)
  print("\nTraining complete")

My demo script finishes by calculating the error on the test data, and then making a prediction for a new previously unseen (fake) iris flower:

unknown = np.array([[5.5, 3.5, 3.5, 1.5]],
  dtype=np.float32)
predicted = network.eval( {input_Var: unknown} )
print("Prediction is: ")
my_print(predicted[0,0], 3)  # 3 decimals

My conclusions are that CNTK is not a simple tool, instead it’s a complex code library that requires at least intermediate level Python skills. In a perfect world I’d dedicate time to learn both CNTK and its direct competitor, Google’s TensorFlow. However, that’s not feasible for me because both libraries would clearly require a major investment of time — so it’ll have to be either CNTK or TensorFlow but not both.

irisdemocntkversion20_editor

Advertisements
This entry was posted in CNTK, Machine Learning. Bookmark the permalink.