Nv dli fundamentals of dl
At times you will need to clear the GPUs memory, either to reset the GPU state when an experiment goes wrong, or, in between notebooks when you need a fresh start for a new set of exercises.
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
MNIST
from tensorflow.keras.datasets import mnist
# the data, split between train and validation sets
(x_train, y_train), (x_valid, y_valid) = mnist.load_data()
x_train.shape
x_valid.shape
x_train.dtype
x_train.min()
x_train.max()
import matplotlib.pyplot as plt
image = x_train[0]
plt.imshow(image, cmap='gray')
y_train[0]
#Flatten the image
x_train = x_train.reshape(60000, 784)
x_valid = x_valid.reshape(10000, 784)
x_train.shape
#Normalize Data
x_train = x_train / 255
x_valid = x_valid / 255
x_train.dtype
x_train.min()
x_train.max()
#Categorically Encoding the Labels
import tensorflow.keras as keras
num_categories = 10
y_train = keras.utils.to_categorical(y_train, num_categories)
y_valid = keras.utils.to_categorical(y_valid, num_categories)
y_train[0:9]
#Instantiating the Model
from tensorflow.keras.models import Sequential
model = Sequential()
from tensorflow.keras.layers import Dense
model.add(Dense(units=512, activation='relu', input_shape=(784,)))
model.add(Dense(units = 512, activation='relu'))
model.add(Dense(units = 10, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', metrics=['accuracy'])
history = model.fit(
x_train, y_train, epochs=5, verbose=1, validation_data=(x_valid, y_valid)
)
Image Classification of an American Sign Language Dataset
import pandas as pd
train_df = pd.read_csv("data/asl_data/sign_mnist_train.csv")
valid_df = pd.read_csv("data/asl_data/sign_mnist_valid.csv")
#Extracting the Labels and Images
y_train = train_df['label']
y_valid = valid_df['label']
del train_df['label']
del valid_df['label']
x_train = train_df.values
x_valid = valid_df.values
x_train.shape
y_train.shape
x_valid.shape
y_valid.shape
import matplotlib.pyplot as plt
plt.figure(figsize=(40,40))
num_images = 20
for i in range(num_images):
row = x_train[i]
label = y_train[i]
image = row.reshape(28,28)
plt.subplot(1, num_images, i+1)
plt.title(label, fontdict={'fontsize': 30})
plt.axis('off')
plt.imshow(image, cmap='gray')
#Normalize the Image Data
x_train.min()
x_train.max()
# TODO: Normalize x_train and x_valid.
x_train = x_train / 255
x_valid = x_valid / 255
#Categorize the Labels
import tensorflow.keras as keras
num_classes = 24
# TODO: Categorically encode y_train and y_valid.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_valid = keras.utils.to_categorical(y_valid, num_classes)
#Build the Model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# TODO: build a model following the guidelines above.
model = Sequential([
Dense(units=512, activation='relu', input_shape=(784,)),
Dense(units = 512, activation='relu'),
Dense(units = 24, activation='softmax')])
model.summary()
model.compile(loss='categorical_crossentropy', metrics=['accuracy'])
# TODO: Train the model for 20 epochs.
history = model.fit(
x_train, y_train, epochs=20, verbose=1, validation_data=(x_valid, y_valid)
)
#This is an example of the model learning to categorize the training data, but performing poorly against new data that it has not been trained on. Essentially, it is memorizing the dataset, but not gaining a robust and general understanding of the problem. This is a common issue called overfitting. We will discuss overfitting in the next two lectures, as well as some ways to address it.
CNN
#Loading and Preparing the Data
import tensorflow.keras as keras
import pandas as pd
# Load in our data from CSV files
train_df = pd.read_csv("data/asl_data/sign_mnist_train.csv")
valid_df = pd.read_csv("data/asl_data/sign_mnist_valid.csv")
# Separate out our target values
y_train = train_df['label']
y_valid = valid_df['label']
del train_df['label']
del valid_df['label']
# Separate out our image vectors
x_train = train_df.values
x_valid = valid_df.values
# Turn our scalar targets into binary categories
num_classes = 24
y_train = keras.utils.to_categorical(y_train, num_classes)
y_valid = keras.utils.to_categorical(y_valid, num_classes)
# Normalize our image data
x_train = x_train / 255
x_valid = x_valid / 255
#Reshaping Images
x_train.shape, x_valid.shape
x_train = x_train.reshape(-1,28,28,1)
x_valid = x_valid.reshape(-1,28,28,1)
x_train.shape
x_valid.shape
x_train.shape, x_valid.shape
#Create a Convolutional Model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import (
Dense,
Conv2D,
MaxPool2D,
Flatten,
Dropout,
BatchNormalization,
)
model = Sequential()
model.add(Conv2D(75, (3, 3), strides=1, padding="same", activation="relu",
input_shape=(28, 28, 1)))
model.add(BatchNormalization())
model.add(MaxPool2D((2, 2), strides=2, padding="same"))
model.add(Conv2D(50, (3, 3), strides=1, padding="same", activation="relu"))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(MaxPool2D((2, 2), strides=2, padding="same"))
model.add(Conv2D(25, (3, 3), strides=1, padding="same", activation="relu"))
model.add(BatchNormalization())
model.add(MaxPool2D((2, 2), strides=2, padding="same"))
model.add(Flatten())
model.add(Dense(units=512, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(units=num_classes, activation="softmax"))
model.summary()
model.compile(loss="categorical_crossentropy", metrics=["accuracy"])
model.fit(x_train, y_train, epochs=20, verbose=1, validation_data=(x_valid, y_valid))
Data Augmentation
import tensorflow.keras as keras
import pandas as pd
# Load in our data from CSV files
train_df = pd.read_csv("data/asl_data/sign_mnist_train.csv")
valid_df = pd.read_csv("data/asl_data/sign_mnist_valid.csv")
# Separate out our target values
y_train = train_df['label']
y_valid = valid_df['label']
del train_df['label']
del valid_df['label']
# Separate our our image vectors
x_train = train_df.values
x_valid = valid_df.values
# Turn our scalar targets into binary categories
num_classes = 24
y_train = keras.utils.to_categorical(y_train, num_classes)
y_valid = keras.utils.to_categorical(y_valid, num_classes)
# Normalize our image data
x_train = x_train / 255
x_valid = x_valid / 255
# Reshape the image data for the convolutional network
x_train = x_train.reshape(-1,28,28,1)
x_valid = x_valid.reshape(-1,28,28,1)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import (
Dense,
Conv2D,
MaxPool2D,
Flatten,
Dropout,
BatchNormalization,
)
#Model Creation
model = Sequential()
model.add(Conv2D(75, (3, 3), strides=1, padding="same", activation="relu",
input_shape=(28, 28, 1)))
model.add(BatchNormalization())
model.add(MaxPool2D((2, 2), strides=2, padding="same"))
model.add(Conv2D(50, (3, 3), strides=1, padding="same", activation="relu"))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(MaxPool2D((2, 2), strides=2, padding="same"))
model.add(Conv2D(25, (3, 3), strides=1, padding="same", activation="relu"))
model.add(BatchNormalization())
model.add(MaxPool2D((2, 2), strides=2, padding="same"))
model.add(Flatten())
model.add(Dense(units=512, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(units=num_classes, activation="softmax"))
#Data Augmentation
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range=0.1, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images horizontally
vertical_flip=False, # Don't randomly flip images vertically
)
#Batch Size
import matplotlib.pyplot as plt
import numpy as np
batch_size = 32
img_iter = datagen.flow(x_train, y_train, batch_size=batch_size)
x, y = img_iter.next()
fig, ax = plt.subplots(nrows=4, ncols=8)
for i in range(batch_size):
image = x[i]
ax.flatten()[i].imshow(np.squeeze(image))
plt.show()
#Fitting the Data to the Generator
datagen.fit(x_train)
model.compile(loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(img_iter,
epochs=20,
steps_per_epoch=len(x_train)/batch_size, # Run same number of steps we would if we were not using a generator.
validation_data=(x_valid, y_valid))
#You will notice that the validation accuracy is higher, and more consistent. This means that our model is no longer overfitting in the way it was; it generalizes better, making better predictions on new data.
#Save the Model
model.save('asl_model')
Deploy Your Model
#Loading the Model
from tensorflow import keras
model = keras.models.load_model('asl_model')
model.summary()
#Showing new images
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def show_image(image_path):
image = mpimg.imread(image_path)
plt.imshow(image, cmap='gray')
show_image('data/asl_images/b.png')
#Scaling the Images
from tensorflow.keras.preprocessing import image as image_utils
def load_and_scale_image(image_path):
image = image_utils.load_img(image_path, color_mode="grayscale", target_size=(28,28))
return image
image = load_and_scale_image('data/asl_images/b.png')
plt.imshow(image, cmap='gray')
#Preparing the Image for prediction
type(image) # -> PIL.Image.Image
image = image_utils.img_to_array(image)
# This reshape corresponds to 1 image of 28x28 pixels with one color channel
image = image.reshape(1,28,28,1)
image = image / 255
#Making Prediction
prediction = model.predict(image)
print(prediction)
#Understanding the Prediction
import numpy as np
np.argmax(prediction)
# Alphabet does not contain j or z because they require movement
alphabet = "abcdefghiklmnopqrstuvwxy"
dictionary = {}
for i in range(24):
dictionary[i] = alphabet[i]
dictionary
dictionary[np.argmax(prediction)]
#Put it all Together
def predict_letter(file_path):
# Show image
show_image(file_path)
# Load and scale image
image = load_and_scale_image(file_path)
# Convert to array
image = image_utils.img_to_array(image)
# Reshape image
image = image.reshape(1,28,28,1)
# Normalize image
image = image / 255
# Make prediction
prediction = model.predict(image)
# Convert prediction to letter
predicted_letter = dictionary[np.argmax(prediction)]
# Return prediction
return predicted_letter
predict_letter("data/asl_images/b.png")
predict_letter("data/asl_images/a.png")
Pre-Trained Models
from tensorflow.keras.applications import VGG16
# load the VGG16 network *pre-trained* on the ImageNet dataset
model = VGG16(weights="imagenet")
model.summary()
#Loading an image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def show_image(image_path):
image = mpimg.imread(image_path)
print(image.shape)
plt.imshow(image)
show_image("data/doggy_door_images/happy_dog.jpg")
#Preprocessing the Image
from tensorflow.keras.preprocessing import image as image_utils
from tensorflow.keras.applications.vgg16 import preprocess_input
def load_and_process_image(image_path):
# Print image's original shape, for reference
print('Original image shape: ', mpimg.imread(image_path).shape)
# Load in the image with a target size of 224, 224
image = image_utils.load_img(image_path, target_size=(224, 224))
# Convert the image from a PIL format to a numpy array
image = image_utils.img_to_array(image)
# Add a dimension for number of images, in our case 1
image = image.reshape(1,224,224,3)
# Preprocess image to align with original ImageNet dataset
image = preprocess_input(image)
# Print image's shape after processing
print('Processed image shape: ', image.shape)
return image
processed_image = load_and_process_image("data/doggy_door_images/brown_bear.jpg")
#Make a prediction
from tensorflow.keras.applications.vgg16 import decode_predictions
def readable_prediction(image_path):
# Show image
show_image(image_path)
# Load and pre-process image
image = load_and_process_image(image_path)
# Make predictions
predictions = model.predict(image)
# Print predictions in readable form
print('Predicted:', decode_predictions(predictions, top=3))
readable_prediction("data/doggy_door_images/happy_dog.jpg")
readable_prediction("data/doggy_door_images/brown_bear.jpg")
readable_prediction("data/doggy_door_images/sleepy_cat.jpg")
#Only Dogs
import numpy as np
def doggy_door(image_path):
show_image(image_path)
image = load_and_process_image(image_path)
preds = model.predict(image)
if (np.argmax(preds) >= 151) and (np.argmax(preds) <= 268):
print("Doggy come on in!")
elif (np.argmax(preds) >= 281) and (np.argmax(preds) <= 285):
print("Kitty stay inside!")
else:
print("You're not a dog! Stay outside!")
readable_prediction("data/doggy_door_images/happy_dog.jpg")
readable_prediction("data/doggy_door_images/brown_bear.jpg")
readable_prediction("data/doggy_door_images/sleepy_cat.jpg")
Transfer Learning
from tensorflow import keras
base_model = keras.applications.VGG16(
weights='imagenet', # Load weights pre-trained on ImageNet.
input_shape=(224, 224, 3),
include_top=False)
base_model.summary()
#Freezing the Base Model
base_model.trainable = False
#Adding New Layers
inputs = keras.Input(shape=(224, 224, 3))
# Separately from setting trainable on the model, we set training to False
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
# A Dense classifier with a single unit (binary classification)
outputs = keras.layers.Dense(1)(x)
model = keras.Model(inputs, outputs)
model.summary()
model.compile(loss=keras.losses.BinaryCrossentropy(from_logits=True), metrics=[keras.metrics.BinaryAccuracy()])
#Data Augumentation
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# create a data generator
datagen = ImageDataGenerator(
samplewise_center=True, # set each sample mean to 0
rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range = 0.1, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # we don't expect Bo to be upside-down so we will not flip vertically
#Loading the data
# load and iterate training dataset
train_it = datagen.flow_from_directory('data/presidential_doggy_door/train/',
target_size=(224, 224),
color_mode='rgb',
class_mode='binary',
batch_size=8)
# load and iterate validation dataset
valid_it = datagen.flow_from_directory('data/presidential_doggy_door/valid/',
target_size=(224, 224),
color_mode='rgb',
class_mode='binary',
batch_size=8)
model.fit(train_it, steps_per_epoch=12, validation_data=valid_it, validation_steps=4, epochs=20)
#Fine-tuning the Model
# Unfreeze the base model
base_model.trainable = True
# It's important to recompile your model after you make any changes
# to the `trainable` attribute of any inner layer, so that your changes
# are taken into account
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate = .00001), # Very low learning rate
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()])
model.fit(train_it, steps_per_epoch=12, validation_data=valid_it, validation_steps=4, epochs=10)
#Examing the Predictions
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from tensorflow.keras.preprocessing import image as image_utils
from tensorflow.keras.applications.imagenet_utils import preprocess_input
def show_image(image_path):
image = mpimg.imread(image_path)
plt.imshow(image)
def make_predictions(image_path):
show_image(image_path)
image = image_utils.load_img(image_path, target_size=(224, 224))
image = image_utils.img_to_array(image)
image = image.reshape(1,224,224,3)
image = preprocess_input(image)
preds = model.predict(image)
return preds
make_predictions('data/presidential_doggy_door/valid/bo/bo_20.jpg')
make_predictions('data/presidential_doggy_door/valid/not_bo/121.jpg')
#Bo's Doggy Door
def presidential_doggy_door(image_path):
preds = make_predictions(image_path)
if preds[0] < 0:
print("It's Bo! Let him in!")
else:
print("That's not Bo! Stay out!")
presidential_doggy_door('data/presidential_doggy_door/valid/not_bo/131.jpg')
presidential_doggy_door('data/presidential_doggy_door/valid/bo/bo_29.jpg')
Sequence Data
#Reading in the Data
import os
import pandas as pd
nyt_dir = 'data/nyt_dataset/articles/'
all_headlines = []
for filename in os.listdir(nyt_dir):
if 'Articles' in filename:
# Read in all the data from the CSV file
headlines_df = pd.read_csv(nyt_dir + filename)
# Add all of the headlines to our list
all_headlines.extend(list(headlines_df.headline.values))
len(all_headlines)
all_headlines[:20]
#Clearning the data
# Remove all headlines with the value of "Unknown"
all_headlines = [h for h in all_headlines if h != "Unknown"]
len(all_headlines)
all_headlines[:20]
#Tokenization
from tensorflow.keras.preprocessing.text import Tokenizer
# Tokenize the words in our headlines
tokenizer = Tokenizer()
tokenizer.fit_on_texts(all_headlines)
total_words = len(tokenizer.word_index) + 1
print('Total words: ', total_words)
# Print a subset of the word_index dictionary created by Tokenizer
subset_dict = {key: value for key, value in tokenizer.word_index.items() \
if key in ['a','man','a','plan','a','canal','panama']}
print(subset_dict)
tokenizer.texts_to_sequences(['a','man','a','plan','a','canal','panama'])
#Creating Sequences
# Convert data to sequence of tokens
input_sequences = []
for line in all_headlines:
# Convert our headline into a sequence of tokens
token_list = tokenizer.texts_to_sequences([line])[0]
# Create a series of sequences for each headline
for i in range(1, len(token_list)):
partial_sequence = token_list[:i+1]
input_sequences.append(partial_sequence)
print(tokenizer.sequences_to_texts(input_sequences[:5]))
input_sequences[:5]
#Padding Sequences
from tensorflow.keras.preprocessing.sequence import pad_sequences
import numpy as np
# Determine max sequence length
max_sequence_len = max([len(x) for x in input_sequences])
# Pad all sequences with zeros at the beginning to make them all max length
input_sequences = np.array(pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre'))
input_sequences[0]
#Creating Predictors and Target
# Predictors are every word except the last
predictors = input_sequences[:,:-1]
# Labels are the last word
labels = input_sequences[:,-1]
labels[:5]
from tensorflow.keras import utils
labels = utils.to_categorical(labels, num_classes=total_words)
#Creating the Model
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
from tensorflow.keras.models import Sequential
# Input is max sequence length - 1, as we've removed the last word for the label
input_len = max_sequence_len - 1
model = Sequential()
# Add input embedding layer
model.add(Embedding(total_words, 10, input_length=input_len))
# Add LSTM layer with 100 units
model.add(LSTM(100))
model.add(Dropout(0.1))
# Add output layer
model.add(Dense(total_words, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam')
model.fit(predictors, labels, epochs=30, verbose=1)
#Making Predictions
def predict_next_token(seed_text):
token_list = tokenizer.texts_to_sequences([seed_text])[0]
token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
prediction = model.predict_classes(token_list, verbose=0)
return prediction
prediction = predict_next_token("today in new york")
prediction
tokenizer.sequences_to_texts([prediction])
#Creating New Headlines
def generate_headline(seed_text, next_words=1):
for _ in range(next_words):
# Predict next token
prediction = predict_next_token(seed_text)
# Convert token to word
next_word = tokenizer.sequences_to_texts([prediction])[0]
# Add next word to the headline. This headline will be used in the next pass of the loop.
seed_text += " " + next_word
# Return headline as title-case
return seed_text.title()
seed_texts = [
'washington dc is',
'today in new york',
'the school district has',
'crime has become']
for seed in seed_texts:
print(generate_headline(seed, next_words=5))
Assessment
from tensorflow import keras
base_model = keras.applications.VGG16(
weights="imagenet",
input_shape=(224, 224, 3),
include_top=False)
# Freeze base model
base_model.trainable = False
# Create inputs with correct shape
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
# Add pooling layer or flatten layer
x = keras.layers.GlobalAveragePooling2D()(x)
# Add final dense layer
outputs = keras.layers.Dense(6, activation = 'softmax')(x)
# Combine inputs and outputs to create model
model = keras.Model(inputs, outputs)
model.summary()
model.compile(loss='categorical_crossentropy', metrics=['accuracy'])
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
samplewise_center=True, # set each sample mean to 0
rotation_range=180, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range = 0.1, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=True)
# load and iterate training dataset
train_it = datagen.flow_from_directory('data/fruits/train/',
target_size=(224, 224),
color_mode='rgb',
class_mode="categorical")
# load and iterate validation dataset
valid_it = datagen.flow_from_directory('data/fruits/valid/',
target_size=(224, 224),
color_mode='rgb',
class_mode="categorical")
model.fit(train_it,
validation_data=valid_it,
steps_per_epoch=train_it.samples/train_it.batch_size,
validation_steps=valid_it.samples/valid_it.batch_size,
epochs=20)
# Unfreeze the base model
base_model.trainable = True
# Compile the model with a low learning rate
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate = .00001),
loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(FIXME,
validation_data=FIXME,
steps_per_epoch=train_it.samples/train_it.batch_size,
validation_steps=valid_it.samples/valid_it.batch_size,
epochs=20)
model.evaluate(valid_it, steps=valid_it.samples/valid_it.batch_size)
from run_assessment import run_assessment
run_assessment(model, valid_it)