Home | History | Annotate | Download | only in layers
      1 #  Copyright 2016 The TensorFlow Authors. All Rights Reserved.
      2 #
      3 #  Licensed under the Apache License, Version 2.0 (the "License");
      4 #  you may not use this file except in compliance with the License.
      5 #  You may obtain a copy of the License at
      6 #
      7 #   http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 #  Unless required by applicable law or agreed to in writing, software
     10 #  distributed under the License is distributed on an "AS IS" BASIS,
     11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 #  See the License for the specific language governing permissions and
     13 #  limitations under the License.
     14 """Convolutional Neural Network Estimator for MNIST, built with tf.layers."""
     15 
     16 from __future__ import absolute_import
     17 from __future__ import division
     18 from __future__ import print_function
     19 
     20 import numpy as np
     21 import tensorflow as tf
     22 
     23 tf.logging.set_verbosity(tf.logging.INFO)
     24 
     25 
     26 def cnn_model_fn(features, labels, mode):
     27   """Model function for CNN."""
     28   # Input Layer
     29   # Reshape X to 4-D tensor: [batch_size, width, height, channels]
     30   # MNIST images are 28x28 pixels, and have one color channel
     31   input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])
     32 
     33   # Convolutional Layer #1
     34   # Computes 32 features using a 5x5 filter with ReLU activation.
     35   # Padding is added to preserve width and height.
     36   # Input Tensor Shape: [batch_size, 28, 28, 1]
     37   # Output Tensor Shape: [batch_size, 28, 28, 32]
     38   conv1 = tf.layers.conv2d(
     39       inputs=input_layer,
     40       filters=32,
     41       kernel_size=[5, 5],
     42       padding="same",
     43       activation=tf.nn.relu)
     44 
     45   # Pooling Layer #1
     46   # First max pooling layer with a 2x2 filter and stride of 2
     47   # Input Tensor Shape: [batch_size, 28, 28, 32]
     48   # Output Tensor Shape: [batch_size, 14, 14, 32]
     49   pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
     50 
     51   # Convolutional Layer #2
     52   # Computes 64 features using a 5x5 filter.
     53   # Padding is added to preserve width and height.
     54   # Input Tensor Shape: [batch_size, 14, 14, 32]
     55   # Output Tensor Shape: [batch_size, 14, 14, 64]
     56   conv2 = tf.layers.conv2d(
     57       inputs=pool1,
     58       filters=64,
     59       kernel_size=[5, 5],
     60       padding="same",
     61       activation=tf.nn.relu)
     62 
     63   # Pooling Layer #2
     64   # Second max pooling layer with a 2x2 filter and stride of 2
     65   # Input Tensor Shape: [batch_size, 14, 14, 64]
     66   # Output Tensor Shape: [batch_size, 7, 7, 64]
     67   pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
     68 
     69   # Flatten tensor into a batch of vectors
     70   # Input Tensor Shape: [batch_size, 7, 7, 64]
     71   # Output Tensor Shape: [batch_size, 7 * 7 * 64]
     72   pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
     73 
     74   # Dense Layer
     75   # Densely connected layer with 1024 neurons
     76   # Input Tensor Shape: [batch_size, 7 * 7 * 64]
     77   # Output Tensor Shape: [batch_size, 1024]
     78   dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
     79 
     80   # Add dropout operation; 0.6 probability that element will be kept
     81   dropout = tf.layers.dropout(
     82       inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
     83 
     84   # Logits layer
     85   # Input Tensor Shape: [batch_size, 1024]
     86   # Output Tensor Shape: [batch_size, 10]
     87   logits = tf.layers.dense(inputs=dropout, units=10)
     88 
     89   predictions = {
     90       # Generate predictions (for PREDICT and EVAL mode)
     91       "classes": tf.argmax(input=logits, axis=1),
     92       # Add `softmax_tensor` to the graph. It is used for PREDICT and by the
     93       # `logging_hook`.
     94       "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
     95   }
     96   if mode == tf.estimator.ModeKeys.PREDICT:
     97     return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
     98 
     99   # Calculate Loss (for both TRAIN and EVAL modes)
    100   loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
    101 
    102   # Configure the Training Op (for TRAIN mode)
    103   if mode == tf.estimator.ModeKeys.TRAIN:
    104     optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
    105     train_op = optimizer.minimize(
    106         loss=loss,
    107         global_step=tf.train.get_global_step())
    108     return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
    109 
    110   # Add evaluation metrics (for EVAL mode)
    111   eval_metric_ops = {
    112       "accuracy": tf.metrics.accuracy(
    113           labels=labels, predictions=predictions["classes"])}
    114   return tf.estimator.EstimatorSpec(
    115       mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
    116 
    117 
    118 def main(unused_argv):
    119   # Load training and eval data
    120   mnist = tf.contrib.learn.datasets.load_dataset("mnist")
    121   train_data = mnist.train.images  # Returns np.array
    122   train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
    123   eval_data = mnist.test.images  # Returns np.array
    124   eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
    125 
    126   # Create the Estimator
    127   mnist_classifier = tf.estimator.Estimator(
    128       model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model")
    129 
    130   # Set up logging for predictions
    131   # Log the values in the "Softmax" tensor with label "probabilities"
    132   tensors_to_log = {"probabilities": "softmax_tensor"}
    133   logging_hook = tf.train.LoggingTensorHook(
    134       tensors=tensors_to_log, every_n_iter=50)
    135 
    136   # Train the model
    137   train_input_fn = tf.estimator.inputs.numpy_input_fn(
    138       x={"x": train_data},
    139       y=train_labels,
    140       batch_size=100,
    141       num_epochs=None,
    142       shuffle=True)
    143   mnist_classifier.train(
    144       input_fn=train_input_fn,
    145       steps=20000,
    146       hooks=[logging_hook])
    147 
    148   # Evaluate the model and print results
    149   eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    150       x={"x": eval_data},
    151       y=eval_labels,
    152       num_epochs=1,
    153       shuffle=False)
    154   eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
    155   print(eval_results)
    156 
    157 
    158 if __name__ == "__main__":
    159   tf.app.run()
    160