Table of Contents
- 1- Packages
- 2 - Basic Optimization with GradientTape
- 3 - Building Your First Neural Network in TensorFlow
- 4 - Bibliography
1 - Packages
In [1]:
import h5py import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.python.framework.ops import EagerTensor from tensorflow.python.ops.resource_variable_ops import ResourceVariable import time
1.1 - Checking TensorFlow Version
You will be using v2.3 for this assignment, for maximum speed and efficiency.
In [2]:
tf.__version__
Out[2]:
'2.3.0'
2 - Basic Optimization with GradientTape
The beauty of TensorFlow 2 is in its simplicity. Basically, all you need to do is implement forward propagation through a computational graph. TensorFlow will compute the derivatives for you, by moving backwards through the graph recorded with GradientTape
. All that's left for you to do then is specify the cost function and optimizer you want to use!
When writing a TensorFlow program, the main object to get used and transformed is the tf.Tensor
. These tensors are the TensorFlow equivalent of Numpy arrays, i.e. multidimensional arrays of a given data type that also contain information about the computational graph.
Below, you'll use tf.Variable
to store the state of your variables. Variables can only be created once as its initial value defines the variable shape and type. Additionally, the dtype
arg in tf.Variable
can be set to allow data to be converted to that type. But if none is specified, either the datatype will be kept if the initial value is a Tensor, or convert_to_tensor
will decide. It's generally best for you to specify directly, so nothing breaks!
Here you'll call the TensorFlow dataset created on a HDF5 file, which you can use in place of a Numpy array to store your datasets. You can think of this as a TensorFlow data generator!
You will use the Hand sign data set, that is composed of images with shape 64x64x3.
In [3]:
train_dataset = h5py.File('datasets/train_signs.h5', "r") test_dataset = h5py.File('datasets/test_signs.h5', "r")
In [4]:
x_train = tf.data.Dataset.from_tensor_slices(train_dataset['train_set_x']) y_train = tf.data.Dataset.from_tensor_slices(train_dataset['train_set_y']) x_test = tf.data.Dataset.from_tensor_slices(test_dataset['test_set_x']) y_test = tf.data.Dataset.from_tensor_slices(test_dataset['test_set_y'])
In [5]:
type(x_train)
Out[5]:
tensorflow.python.data.ops.dataset_ops.TensorSliceDataset
Since TensorFlow Datasets are generators, you can't access directly the contents unless you iterate over them in a for loop, or by explicitly creating a Python iterator using iter
and consuming its elements using next
. Also, you can inspect the shape
and dtype
of each element using the element_spec
attribute.
In [6]:
print(x_train.element_spec)
TensorSpec(shape=(64, 64, 3), dtype=tf.uint8, name=None)
In [7]:
print(next(iter(x_train)))
tf.Tensor( [[[227 220 214] [227 221 215] [227 222 215] ... [232 230 224] [231 229 222] [230 229 221]] [[227 221 214] [227 221 215] [228 221 215] ... [232 230 224] [231 229 222] [231 229 221]] [[227 221 214] [227 221 214] [227 221 215] ... [232 230 224] [231 229 223] [230 229 221]] ... [[119 81 51] [124 85 55] [127 87 58] ... [210 211 211] [211 212 210] [210 211 210]] [[119 79 51] [124 84 55] [126 85 56] ... [210 211 210] [210 211 210] [209 210 209]] [[119 81 51] [123 83 55] [122 82 54] ... [209 210 210] [209 210 209] [208 209 209]]], shape=(64, 64, 3), dtype=uint8)
The dataset that you'll be using during this assignment is a subset of the sign language digits. It contains six different classes representing the digits from 0 to 5.
In [8]:
unique_labels = set() for element in y_train: unique_labels.add(element.numpy()) print(unique_labels)
{0, 1, 2, 3, 4, 5}
You can see some of the images in the dataset by running the following cell.
In [9]:
images_iter = iter(x_train) labels_iter = iter(y_train) plt.figure(figsize=(10, 10)) for i in range(25): ax = plt.subplot(5, 5, i + 1) plt.imshow(next(images_iter).numpy().astype("uint8")) plt.title(next(labels_iter).numpy().astype("uint8")) plt.axis("off")
There's one more additional difference between TensorFlow datasets and Numpy arrays: If you need to transform one, you would invoke the map
method to apply the function passed as an argument to each of the elements.
In [10]:
def normalize(image): """ Transform an image into a tensor of shape (64 * 64 * 3, ) and normalize its components. Arguments image - Tensor. Returns: result -- Transformed tensor """ image = tf.cast(image, tf.float32) / 255.0 image = tf.reshape(image, [-1,]) return image
In [11]:
new_train = x_train.map(normalize) new_test = x_test.map(normalize)
In [12]:
new_train.element_spec
Out[12]:
TensorSpec(shape=(12288,), dtype=tf.float32, name=None)
In [13]:
print(next(iter(new_train)))
tf.Tensor