Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/C4 - Convolutional Neural Networks/Week 1/Convolution_model_Application 2022.py
Views: 4802
#!/usr/bin/env python1# coding: utf-823# # Convolutional Neural Networks: Application4#5# Welcome to Course 4's second assignment! In this notebook, you will:6#7# - Create a mood classifer using the TF Keras Sequential API8# - Build a ConvNet to identify sign language digits using the TF Keras Functional API9#10# **After this assignment you will be able to:**11#12# - Build and train a ConvNet in TensorFlow for a __binary__ classification problem13# - Build and train a ConvNet in TensorFlow for a __multiclass__ classification problem14# - Explain different use cases for the Sequential and Functional APIs15#16# To complete this assignment, you should already be familiar with TensorFlow. If you are not, please refer back to the **TensorFlow Tutorial** of the third week of Course 2 ("**Improving deep neural networks**").1718# ## Table of Contents19#20# - [1 - Packages](#1)21# - [1.1 - Load the Data and Split the Data into Train/Test Sets](#1-1)22# - [2 - Layers in TF Keras](#2)23# - [3 - The Sequential API](#3)24# - [3.1 - Create the Sequential Model](#3-1)25# - [Exercise 1 - happyModel](#ex-1)26# - [3.2 - Train and Evaluate the Model](#3-2)27# - [4 - The Functional API](#4)28# - [4.1 - Load the SIGNS Dataset](#4-1)29# - [4.2 - Split the Data into Train/Test Sets](#4-2)30# - [4.3 - Forward Propagation](#4-3)31# - [Exercise 2 - convolutional_model](#ex-2)32# - [4.4 - Train the Model](#4-4)33# - [5 - History Object](#5)34# - [6 - Bibliography](#6)3536# <a name='1'></a>37# ## 1 - Packages38#39# As usual, begin by loading in the packages.4041# In[4]:424344import math45import numpy as np46import h5py47import matplotlib.pyplot as plt48from matplotlib.pyplot import imread49import scipy50from PIL import Image51import pandas as pd52import tensorflow as tf53import tensorflow.keras.layers as tfl54from tensorflow.python.framework import ops55from cnn_utils import *56from test_utils import summary, comparator5758get_ipython().run_line_magic('matplotlib', 'inline')59np.random.seed(1)606162# <a name='1-1'></a>63# ### 1.1 - Load the Data and Split the Data into Train/Test Sets64#65# You'll be using the Happy House dataset for this part of the assignment, which contains images of peoples' faces. Your task will be to build a ConvNet that determines whether the people in the images are smiling or not -- because they only get to enter the house if they're smiling!6667# In[5]:686970X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_happy_dataset()7172# Normalize image vectors73X_train = X_train_orig/255.74X_test = X_test_orig/255.7576# Reshape77Y_train = Y_train_orig.T78Y_test = Y_test_orig.T7980print ("number of training examples = " + str(X_train.shape[0]))81print ("number of test examples = " + str(X_test.shape[0]))82print ("X_train shape: " + str(X_train.shape))83print ("Y_train shape: " + str(Y_train.shape))84print ("X_test shape: " + str(X_test.shape))85print ("Y_test shape: " + str(Y_test.shape))868788# You can display the images contained in the dataset. Images are **64x64** pixels in RGB format (3 channels).8990# In[6]:919293index = 12494plt.imshow(X_train_orig[index]) #display sample training image95plt.show()969798# <a name='2'></a>99# ## 2 - Layers in TF Keras100#101# In the previous assignment, you created layers manually in numpy. In TF Keras, you don't have to write code directly to create layers. Rather, TF Keras has pre-defined layers you can use.102#103# When you create a layer in TF Keras, you are creating a function that takes some input and transforms it into an output you can reuse later. Nice and easy!104105# <a name='3'></a>106# ## 3 - The Sequential API107#108# In the previous assignment, you built helper functions using `numpy` to understand the mechanics behind convolutional neural networks. Most practical applications of deep learning today are built using programming frameworks, which have many built-in functions you can simply call. Keras is a high-level abstraction built on top of TensorFlow, which allows for even more simplified and optimized model creation and training.109#110# For the first part of this assignment, you'll create a model using TF Keras' Sequential API, which allows you to build layer by layer, and is ideal for building models where each layer has **exactly one** input tensor and **one** output tensor.111#112# As you'll see, using the Sequential API is simple and straightforward, but is only appropriate for simpler, more straightforward tasks. Later in this notebook you'll spend some time building with a more flexible, powerful alternative: the Functional API.113#114115# <a name='3-1'></a>116# ### 3.1 - Create the Sequential Model117#118# As mentioned earlier, the TensorFlow Keras Sequential API can be used to build simple models with layer operations that proceed in a sequential order.119#120# You can also add layers incrementally to a Sequential model with the `.add()` method, or remove them using the `.pop()` method, much like you would in a regular Python list.121#122# Actually, you can think of a Sequential model as behaving like a list of layers. Like Python lists, Sequential layers are ordered, and the order in which they are specified matters. If your model is non-linear or contains layers with multiple inputs or outputs, a Sequential model wouldn't be the right choice!123#124# For any layer construction in Keras, you'll need to specify the input shape in advance. This is because in Keras, the shape of the weights is based on the shape of the inputs. The weights are only created when the model first sees some input data. Sequential models can be created by passing a list of layers to the Sequential constructor, like you will do in the next assignment.125#126# <a name='ex-1'></a>127# ### Exercise 1 - happyModel128#129# Implement the `happyModel` function below to build the following model: `ZEROPAD2D -> CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> FLATTEN -> DENSE`. Take help from [tf.keras.layers](https://www.tensorflow.org/api_docs/python/tf/keras/layers)130#131# Also, plug in the following parameters for all the steps:132#133# - [ZeroPadding2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/ZeroPadding2D): padding 3, input shape 64 x 64 x 3134# - [Conv2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D): Use 32 7x7 filters, stride 1135# - [BatchNormalization](https://www.tensorflow.org/api_docs/python/tf/keras/layers/BatchNormalization): for axis 3136# - [ReLU](https://www.tensorflow.org/api_docs/python/tf/keras/layers/ReLU)137# - [MaxPool2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D): Using default parameters138# - [Flatten](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Flatten) the previous output.139# - Fully-connected ([Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)) layer: Apply a fully connected layer with 1 neuron and a sigmoid activation.140#141#142# **Hint:**143#144# Use **tfl** as shorthand for **tensorflow.keras.layers**145146# In[102]:147148149# GRADED FUNCTION: happyModel150151def happyModel():152"""153Implements the forward propagation for the binary classification model:154ZEROPAD2D -> CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> FLATTEN -> DENSE155156Note that for simplicity and grading purposes, you'll hard-code all the values157such as the stride and kernel (filter) sizes.158Normally, functions should take these values as function parameters.159160Arguments:161None162163Returns:164model -- TF Keras model (object containing the information for the entire training process)165"""166model = tf.keras.Sequential([167## ZeroPadding2D with padding 3, input shape of 64 x 64 x 3168169## Conv2D with 32 7x7 filters and stride of 1170171## BatchNormalization for axis 3172173## ReLU174175## Max Pooling 2D with default parameters176177## Flatten layer178179## Dense layer with 1 unit for output & 'sigmoid' activation180181# YOUR CODE STARTS HERE182183184tf.keras.layers.ZeroPadding2D(padding=(3,3),input_shape=(64, 64, 3), data_format="channels_last"),185186tf.keras.layers.Conv2D(32, (7, 7), strides = (1, 1), name = 'conv0'),187188189tf.keras.layers.BatchNormalization(axis = 3, name = 'bn0'),190191tf.keras.layers.ReLU(192max_value=None, negative_slope=0.0, threshold=0.0193),194195tf.keras.layers.MaxPooling2D((2, 2), name='max_pool0'),196197tf.keras.layers.Flatten(),198199tf.keras.layers.Dense(1, activation='sigmoid', name='fc'),200201# YOUR CODE ENDS HERE202])203204return model205206207# In[103]:208209210happy_model = happyModel()211# Print a summary for each layer212for layer in summary(happy_model):213print(layer)214215output = [['ZeroPadding2D', (None, 70, 70, 3), 0, ((3, 3), (3, 3))],216['Conv2D', (None, 64, 64, 32), 4736, 'valid', 'linear', 'GlorotUniform'],217['BatchNormalization', (None, 64, 64, 32), 128],218['ReLU', (None, 64, 64, 32), 0],219['MaxPooling2D', (None, 32, 32, 32), 0, (2, 2), (2, 2), 'valid'],220['Flatten', (None, 32768), 0],221['Dense', (None, 1), 32769, 'sigmoid']]222223comparator(summary(happy_model), output)224225226# Now that your model is created, you can compile it for training with an optimizer and loss of your choice. When the string `accuracy` is specified as a metric, the type of accuracy used will be automatically converted based on the loss function used. This is one of the many optimizations built into TensorFlow that make your life easier! If you'd like to read more on how the compiler operates, check the docs [here](https://www.tensorflow.org/api_docs/python/tf/keras/Model#compile).227228# In[77]:229230231happy_model.compile(optimizer='adam',232loss='binary_crossentropy',233metrics=['accuracy'])234235236# It's time to check your model's parameters with the `.summary()` method. This will display the types of layers you have, the shape of the outputs, and how many parameters are in each layer.237238# In[78]:239240241happy_model.summary()242243244# <a name='3-2'></a>245# ### 3.2 - Train and Evaluate the Model246#247# After creating the model, compiling it with your choice of optimizer and loss function, and doing a sanity check on its contents, you are now ready to build!248#249# Simply call `.fit()` to train. That's it! No need for mini-batching, saving, or complex backpropagation computations. That's all been done for you, as you're using a TensorFlow dataset with the batches specified already. You do have the option to specify epoch number or minibatch size if you like (for example, in the case of an un-batched dataset).250251# In[ ]:252253254happy_model.fit(X_train, Y_train, epochs=10, batch_size=16)255256257# After that completes, just use `.evaluate()` to evaluate against your test set. This function will print the value of the loss function and the performance metrics specified during the compilation of the model. In this case, the `binary_crossentropy` and the `accuracy` respectively.258259# In[ ]:260261262happy_model.evaluate(X_test, Y_test)263264265# Easy, right? But what if you need to build a model with shared layers, branches, or multiple inputs and outputs? This is where Sequential, with its beautifully simple yet limited functionality, won't be able to help you.266#267# Next up: Enter the Functional API, your slightly more complex, highly flexible friend.268269# <a name='4'></a>270# ## 4 - The Functional API271272# Welcome to the second half of the assignment, where you'll use Keras' flexible [Functional API](https://www.tensorflow.org/guide/keras/functional) to build a ConvNet that can differentiate between 6 sign language digits.273#274# The Functional API can handle models with non-linear topology, shared layers, as well as layers with multiple inputs or outputs. Imagine that, where the Sequential API requires the model to move in a linear fashion through its layers, the Functional API allows much more flexibility. Where Sequential is a straight line, a Functional model is a graph, where the nodes of the layers can connect in many more ways than one.275#276# In the visual example below, the one possible direction of the movement Sequential model is shown in contrast to a skip connection, which is just one of the many ways a Functional model can be constructed. A skip connection, as you might have guessed, skips some layer in the network and feeds the output to a later layer in the network. Don't worry, you'll be spending more time with skip connections very soon!277278# <img src="images/seq_vs_func.png" style="width:350px;height:200px;">279280# <a name='4-1'></a>281# ### 4.1 - Load the SIGNS Dataset282#283# As a reminder, the SIGNS dataset is a collection of 6 signs representing numbers from 0 to 5.284285# In[79]:286287288# Loading the data (signs)289X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_signs_dataset()290291292# <img src="images/SIGNS.png" style="width:800px;height:300px;">293#294# The next cell will show you an example of a labelled image in the dataset. Feel free to change the value of `index` below and re-run to see different examples.295296# In[80]:297298299# Example of an image from the dataset300index = 9301plt.imshow(X_train_orig[index])302print ("y = " + str(np.squeeze(Y_train_orig[:, index])))303304305# <a name='4-2'></a>306# ### 4.2 - Split the Data into Train/Test Sets307#308# In Course 2, you built a fully-connected network for this dataset. But since this is an image dataset, it is more natural to apply a ConvNet to it.309#310# To get started, let's examine the shapes of your data.311312# In[81]:313314315X_train = X_train_orig/255.316X_test = X_test_orig/255.317Y_train = convert_to_one_hot(Y_train_orig, 6).T318Y_test = convert_to_one_hot(Y_test_orig, 6).T319print ("number of training examples = " + str(X_train.shape[0]))320print ("number of test examples = " + str(X_test.shape[0]))321print ("X_train shape: " + str(X_train.shape))322print ("Y_train shape: " + str(Y_train.shape))323print ("X_test shape: " + str(X_test.shape))324print ("Y_test shape: " + str(Y_test.shape))325326327# <a name='4-3'></a>328# ### 4.3 - Forward Propagation329#330# In TensorFlow, there are built-in functions that implement the convolution steps for you. By now, you should be familiar with how TensorFlow builds computational graphs. In the [Functional API](https://www.tensorflow.org/guide/keras/functional), you create a graph of layers. This is what allows such great flexibility.331#332# However, the following model could also be defined using the Sequential API since the information flow is on a single line. But don't deviate. What we want you to learn is to use the functional API.333#334# Begin building your graph of layers by creating an input node that functions as a callable object:335#336# - **input_img = tf.keras.Input(shape=input_shape):**337#338# Then, create a new node in the graph of layers by calling a layer on the `input_img` object:339#340# - **tf.keras.layers.Conv2D(filters= ... , kernel_size= ... , padding='same')(input_img):** Read the full documentation on [Conv2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D).341#342# - **tf.keras.layers.MaxPool2D(pool_size=(f, f), strides=(s, s), padding='same'):** `MaxPool2D()` downsamples your input using a window of size (f, f) and strides of size (s, s) to carry out max pooling over each window. For max pooling, you usually operate on a single example at a time and a single channel at a time. Read the full documentation on [MaxPool2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D).343#344# - **tf.keras.layers.ReLU():** computes the elementwise ReLU of Z (which can be any shape). You can read the full documentation on [ReLU](https://www.tensorflow.org/api_docs/python/tf/keras/layers/ReLU).345#346# - **tf.keras.layers.Flatten()**: given a tensor "P", this function takes each training (or test) example in the batch and flattens it into a 1D vector.347#348# * If a tensor P has the shape (batch_size,h,w,c), it returns a flattened tensor with shape (batch_size, k), where $k=h \times w \times c$. "k" equals the product of all the dimension sizes other than the first dimension.349#350# * For example, given a tensor with dimensions [100, 2, 3, 4], it flattens the tensor to be of shape [100, 24], where 24 = 2 * 3 * 4. You can read the full documentation on [Flatten](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Flatten).351#352# - **tf.keras.layers.Dense(units= ... , activation='softmax')(F):** given the flattened input F, it returns the output computed using a fully connected layer. You can read the full documentation on [Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense).353#354# In the last function above (`tf.keras.layers.Dense()`), the fully connected layer automatically initializes weights in the graph and keeps on training them as you train the model. Hence, you did not need to initialize those weights when initializing the parameters.355#356# Lastly, before creating the model, you'll need to define the output using the last of the function's compositions (in this example, a Dense layer):357#358# - **outputs = tf.keras.layers.Dense(units=6, activation='softmax')(F)**359#360#361# #### Window, kernel, filter, pool362#363# The words "kernel" and "filter" are used to refer to the same thing. The word "filter" accounts for the amount of "kernels" that will be used in a single convolution layer. "Pool" is the name of the operation that takes the max or average value of the kernels.364#365# This is why the parameter `pool_size` refers to `kernel_size`, and you use `(f,f)` to refer to the filter size.366#367# Pool size and kernel size refer to the same thing in different objects - They refer to the shape of the window where the operation takes place.368369# <a name='ex-2'></a>370# ### Exercise 2 - convolutional_model371#372# Implement the `convolutional_model` function below to build the following model: `CONV2D -> RELU -> MAXPOOL -> CONV2D -> RELU -> MAXPOOL -> FLATTEN -> DENSE`. Use the functions above!373#374# Also, plug in the following parameters for all the steps:375#376# - [Conv2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D): Use 8 4 by 4 filters, stride 1, padding is "SAME"377# - [ReLU](https://www.tensorflow.org/api_docs/python/tf/keras/layers/ReLU)378# - [MaxPool2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D): Use an 8 by 8 filter size and an 8 by 8 stride, padding is "SAME"379# - **Conv2D**: Use 16 2 by 2 filters, stride 1, padding is "SAME"380# - **ReLU**381# - **MaxPool2D**: Use a 4 by 4 filter size and a 4 by 4 stride, padding is "SAME"382# - [Flatten](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Flatten) the previous output.383# - Fully-connected ([Dense](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)) layer: Apply a fully connected layer with 6 neurons and a softmax activation.384385# In[143]:386387388# GRADED FUNCTION: convolutional_model389390def convolutional_model(input_shape):391"""392Implements the forward propagation for the model:393CONV2D -> RELU -> MAXPOOL -> CONV2D -> RELU -> MAXPOOL -> FLATTEN -> DENSE394395Note that for simplicity and grading purposes, you'll hard-code some values396such as the stride and kernel (filter) sizes.397Normally, functions should take these values as function parameters.398399Arguments:400input_img -- input dataset, of shape (input_shape)401402Returns:403model -- TF Keras model (object containing the information for the entire training process)404"""405406input_img = tf.keras.Input(shape=input_shape)407## CONV2D: 8 filters 4x4, stride of 1, padding 'SAME'408# Z1 = None409## RELU410# A1 = None411## MAXPOOL: window 8x8, stride 8, padding 'SAME'412# P1 = None413## CONV2D: 16 filters 2x2, stride 1, padding 'SAME'414# Z2 = None415## RELU416# A2 = None417## MAXPOOL: window 4x4, stride 4, padding 'SAME'418# P2 = None419## FLATTEN420# F = None421## Dense layer422## 6 neurons in output layer. Hint: one of the arguments should be "activation='softmax'"423# outputs = None424# YOUR CODE STARTS HERE425426Z1 = tf.keras.layers.Conv2D(filters = 8 , kernel_size= (4,4), strides = (1,1), padding='same')(input_img)427A1 = tf.keras.layers.ReLU()(Z1)428P1 = tf.keras.layers.MaxPool2D(pool_size=(8,8), strides=(8, 8), padding='same')(A1)429Z2 = tf.keras.layers.Conv2D(filters = 16 , kernel_size= (2,2), strides = (1,1), padding='same')(P1)430A2 = tf.keras.layers.ReLU()(Z2)431P2 = tf.keras.layers.MaxPool2D(pool_size=(4,4), strides=(4, 4), padding='same')(A2)432F = tf.keras.layers.Flatten()(P2)433outputs = tf.keras.layers.Dense(units=6, activation='softmax')(F)434435# YOUR CODE ENDS HERE436model = tf.keras.Model(inputs=input_img, outputs=outputs)437return model438439440# In[144]:441442443conv_model = convolutional_model((64, 64, 3))444conv_model.compile(optimizer='adam',445loss='categorical_crossentropy',446metrics=['accuracy'])447conv_model.summary()448449output = [['InputLayer', [(None, 64, 64, 3)], 0],450['Conv2D', (None, 64, 64, 8), 392, 'same', 'linear', 'GlorotUniform'],451['ReLU', (None, 64, 64, 8), 0],452['MaxPooling2D', (None, 8, 8, 8), 0, (8, 8), (8, 8), 'same'],453['Conv2D', (None, 8, 8, 16), 528, 'same', 'linear', 'GlorotUniform'],454['ReLU', (None, 8, 8, 16), 0],455['MaxPooling2D', (None, 2, 2, 16), 0, (4, 4), (4, 4), 'same'],456['Flatten', (None, 64), 0],457['Dense', (None, 6), 390, 'softmax']]458459comparator(summary(conv_model), output)460461462# Both the Sequential and Functional APIs return a TF Keras model object. The only difference is how inputs are handled inside the object model!463464# <a name='4-4'></a>465# ### 4.4 - Train the Model466467# In[ ]:468469470train_dataset = tf.data.Dataset.from_tensor_slices((X_train, Y_train)).batch(64)471test_dataset = tf.data.Dataset.from_tensor_slices((X_test, Y_test)).batch(64)472history = conv_model.fit(train_dataset, epochs=100, validation_data=test_dataset)473474475# <a name='5'></a>476# ## 5 - History Object477#478# The history object is an output of the `.fit()` operation, and provides a record of all the loss and metric values in memory. It's stored as a dictionary that you can retrieve at `history.history`:479480# In[ ]:481482483history.history484485486# Now visualize the loss over time using `history.history`:487488# In[ ]:489490491# The history.history["loss"] entry is a dictionary with as many values as epochs that the492# model was trained on.493df_loss_acc = pd.DataFrame(history.history)494df_loss= df_loss_acc[['loss','val_loss']]495df_loss.rename(columns={'loss':'train','val_loss':'validation'},inplace=True)496df_acc= df_loss_acc[['accuracy','val_accuracy']]497df_acc.rename(columns={'accuracy':'train','val_accuracy':'validation'},inplace=True)498df_loss.plot(title='Model loss',figsize=(12,8)).set(xlabel='Epoch',ylabel='Loss')499df_acc.plot(title='Model Accuracy',figsize=(12,8)).set(xlabel='Epoch',ylabel='Accuracy')500501502# **Congratulations**! You've finished the assignment and built two models: One that recognizes smiles, and another that recognizes SIGN language with almost 80% accuracy on the test set. In addition to that, you now also understand the applications of two Keras APIs: Sequential and Functional. Nicely done!503#504# By now, you know a bit about how the Functional API works and may have glimpsed the possibilities. In your next assignment, you'll really get a feel for its power when you get the opportunity to build a very deep ConvNet, using ResNets!505506# <a name='6'></a>507# ## 6 - Bibliography508#509# You're always encouraged to read the official documentation. To that end, you can find the docs for the Sequential and Functional APIs here:510#511# https://www.tensorflow.org/guide/keras/sequential_model512#513# https://www.tensorflow.org/guide/keras/functional514515516