Create a file called low_level_cnn.py, and add the following code:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import tensorflow as tf
from data_utils import get_one_shot_test_data
TEST_BATCH=100
def conv_relu(inputs, filters, k_size, stride, padding, scope_name):
'''
A method that does convolution + relu on inputs
'''
with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
in_channels = inputs.shape[-1]
kernel = tf.get_variable('kernel',
[k_size, k_size, in_channels, filters],
initializer=tf.truncated_normal_initializer())
biases = tf.get_variable('biases',
[filters],
initializer=tf.random_normal_initializer())
conv = tf.nn.conv2d(inputs, kernel, strides=[1, stride, stride, 1], padding=padding)
return tf.nn.relu(tf.nn.bias_add(conv, biases), name=scope.name)
def maxpool(inputs, ksize, stride, padding='VALID', scope_name='pool'):
'''A method that does max pooling on inputs'''
with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
pool = tf.nn.max_pool(inputs,
ksize=[1, ksize, ksize, 1],
strides=[1, stride, stride, 1],
padding=padding)
return pool
def fully_connected(inputs, out_dim, scope_name='fc'):
'''
A fully connected linear layer on inputs
'''
with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
in_dim = inputs.shape[-1]
w = tf.get_variable('weights', [in_dim, out_dim],
initializer=tf.truncated_normal_initializer())
b = tf.get_variable('b', [out_dim],
initializer=tf.constant_initializer(0.0))
out = tf.matmul(inputs, w) + b
return out
def net_fn(image, n_classes=10, keep_prob=0.5, is_training=True):
conv1 = conv_relu(inputs=image,
filters=32,
k_size=5,
stride=1,
padding='SAME',
scope_name='conv1')
pool1 = maxpool(conv1, 2, 2, 'VALID', 'pool1')
conv2 = conv_relu(inputs=pool1,
filters=64,
k_size=5,
stride=1,
padding='SAME',
scope_name='conv2')
pool2 = maxpool(conv2, 2, 2, 'VALID', 'pool2')
feature_dim = pool2.shape[1] * pool2.shape[2] * pool2.shape[3]
pool2 = tf.reshape(pool2, [-1, feature_dim])
fc = fully_connected(pool2, 1024, 'fc')
keep_prob = keep_prob if is_training else 1
dropout = tf.nn.dropout(tf.nn.relu(fc), keep_prob, name='relu_dropout')
logits = fully_connected(dropout, n_classes, 'logits')
return logits
net_fn.default_image_size=28
def model_fn():
tf.logging.set_verbosity(tf.logging.INFO)
img, labels = get_one_shot_test_data(TEST_BATCH)
logits = net_fn(img, is_training=False)
predictions = tf.argmax(logits, 1)
labels = tf.argmax(labels, 1)
eval_metric_ops = {
'accuracy': tf.metrics.accuracy(labels, predictions),
'recall_5': tf.metrics.recall_at_k(labels, logits, 5)
}
return eval_metric_ops
The net_fn
function defines the network
architecture. It takes the MNIST image data as argument and return a logits tensor. The
model_fn
function reads an input data pipeline and
returns a dictionary of evaluation metrics operations.