In [ ]:
from urllib.request import urlretrieve
from os.path import isfile, isdir
from tqdm import tqdm
import problem_unittests as tests
import tarfile
cifar10_dataset_folder_path = 'cifar-10-batches-py'
In [ ]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import pickle
import problem_unittests as tests
import helper
# Load the Preprocessed Validation data
valid_features, valid_labels = pickle.load(open('preprocess_validation.p', mode='rb'))
In [ ]:
import tensorflow as tf
def neural_net_image_input(image_shape):
"""
Return a Tensor for a batch of image input
: image_shape: Shape of the images
: return: Tensor for image input.
"""
# TODO: Implement Function
shape = list(image_shape)
shape.insert (0, None)
return tf.placeholder (tf.float32, shape=shape, name='x')
def neural_net_label_input(n_classes):
"""
Return a Tensor for a batch of label input
: n_classes: Number of classes
: return: Tensor for label input.
"""
# TODO: Implement Function
return tf.placeholder (tf.float32, shape=[None, n_classes], name='y')
def neural_net_keep_prob_input():
"""
Return a Tensor for keep probability
: return: Tensor for keep probability.
"""
# TODO: Implement Function
return tf.placeholder (tf.float32, name='keep_prob')
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tf.reset_default_graph()
tests.test_nn_image_inputs(neural_net_image_input)
tests.test_nn_label_inputs(neural_net_label_input)
tests.test_nn_keep_prob_inputs(neural_net_keep_prob_input)
In [ ]:
def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
"""
Apply convolution then max pooling to x_tensor
:param x_tensor: TensorFlow Tensor
:param conv_num_outputs: Number of outputs for the convolutional layer
:param conv_ksize: kernal size 2-D Tuple for the convolutional layer
:param conv_strides: Stride 2-D Tuple for convolution
:param pool_ksize: kernal size 2-D Tuple for pool
:param pool_strides: Stride 2-D Tuple for pool
: return: A tensor that represents convolution and max pooling of x_tensor
"""
# TODO: Implement Function
input_shape = [conv_ksize[0], conv_ksize[1], x_tensor.get_shape().as_list()[3], conv_num_outputs]
weights = tf.Variable (tf.truncated_normal (input_shape, mean=0.0, stddev=0.10, dtype=tf.float32))
biases = tf.Variable (tf.zeros (conv_num_outputs, dtype=tf.float32))
strides = [1, conv_strides[0], conv_strides[1], 1]
conv = tf.nn.conv2d (x_tensor, weights, strides=strides, padding='SAME')
conv = tf.nn.bias_add (conv, biases)
conv = tf.nn.relu (conv)
ksize = [1, pool_ksize[0], pool_ksize[1], 1]
strides = [1, pool_strides[0], pool_strides[1], 1]
maxpool = tf.nn.max_pool (conv, ksize=ksize, strides=strides, padding='SAME')
return maxpool
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_con_pool(conv2d_maxpool)
In [ ]:
import operator
import functools
def flatten(x_tensor):
"""
Flatten x_tensor to (Batch Size, Flattened Image Size)
: x_tensor: A tensor of size (Batch Size, ...), where ... are the image dimensions.
: return: A tensor of size (Batch Size, Flattened Image Size).
"""
# TODO: Implement Function
image_size = functools.reduce(operator.mul, x_tensor.get_shape().as_list()[1:], 1)
return tf.reshape (x_tensor, [-1, image_size])
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_flatten(flatten)
In [ ]:
def fully_conn(x_tensor, num_outputs):
"""
Apply a fully connected layer to x_tensor using weight and bias
: x_tensor: A 2-D tensor where the first dimension is batch size.
: num_outputs: The number of output that the new tensor should be.
: return: A 2-D tensor where the second dimension is num_outputs.
"""
# TODO: Implement Function
weights = tf.Variable (tf.truncated_normal ([x_tensor.get_shape().as_list()[1], num_outputs], mean=0.0, stddev=0.10, dtype=tf.float32))
biases = tf.Variable (tf.zeros (num_outputs, dtype=tf.float32))
activations = tf.add (tf.matmul (x_tensor, weights), biases)
return tf.nn.relu (activations)
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_fully_conn(fully_conn)
In [ ]:
def output(x_tensor, num_outputs):
"""
Apply a output layer to x_tensor using weight and bias
: x_tensor: A 2-D tensor where the first dimension is batch size.
: num_outputs: The number of output that the new tensor should be.
: return: A 2-D tensor where the second dimension is num_outputs.
"""
# TODO: Implement Function
weights = tf.Variable (tf.truncated_normal ([x_tensor.get_shape().as_list()[1], num_outputs], mean=0.0, stddev=0.10, dtype=tf.float32))
biases = tf.Variable (tf.zeros (num_outputs, dtype=tf.float32))
return tf.add (tf.matmul (x_tensor, weights), biases)
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_output(output)
In [ ]:
def conv_net(x, keep_prob):
"""
Create a convolutional neural network model
: x: Placeholder tensor that holds image data.
: keep_prob: Placeholder tensor that hold dropout keep probability.
: return: Tensor that represents logits
"""
# TODO: Apply 1, 2, or 3 Convolution and Max Pool layers
conv1 = conv2d_maxpool (x, conv_num_outputs=64, conv_ksize=(8,8), conv_strides=(2,2), pool_ksize=(2,2), pool_strides=(2,2))
conv2 = conv2d_maxpool (conv1, conv_num_outputs=128, conv_ksize=(6,6), conv_strides=(2,2), pool_ksize=(2,2), pool_strides=(2,2))
flat = flatten (conv2)
conn1 = fully_conn (flat, 2048)
conn1 = tf.nn.dropout (conn1, keep_prob)
conn2 = fully_conn (conn1, 1024)
conn2 = tf.nn.dropout (conn2, keep_prob)
out = output (conn2, 10)
return out
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
##############################
## Build the Neural Network ##
##############################
# Remove previous weights, bias, inputs, etc..
tf.reset_default_graph()
# Inputs
x = neural_net_image_input((32, 32, 3))
y = neural_net_label_input(10)
keep_prob = neural_net_keep_prob_input()
# Model
logits = conv_net(x, keep_prob)
# Name logits Tensor, so that is can be loaded from disk after training
logits = tf.identity(logits, name='logits')
# Loss and Optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))
optimizer = tf.train.AdamOptimizer().minimize(cost)
# Accuracy
correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name='accuracy')
tests.test_conv_net(conv_net)
In [ ]:
def train_neural_network(session, optimizer, keep_probability, feature_batch, label_batch):
"""
Optimize the session on a batch of images and labels
: session: Current TensorFlow session
: optimizer: TensorFlow optimizer function
: keep_probability: keep probability
: feature_batch: Batch of Numpy image data
: label_batch: Batch of Numpy label data
"""
# TODO: Implement Function
session.run (optimizer, feed_dict={x:feature_batch, y:label_batch, keep_prob:keep_probability})
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_train_nn(train_neural_network)
In [ ]:
def print_stats(session, feature_batch, label_batch, cost, accuracy):
"""
Print information about loss and validation accuracy
: session: Current TensorFlow session
: feature_batch: Batch of Numpy image data
: label_batch: Batch of Numpy label data
: cost: TensorFlow cost function
: accuracy: TensorFlow accuracy function
"""
# TODO: Implement Function
loss = session.run (cost, feed_dict={x:feature_batch, y:label_batch, keep_prob:1.0})
valid_acc = session.run (accuracy, feed_dict={x:valid_features, y:valid_labels, keep_prob:1.0})
print ('Loss = {:8.6f}, Validation Accuracy = {:.4f}'.format (loss, valid_acc))
In [ ]:
# TODO: Tune Parameters
epochs = 20
batch_size = 128
keep_probability = 0.75
In [ ]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
save_model_path = './image_classification'
print('Training...')
with tf.Session() as sess:
print ("Initializing the variables")
sess.run(tf.global_variables_initializer())
# Training cycle
for epoch in range(epochs):
# Loop over all batches
n_batches = 5
for batch_i in range(1, n_batches + 1):
for batch_features, batch_labels in helper.load_preprocess_training_batch(batch_i, batch_size):
train_neural_network(sess, optimizer, keep_probability, batch_features, batch_labels)
print('Epoch {:>2}, CIFAR-10 Batch {}: '.format(epoch + 1, batch_i), end='')
print_stats(sess, batch_features, batch_labels, cost, accuracy)
if (epoch + 1) % 100 == 0:
# Save Model
print ("Save model...")
saver = tf.train.Saver()
save_path = saver.save(sess, save_model_path + '-' + str(epoch + 1))
# Save Model
saver = tf.train.Saver()
save_path = saver.save(sess, save_model_path + '-' + str(epoch + 1))