Canned Estimators

In this notebook we'll demonstrate how to use two Canned Estimators (these encapsulate the lower-level TensorFlow code we've seen so far, and use an API loosely inspired by scikit-learn. There are several advantages to Canned Estimators.

  • If you're using Estimators, you won't have to manage Sessions, or write your own logic for TensorBoard, or for saving and loading checkpoints.
  • You'll get out-of-the-box distributed training (of course, you will have to take care to read your data efficiently, and set up a cluster).

Here, we'll read data using input functions, which are appropriate for in-memory data.

  • These provide batching and other features for you, so you don't have to write that code yourself.
  • In the strucuted data notebook, we'll use the new Dataset API - which is a popular abstraction, and a great way to efficiently read and pre-process large datasets efficiently.

Although the Estimators we'll use here are relative simple (a LinearClassifier, and a Fully Connected Deep Neural Network), we also provide more interesting ones (including for TensorFlow Wide and Deep. I'm also excited that additional Estimators are on their way - stay tuned in the upcoming months.

Also note that Estimators log quite a lot of output


In [ ]:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import tensorflow as tf

In [ ]:
# We'll use Keras (included with TensorFlow) to import the data
(x_train, y_train), (x_test, y_test) = tf.contrib.keras.datasets.mnist.load_data()

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')

y_train = y_train.astype('int32')
y_test = y_test.astype('int32')

# Normalize the color values to 0-1
# (as imported, they're 0-255)
x_train /= 255
x_test /= 255

print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

Here's our input function.

  • By setting num_epochs to None, we'll loop over the data indefinitely so we can train for as long as we like.
  • The default batch_size is 128, but you can provide a different parameter if you like.

You can read more about the numpy input function here. We also provide a nice one for Pandas, more on that later.


In [ ]:
train_input = tf.estimator.inputs.numpy_input_fn(
    {'x': x_train},
    y_train, 
    num_epochs=None, # repeat forever
    shuffle=True # 
)

In [ ]:
test_input = tf.estimator.inputs.numpy_input_fn(
    {'x': x_test},
    y_test,
    num_epochs=1, # loop through the dataset once
    shuffle=False # don't shuffle the test data
)

In [ ]:
# define the features for our model
# the names must match the input function
feature_spec = [tf.feature_column.numeric_column('x', shape=784)]

Here, we'll create a LinearClassifier - this is identical to our Softmax (aka, multiclass logistic regression model) from the second notebok.


In [ ]:
estimator = tf.estimator.LinearClassifier(feature_spec, 
                                          n_classes=10,
                                          model_dir="./graphs/canned/linear")

In [ ]:
# I've arbitrarily decided to train for 1000 steps
estimator.train(train_input, steps=1000)

In [ ]:
# We should see about 90% accuracy here.
evaluation = estimator.evaluate(input_fn=test_input)
print(evaluation)

Here's how you would print individual predictions.


In [ ]:
MAX_TO_PRINT = 5

# This returns a generator object
predictions = estimator.predict(input_fn=test_input)
i = 0
for p in predictions:
    true_label = y_test[i]
    predicted_label = p['class_ids'][0]
    print("Example %d. True: %d, Predicted: %d" % (i, true_label, predicted_label))
    i += 1
    if i == MAX_TO_PRINT: break

Here's how easy it is to switch the model to a fully connected DNN.


In [ ]:
estimator = tf.estimator.DNNClassifier(
    hidden_units=[256], # we will arbitrarily use two layers
    feature_columns=feature_spec,
    n_classes=10,
    model_dir="./graphs/canned/deep")

In [ ]:
# I've arbitrarily decided to train for 2000 steps
estimator.train(train_input, steps=2000)

In [ ]:
# Expect accuracy around 97%
evaluation = estimator.evaluate(input_fn=test_input)
print(evaluation)

If you like, you can compare these runs with TensorBoard.

$ tensorboard --logdir=graphs/canned/