Code icon

The App is Under a Quick Maintenance

We apologize for the inconvenience. Please come back later

Menu iconMenu iconDeep Learning and AI Superhero
Deep Learning and AI Superhero

Chapter 2: Deep Learning with TensorFlow 2.x

Practical Exercises Chapter 2

Exercise 1: Saving and Loading a TensorFlow Model

Task: Train a simple neural network on the MNIST dataset and save the trained model using the SavedModel format. Then, load the saved model and use it to make predictions on the test set.

Solution:

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten

# Load the MNIST dataset
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Normalize the data
X_train, X_test = X_train / 255.0, X_test / 255.0

# Build a simple neural network model
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

# Save the trained model using SavedModel format
model.save('saved_mnist_model')

# Load the saved model
loaded_model = tf.keras.models.load_model('saved_mnist_model')

# Make predictions with the loaded model
predictions = loaded_model.predict(X_test)
print(f"Predictions for first test sample: {predictions[0]}")

Exercise 2: Saving and Loading Model Checkpoints

Task: Train a neural network and save checkpoints during training. After training, load the weights from the saved checkpoint and use them to continue training.

Solution:

from tensorflow.keras.callbacks import ModelCheckpoint

# Define the checkpoint path
checkpoint_path = "training_checkpoints/cp.ckpt"

# Define the checkpoint callback to save model weights
checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, save_weights_only=True, verbose=1)

# Train the model with checkpoint saving
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test), callbacks=[checkpoint_callback])

# Load the weights from the saved checkpoint
model.load_weights(checkpoint_path)

# Continue training the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

Exercise 3: Deploying a TensorFlow Model with TensorFlow Serving

Task: Save a trained model in the SavedModel format and prepare it for deployment using TensorFlow Serving. Use the requests library to send a prediction request to the served model.

Solution:

# Save the model for TensorFlow Serving
model.save('serving_model/my_served_model')

# Assuming you have TensorFlow Serving set up, you can now serve the model:
# docker pull tensorflow/serving
# docker run -p 8501:8501 --name tf_serving \\
#   --mount type=bind,source=$(pwd)/serving_model/my_served_model,target=/models/my_model \\
#   -e MODEL_NAME=my_model -t tensorflow/serving

# After running TensorFlow Serving, use requests to get predictions:
import requests
import numpy as np
import json

# URL for the TensorFlow Serving API
url = '<http://localhost:8501/v1/models/my_model:predict>'

# Prepare the input data (random data for demonstration)
input_data = np.random.rand(1, 784).tolist()
data = json.dumps({"instances": input_data})

# Send a POST request to the TensorFlow Serving API
response = requests.post(url, data=data)

# Parse the response and display predictions
predictions = json.loads(response.text)['predictions']
print(f"Predictions: {predictions}")

Exercise 4: Converting a Model to TensorFlow Lite

Task: Convert a trained model to TensorFlow Lite format and save it. Then, load the TensorFlow Lite model and run inference using the TensorFlow Lite Interpreter.

Solution:

# Convert the model to TensorFlow Lite format
converter = tf.lite.TFLiteConverter.from_saved_model('saved_mnist_model')
tflite_model = converter.convert()

# Save the TensorFlow Lite model to a file
with open('mnist_model.tflite', 'wb') as f:
    f.write(tflite_model)

# Use TensorFlow Lite Interpreter to run inference
interpreter = tf.lite.Interpreter(model_path='mnist_model.tflite')
interpreter.allocate_tensors()

# Get input and output tensors
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Prepare a test sample
test_sample = np.expand_dims(X_test[0], axis=0).astype(np.float32)

# Set the test sample as the input tensor
interpreter.set_tensor(input_details[0]['index'], test_sample)

# Run the model
interpreter.invoke()

# Get the output tensor
output_data = interpreter.get_tensor(output_details[0]['index'])
print(f"TensorFlow Lite model predictions: {output_data}")

Exercise 5: Fine-Tuning a Pretrained Model from TensorFlow Hub

Task: Load a pretrained model from TensorFlow Hub (e.g., MobileNetV2) and fine-tune it on a new dataset (e.g., the CIFAR-10 dataset). Unfreeze the last few layers and perform fine-tuning.

Solution:

import tensorflow_hub as hub
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential

# Load the CIFAR-10 dataset
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0

# Load a pretrained MobileNetV2 model from TensorFlow Hub
mobilenet_url = "<https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4>"
mobilenet_model = hub.KerasLayer(mobilenet_url, input_shape=(32, 32, 3), trainable=False)

# Build a new model on top of the pretrained MobileNetV2
model = Sequential([
    mobilenet_model,  # Pretrained MobileNetV2
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')  # 10 output classes for CIFAR-10
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Fine-tune the model by unfreezing the last layers
mobilenet_model.trainable = True
for layer in mobilenet_model.layers[:-20]:
    layer.trainable = False

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

These exercises reinforce the key concepts from Chapter 2, including how to save and load models using the SavedModel format and checkpoints, deploy models using TensorFlow Serving, convert models to TensorFlow Lite, and fine-tune pretrained models from TensorFlow Hub. These tasks are crucial for taking models from development to production in real-world applications.

Practical Exercises Chapter 2

Exercise 1: Saving and Loading a TensorFlow Model

Task: Train a simple neural network on the MNIST dataset and save the trained model using the SavedModel format. Then, load the saved model and use it to make predictions on the test set.

Solution:

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten

# Load the MNIST dataset
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Normalize the data
X_train, X_test = X_train / 255.0, X_test / 255.0

# Build a simple neural network model
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

# Save the trained model using SavedModel format
model.save('saved_mnist_model')

# Load the saved model
loaded_model = tf.keras.models.load_model('saved_mnist_model')

# Make predictions with the loaded model
predictions = loaded_model.predict(X_test)
print(f"Predictions for first test sample: {predictions[0]}")

Exercise 2: Saving and Loading Model Checkpoints

Task: Train a neural network and save checkpoints during training. After training, load the weights from the saved checkpoint and use them to continue training.

Solution:

from tensorflow.keras.callbacks import ModelCheckpoint

# Define the checkpoint path
checkpoint_path = "training_checkpoints/cp.ckpt"

# Define the checkpoint callback to save model weights
checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, save_weights_only=True, verbose=1)

# Train the model with checkpoint saving
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test), callbacks=[checkpoint_callback])

# Load the weights from the saved checkpoint
model.load_weights(checkpoint_path)

# Continue training the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

Exercise 3: Deploying a TensorFlow Model with TensorFlow Serving

Task: Save a trained model in the SavedModel format and prepare it for deployment using TensorFlow Serving. Use the requests library to send a prediction request to the served model.

Solution:

# Save the model for TensorFlow Serving
model.save('serving_model/my_served_model')

# Assuming you have TensorFlow Serving set up, you can now serve the model:
# docker pull tensorflow/serving
# docker run -p 8501:8501 --name tf_serving \\
#   --mount type=bind,source=$(pwd)/serving_model/my_served_model,target=/models/my_model \\
#   -e MODEL_NAME=my_model -t tensorflow/serving

# After running TensorFlow Serving, use requests to get predictions:
import requests
import numpy as np
import json

# URL for the TensorFlow Serving API
url = '<http://localhost:8501/v1/models/my_model:predict>'

# Prepare the input data (random data for demonstration)
input_data = np.random.rand(1, 784).tolist()
data = json.dumps({"instances": input_data})

# Send a POST request to the TensorFlow Serving API
response = requests.post(url, data=data)

# Parse the response and display predictions
predictions = json.loads(response.text)['predictions']
print(f"Predictions: {predictions}")

Exercise 4: Converting a Model to TensorFlow Lite

Task: Convert a trained model to TensorFlow Lite format and save it. Then, load the TensorFlow Lite model and run inference using the TensorFlow Lite Interpreter.

Solution:

# Convert the model to TensorFlow Lite format
converter = tf.lite.TFLiteConverter.from_saved_model('saved_mnist_model')
tflite_model = converter.convert()

# Save the TensorFlow Lite model to a file
with open('mnist_model.tflite', 'wb') as f:
    f.write(tflite_model)

# Use TensorFlow Lite Interpreter to run inference
interpreter = tf.lite.Interpreter(model_path='mnist_model.tflite')
interpreter.allocate_tensors()

# Get input and output tensors
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Prepare a test sample
test_sample = np.expand_dims(X_test[0], axis=0).astype(np.float32)

# Set the test sample as the input tensor
interpreter.set_tensor(input_details[0]['index'], test_sample)

# Run the model
interpreter.invoke()

# Get the output tensor
output_data = interpreter.get_tensor(output_details[0]['index'])
print(f"TensorFlow Lite model predictions: {output_data}")

Exercise 5: Fine-Tuning a Pretrained Model from TensorFlow Hub

Task: Load a pretrained model from TensorFlow Hub (e.g., MobileNetV2) and fine-tune it on a new dataset (e.g., the CIFAR-10 dataset). Unfreeze the last few layers and perform fine-tuning.

Solution:

import tensorflow_hub as hub
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential

# Load the CIFAR-10 dataset
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0

# Load a pretrained MobileNetV2 model from TensorFlow Hub
mobilenet_url = "<https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4>"
mobilenet_model = hub.KerasLayer(mobilenet_url, input_shape=(32, 32, 3), trainable=False)

# Build a new model on top of the pretrained MobileNetV2
model = Sequential([
    mobilenet_model,  # Pretrained MobileNetV2
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')  # 10 output classes for CIFAR-10
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Fine-tune the model by unfreezing the last layers
mobilenet_model.trainable = True
for layer in mobilenet_model.layers[:-20]:
    layer.trainable = False

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

These exercises reinforce the key concepts from Chapter 2, including how to save and load models using the SavedModel format and checkpoints, deploy models using TensorFlow Serving, convert models to TensorFlow Lite, and fine-tune pretrained models from TensorFlow Hub. These tasks are crucial for taking models from development to production in real-world applications.

Practical Exercises Chapter 2

Exercise 1: Saving and Loading a TensorFlow Model

Task: Train a simple neural network on the MNIST dataset and save the trained model using the SavedModel format. Then, load the saved model and use it to make predictions on the test set.

Solution:

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten

# Load the MNIST dataset
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Normalize the data
X_train, X_test = X_train / 255.0, X_test / 255.0

# Build a simple neural network model
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

# Save the trained model using SavedModel format
model.save('saved_mnist_model')

# Load the saved model
loaded_model = tf.keras.models.load_model('saved_mnist_model')

# Make predictions with the loaded model
predictions = loaded_model.predict(X_test)
print(f"Predictions for first test sample: {predictions[0]}")

Exercise 2: Saving and Loading Model Checkpoints

Task: Train a neural network and save checkpoints during training. After training, load the weights from the saved checkpoint and use them to continue training.

Solution:

from tensorflow.keras.callbacks import ModelCheckpoint

# Define the checkpoint path
checkpoint_path = "training_checkpoints/cp.ckpt"

# Define the checkpoint callback to save model weights
checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, save_weights_only=True, verbose=1)

# Train the model with checkpoint saving
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test), callbacks=[checkpoint_callback])

# Load the weights from the saved checkpoint
model.load_weights(checkpoint_path)

# Continue training the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

Exercise 3: Deploying a TensorFlow Model with TensorFlow Serving

Task: Save a trained model in the SavedModel format and prepare it for deployment using TensorFlow Serving. Use the requests library to send a prediction request to the served model.

Solution:

# Save the model for TensorFlow Serving
model.save('serving_model/my_served_model')

# Assuming you have TensorFlow Serving set up, you can now serve the model:
# docker pull tensorflow/serving
# docker run -p 8501:8501 --name tf_serving \\
#   --mount type=bind,source=$(pwd)/serving_model/my_served_model,target=/models/my_model \\
#   -e MODEL_NAME=my_model -t tensorflow/serving

# After running TensorFlow Serving, use requests to get predictions:
import requests
import numpy as np
import json

# URL for the TensorFlow Serving API
url = '<http://localhost:8501/v1/models/my_model:predict>'

# Prepare the input data (random data for demonstration)
input_data = np.random.rand(1, 784).tolist()
data = json.dumps({"instances": input_data})

# Send a POST request to the TensorFlow Serving API
response = requests.post(url, data=data)

# Parse the response and display predictions
predictions = json.loads(response.text)['predictions']
print(f"Predictions: {predictions}")

Exercise 4: Converting a Model to TensorFlow Lite

Task: Convert a trained model to TensorFlow Lite format and save it. Then, load the TensorFlow Lite model and run inference using the TensorFlow Lite Interpreter.

Solution:

# Convert the model to TensorFlow Lite format
converter = tf.lite.TFLiteConverter.from_saved_model('saved_mnist_model')
tflite_model = converter.convert()

# Save the TensorFlow Lite model to a file
with open('mnist_model.tflite', 'wb') as f:
    f.write(tflite_model)

# Use TensorFlow Lite Interpreter to run inference
interpreter = tf.lite.Interpreter(model_path='mnist_model.tflite')
interpreter.allocate_tensors()

# Get input and output tensors
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Prepare a test sample
test_sample = np.expand_dims(X_test[0], axis=0).astype(np.float32)

# Set the test sample as the input tensor
interpreter.set_tensor(input_details[0]['index'], test_sample)

# Run the model
interpreter.invoke()

# Get the output tensor
output_data = interpreter.get_tensor(output_details[0]['index'])
print(f"TensorFlow Lite model predictions: {output_data}")

Exercise 5: Fine-Tuning a Pretrained Model from TensorFlow Hub

Task: Load a pretrained model from TensorFlow Hub (e.g., MobileNetV2) and fine-tune it on a new dataset (e.g., the CIFAR-10 dataset). Unfreeze the last few layers and perform fine-tuning.

Solution:

import tensorflow_hub as hub
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential

# Load the CIFAR-10 dataset
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0

# Load a pretrained MobileNetV2 model from TensorFlow Hub
mobilenet_url = "<https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4>"
mobilenet_model = hub.KerasLayer(mobilenet_url, input_shape=(32, 32, 3), trainable=False)

# Build a new model on top of the pretrained MobileNetV2
model = Sequential([
    mobilenet_model,  # Pretrained MobileNetV2
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')  # 10 output classes for CIFAR-10
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Fine-tune the model by unfreezing the last layers
mobilenet_model.trainable = True
for layer in mobilenet_model.layers[:-20]:
    layer.trainable = False

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

These exercises reinforce the key concepts from Chapter 2, including how to save and load models using the SavedModel format and checkpoints, deploy models using TensorFlow Serving, convert models to TensorFlow Lite, and fine-tune pretrained models from TensorFlow Hub. These tasks are crucial for taking models from development to production in real-world applications.

Practical Exercises Chapter 2

Exercise 1: Saving and Loading a TensorFlow Model

Task: Train a simple neural network on the MNIST dataset and save the trained model using the SavedModel format. Then, load the saved model and use it to make predictions on the test set.

Solution:

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten

# Load the MNIST dataset
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Normalize the data
X_train, X_test = X_train / 255.0, X_test / 255.0

# Build a simple neural network model
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

# Save the trained model using SavedModel format
model.save('saved_mnist_model')

# Load the saved model
loaded_model = tf.keras.models.load_model('saved_mnist_model')

# Make predictions with the loaded model
predictions = loaded_model.predict(X_test)
print(f"Predictions for first test sample: {predictions[0]}")

Exercise 2: Saving and Loading Model Checkpoints

Task: Train a neural network and save checkpoints during training. After training, load the weights from the saved checkpoint and use them to continue training.

Solution:

from tensorflow.keras.callbacks import ModelCheckpoint

# Define the checkpoint path
checkpoint_path = "training_checkpoints/cp.ckpt"

# Define the checkpoint callback to save model weights
checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, save_weights_only=True, verbose=1)

# Train the model with checkpoint saving
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test), callbacks=[checkpoint_callback])

# Load the weights from the saved checkpoint
model.load_weights(checkpoint_path)

# Continue training the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

Exercise 3: Deploying a TensorFlow Model with TensorFlow Serving

Task: Save a trained model in the SavedModel format and prepare it for deployment using TensorFlow Serving. Use the requests library to send a prediction request to the served model.

Solution:

# Save the model for TensorFlow Serving
model.save('serving_model/my_served_model')

# Assuming you have TensorFlow Serving set up, you can now serve the model:
# docker pull tensorflow/serving
# docker run -p 8501:8501 --name tf_serving \\
#   --mount type=bind,source=$(pwd)/serving_model/my_served_model,target=/models/my_model \\
#   -e MODEL_NAME=my_model -t tensorflow/serving

# After running TensorFlow Serving, use requests to get predictions:
import requests
import numpy as np
import json

# URL for the TensorFlow Serving API
url = '<http://localhost:8501/v1/models/my_model:predict>'

# Prepare the input data (random data for demonstration)
input_data = np.random.rand(1, 784).tolist()
data = json.dumps({"instances": input_data})

# Send a POST request to the TensorFlow Serving API
response = requests.post(url, data=data)

# Parse the response and display predictions
predictions = json.loads(response.text)['predictions']
print(f"Predictions: {predictions}")

Exercise 4: Converting a Model to TensorFlow Lite

Task: Convert a trained model to TensorFlow Lite format and save it. Then, load the TensorFlow Lite model and run inference using the TensorFlow Lite Interpreter.

Solution:

# Convert the model to TensorFlow Lite format
converter = tf.lite.TFLiteConverter.from_saved_model('saved_mnist_model')
tflite_model = converter.convert()

# Save the TensorFlow Lite model to a file
with open('mnist_model.tflite', 'wb') as f:
    f.write(tflite_model)

# Use TensorFlow Lite Interpreter to run inference
interpreter = tf.lite.Interpreter(model_path='mnist_model.tflite')
interpreter.allocate_tensors()

# Get input and output tensors
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Prepare a test sample
test_sample = np.expand_dims(X_test[0], axis=0).astype(np.float32)

# Set the test sample as the input tensor
interpreter.set_tensor(input_details[0]['index'], test_sample)

# Run the model
interpreter.invoke()

# Get the output tensor
output_data = interpreter.get_tensor(output_details[0]['index'])
print(f"TensorFlow Lite model predictions: {output_data}")

Exercise 5: Fine-Tuning a Pretrained Model from TensorFlow Hub

Task: Load a pretrained model from TensorFlow Hub (e.g., MobileNetV2) and fine-tune it on a new dataset (e.g., the CIFAR-10 dataset). Unfreeze the last few layers and perform fine-tuning.

Solution:

import tensorflow_hub as hub
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential

# Load the CIFAR-10 dataset
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0

# Load a pretrained MobileNetV2 model from TensorFlow Hub
mobilenet_url = "<https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4>"
mobilenet_model = hub.KerasLayer(mobilenet_url, input_shape=(32, 32, 3), trainable=False)

# Build a new model on top of the pretrained MobileNetV2
model = Sequential([
    mobilenet_model,  # Pretrained MobileNetV2
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')  # 10 output classes for CIFAR-10
])

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Fine-tune the model by unfreezing the last layers
mobilenet_model.trainable = True
for layer in mobilenet_model.layers[:-20]:
    layer.trainable = False

# Train the model
model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

These exercises reinforce the key concepts from Chapter 2, including how to save and load models using the SavedModel format and checkpoints, deploy models using TensorFlow Serving, convert models to TensorFlow Lite, and fine-tune pretrained models from TensorFlow Hub. These tasks are crucial for taking models from development to production in real-world applications.