In [1]:
#  Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
#  Licensed 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.
"""Convolutional Neural Network Estimator for MNIST, built with tf.layers."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import os
import sys

import tensorflow as tf
import dataset


os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = '2'

class Model(object):
  """Class that defines a graph to recognize digits in the MNIST dataset."""

  def __init__(self, data_format):
    """Creates a model for classifying a hand-written digit.
    Args:
      data_format: Either 'channels_first' or 'channels_last'.
        'channels_first' is typically faster on GPUs while 'channels_last' is
        typically faster on CPUs. See
        https://www.tensorflow.org/performance/performance_guide#data_formats
    """
    if data_format == 'channels_first':
      self._input_shape = [-1, 1, 28, 28]
    else:
      assert data_format == 'channels_last'
      self._input_shape = [-1, 28, 28, 1]

    self.conv1 = tf.layers.Conv2D(
        32, 5, padding='same', data_format=data_format, activation=tf.nn.relu)
    self.conv2 = tf.layers.Conv2D(
        64, 5, padding='same', data_format=data_format, activation=tf.nn.relu)
    self.fc1 = tf.layers.Dense(1024, activation=tf.nn.relu)
    self.fc2 = tf.layers.Dense(10)
    self.dropout = tf.layers.Dropout(0.4)
    self.max_pool2d = tf.layers.MaxPooling2D(
        (2, 2), (2, 2), padding='same', data_format=data_format)

  def __call__(self, inputs, training):
    """Add operations to classify a batch of input images.
    Args:
      inputs: A Tensor representing a batch of input images.
      training: A boolean. Set to True to add operations required only when
        training the classifier.
    Returns:
      A logits Tensor with shape [<batch_size>, 10].
    """
    y = tf.reshape(inputs, self._input_shape)
    y = self.conv1(y)
    y = self.max_pool2d(y)
    y = self.conv2(y)
    y = self.max_pool2d(y)
    y = tf.layers.flatten(y)
    y = self.fc1(y)
    y = self.dropout(y, training=training)
    return self.fc2(y)


def model_fn(features, labels, mode, params):
  """The model_fn argument for creating an Estimator."""
  model = Model(params['data_format'])
  image = features
  if isinstance(image, dict):
    image = features['image']

  if mode == tf.estimator.ModeKeys.PREDICT:
    logits = model(image, training=False)
    predictions = {
        'classes': tf.argmax(logits, axis=1),
        'probabilities': tf.nn.softmax(logits),
    }
    return tf.estimator.EstimatorSpec(
        mode=tf.estimator.ModeKeys.PREDICT,
        predictions=predictions,
        export_outputs={
            'classify': tf.estimator.export.PredictOutput(predictions)
        })
  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.AdamOptimizer(learning_rate=1e-4)
    logits = model(image, training=True)
    loss = tf.losses.softmax_cross_entropy(onehot_labels=labels, logits=logits)
    accuracy = tf.metrics.accuracy(
        labels=tf.argmax(labels, axis=1), predictions=tf.argmax(logits, axis=1))
    # Name the accuracy tensor 'train_accuracy' to demonstrate the
    # LoggingTensorHook.
    tf.identity(accuracy[1], name='train_accuracy')
    tf.summary.scalar('train_accuracy', accuracy[1])
    return tf.estimator.EstimatorSpec(
        mode=tf.estimator.ModeKeys.TRAIN,
        loss=loss,
        train_op=optimizer.minimize(loss, tf.train.get_or_create_global_step()))
  if mode == tf.estimator.ModeKeys.EVAL:
    logits = model(image, training=False)
    loss = tf.losses.softmax_cross_entropy(onehot_labels=labels, logits=logits)
    return tf.estimator.EstimatorSpec(
        mode=tf.estimator.ModeKeys.EVAL,
        loss=loss,
        eval_metric_ops={
            'accuracy':
                tf.metrics.accuracy(
                    labels=tf.argmax(labels, axis=1),
                    predictions=tf.argmax(logits, axis=1)),
        })


def main(unused_argv):
  data_format = FLAGS.data_format
  if data_format is None:
    data_format = ('channels_first'
                   if tf.test.is_built_with_cuda() else 'channels_last')
  mnist_classifier = tf.estimator.Estimator(
      model_fn=model_fn,
      model_dir=FLAGS.model_dir,
      params={
          'data_format': data_format
      })

  # Train the model
  def train_input_fn():
    # When choosing shuffle buffer sizes, larger sizes result in better
    # randomness, while smaller sizes use less memory. MNIST is a small
    # enough dataset that we can easily shuffle the full epoch.
    ds = dataset.train(FLAGS.data_dir)
    ds = ds.cache().shuffle(buffer_size=50000).batch(FLAGS.batch_size).repeat(
        FLAGS.train_epochs)
    (images, labels) = ds.make_one_shot_iterator().get_next()
    return (images, labels)

  # Set up training hook that logs the training accuracy every 100 steps.
  tensors_to_log = {'train_accuracy': 'train_accuracy'}
  logging_hook = tf.train.LoggingTensorHook(
      tensors=tensors_to_log, every_n_iter=100)
  mnist_classifier.train(input_fn=train_input_fn, hooks=[logging_hook])

  # Evaluate the model and print results
  def eval_input_fn():
    return dataset.test(FLAGS.data_dir).batch(
        FLAGS.batch_size).make_one_shot_iterator().get_next()

  eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
  print()
  print('Evaluation results:\n\t%s' % eval_results)

  # Export the model
  if FLAGS.export_dir is not None:
    image = tf.placeholder(tf.float32, [None, 28, 28])
    input_fn = tf.estimator.export.build_raw_serving_input_receiver_fn({
        'image': image,
    })
    mnist_classifier.export_savedmodel(FLAGS.export_dir, input_fn)


if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--batch_size',
      type=int,
      default=64,
      help='Number of images to process in a batch')
  parser.add_argument(
      '--data_dir',
      type=str,
      default='/tmp/mnist_data',
      help='Path to directory containing the MNIST dataset')
  parser.add_argument(
      '--model_dir',
      type=str,
      default='/tmp/mnist_model',
      help='The directory where the model will be stored.')
  parser.add_argument(
      '--train_epochs', type=int, default=2, help='Number of epochs to train.')
  parser.add_argument(
      '--data_format',
      type=str,
      default=None,
      choices=['channels_first', 'channels_last'],
      help='A flag to override the data format used in the model. channels_first '
      'provides a performance boost on GPU but is not always compatible '
      'with CPU. If left unspecified, the data format will be chosen '
      'automatically based on whether TensorFlow was built for CPU or GPU.')
  parser.add_argument(
      '--export_dir',
      type=str,
      default='/tmp/mnist_model_export',
      help='The directory where the exported SavedModel will be stored.')

  tf.logging.set_verbosity(tf.logging.INFO)
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)


INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_task_type': 'worker', '_keep_checkpoint_every_n_hours': 10000, '_num_ps_replicas': 0, '_save_summary_steps': 100, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7fa46c214d30>, '_task_id': 0, '_tf_random_seed': None, '_model_dir': '/tmp/mnist_model', '_master': '', '_service': None, '_keep_checkpoint_max': 5, '_log_step_count_steps': 100, '_save_checkpoints_secs': 600, '_num_worker_replicas': 1, '_is_chief': True, '_session_config': None, '_save_checkpoints_steps': None}
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Saving checkpoints for 1 into /tmp/mnist_model/model.ckpt.
INFO:tensorflow:train_accuracy = 0.140625
INFO:tensorflow:step = 1, loss = 2.29284
INFO:tensorflow:global_step/sec: 65.8884
INFO:tensorflow:train_accuracy = 0.460938 (1.519 sec)
INFO:tensorflow:step = 101, loss = 0.565832 (1.519 sec)
INFO:tensorflow:global_step/sec: 82.5162
INFO:tensorflow:train_accuracy = 0.625 (1.212 sec)
INFO:tensorflow:step = 201, loss = 0.233587 (1.212 sec)
INFO:tensorflow:global_step/sec: 122.76
INFO:tensorflow:train_accuracy = 0.714844 (0.815 sec)
INFO:tensorflow:step = 301, loss = 0.130011 (0.815 sec)
INFO:tensorflow:global_step/sec: 122.57
INFO:tensorflow:train_accuracy = 0.76875 (0.816 sec)
INFO:tensorflow:step = 401, loss = 0.145763 (0.816 sec)
INFO:tensorflow:global_step/sec: 122.589
INFO:tensorflow:train_accuracy = 0.807292 (0.815 sec)
INFO:tensorflow:step = 501, loss = 0.0883068 (0.815 sec)
INFO:tensorflow:global_step/sec: 121.138
INFO:tensorflow:train_accuracy = 0.828125 (0.826 sec)
INFO:tensorflow:step = 601, loss = 0.133691 (0.826 sec)
INFO:tensorflow:global_step/sec: 120.989
INFO:tensorflow:train_accuracy = 0.849609 (0.826 sec)
INFO:tensorflow:step = 701, loss = 0.042739 (0.826 sec)
INFO:tensorflow:global_step/sec: 122.181
INFO:tensorflow:train_accuracy = 0.864583 (0.819 sec)
INFO:tensorflow:step = 801, loss = 0.0651859 (0.819 sec)
INFO:tensorflow:global_step/sec: 121.076
INFO:tensorflow:train_accuracy = 0.875 (0.826 sec)
INFO:tensorflow:step = 901, loss = 0.0853941 (0.826 sec)
INFO:tensorflow:global_step/sec: 111.244
INFO:tensorflow:train_accuracy = 0.880682 (0.899 sec)
INFO:tensorflow:step = 1001, loss = 0.220372 (0.898 sec)
INFO:tensorflow:global_step/sec: 120.718
INFO:tensorflow:train_accuracy = 0.889323 (0.829 sec)
INFO:tensorflow:step = 1101, loss = 0.0974882 (0.829 sec)
INFO:tensorflow:global_step/sec: 120.453
INFO:tensorflow:train_accuracy = 0.895433 (0.830 sec)
INFO:tensorflow:step = 1201, loss = 0.106239 (0.830 sec)
INFO:tensorflow:global_step/sec: 121.913
INFO:tensorflow:train_accuracy = 0.899554 (0.820 sec)
INFO:tensorflow:step = 1301, loss = 0.155051 (0.820 sec)
INFO:tensorflow:global_step/sec: 121.553
INFO:tensorflow:train_accuracy = 0.905208 (0.822 sec)
INFO:tensorflow:step = 1401, loss = 0.0364096 (0.822 sec)
INFO:tensorflow:global_step/sec: 120.729
INFO:tensorflow:train_accuracy = 0.911133 (0.829 sec)
INFO:tensorflow:step = 1501, loss = 0.020146 (0.829 sec)
INFO:tensorflow:global_step/sec: 120.699
INFO:tensorflow:train_accuracy = 0.915441 (0.829 sec)
INFO:tensorflow:step = 1601, loss = 0.046171 (0.829 sec)
INFO:tensorflow:global_step/sec: 120.81
INFO:tensorflow:train_accuracy = 0.916667 (0.828 sec)
INFO:tensorflow:step = 1701, loss = 0.218409 (0.827 sec)
INFO:tensorflow:global_step/sec: 123.415
INFO:tensorflow:train_accuracy = 0.919408 (0.810 sec)
INFO:tensorflow:step = 1801, loss = 0.177265 (0.811 sec)
INFO:tensorflow:Saving checkpoints for 1876 into /tmp/mnist_model/model.ckpt.
INFO:tensorflow:Loss for final step: 0.0201572.
Downloading https://storage.googleapis.com/cvdf-datasets/mnist/t10k-images-idx3-ubyte.gz to /tmp/mnist_data/t10k-images-idx3-ubyte.gz
Downloading https://storage.googleapis.com/cvdf-datasets/mnist/t10k-labels-idx1-ubyte.gz to /tmp/mnist_data/t10k-labels-idx1-ubyte.gz
INFO:tensorflow:Starting evaluation at 2018-03-08-07:06:41
INFO:tensorflow:Restoring parameters from /tmp/mnist_model/model.ckpt-1876
INFO:tensorflow:Finished evaluation at 2018-03-08-07:06:42
INFO:tensorflow:Saving dict for global step 1876: accuracy = 0.9832, global_step = 1876, loss = 0.0505907

Evaluation results:
	{'accuracy': 0.98320001, 'global_step': 1876, 'loss': 0.050590701}
INFO:tensorflow:Restoring parameters from /tmp/mnist_model/model.ckpt-1876
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:No assets to write.
INFO:tensorflow:SavedModel written to: b"/tmp/mnist_model_export/temp-b'1520492802'/saved_model.pb"
An exception has occurred, use %tb to see the full traceback.

SystemExit
/home/jorge/anaconda3/envs/tf14/lib/python3.5/site-packages/IPython/core/interactiveshell.py:2870: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

In [ ]: