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.
Here, we'll read data using input functions, which are appropriate for in-memory data.
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.
num_epochs
to None
, we'll loop over the data indefinitely so we can train for as long as we like.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/