0% found this document useful (0 votes)
25 views24 pages

Vertopal.com HW4ML Project Code

This document provides a Phase-1 code starter template for training and evaluating deep learning models using TensorFlow on the Fashion MNIST and CIFAR-10 datasets. It includes functions for model creation, dataset preparation, training, evaluation, and visualization of training curves and confusion matrices. The code emphasizes the importance of ensuring correctness and allows for modifications by the user.

Uploaded by

Amal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views24 pages

Vertopal.com HW4ML Project Code

This document provides a Phase-1 code starter template for training and evaluating deep learning models using TensorFlow on the Fashion MNIST and CIFAR-10 datasets. It includes functions for model creation, dataset preparation, training, evaluation, and visualization of training curves and confusion matrices. The code emphasizes the importance of ensuring correctness and allows for modifications by the user.

Uploaded by

Amal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 24

Phase-1 code starter template

The below code is for your reference; please feel free to change it partially or
fully.

Please make sure it does not have any bugs or mistakes. Code authors DO NOT claim
the code is bug-free. It is the student's responsibility to ensure its correctness.

# Changes: Added training curves (loss and accuracy) and confusion matrix
plotting after evaluation.
# Improved output tracking (history, labels), added Seaborn visualization
style, modularized plotting, and profiled inference latency.

# Import required libraries


import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import fashion_mnist, cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.callbacks import EarlyStopping
import time
import numpy as np
from tqdm import tqdm
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

# Set Seaborn style


sns.set_style('whitegrid')

# Create Base Model


def create_base_model(input_shape, num_classes):
model = models.Sequential([
layers.Conv2D(16, (3, 3), activation='relu', input_shape=input_shape),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(2, activation='relu'),
layers.Dense(num_classes, activation='softmax')
])
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
return model

# Load and Prepare Dataset


def prepare_dataset(dataset_name):
if dataset_name == 'fashion_mnist':
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
num_classes = 10
input_shape = (28, 28, 1)
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
elif dataset_name == 'cifar10':
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
num_classes = 10
input_shape = (32, 32, 3)
else:
raise ValueError(f"Unsupported dataset: {dataset_name}")
# Normalize and one-hot encode
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
y_train = to_categorical(y_train, num_classes)
y_test = to_categorical(y_test, num_classes)

return (x_train, y_train), (x_test, y_test), input_shape, num_classes

# Train and Evaluate Model


def evaluate_model(dataset_name, max_epoch, device):
(x_train, y_train), (x_test, y_test), input_shape, num_classes =
prepare_dataset(dataset_name)

with tf.device(device):
model = create_base_model(input_shape, num_classes)
early_stop = EarlyStopping(monitor='val_loss', patience=3,
restore_best_weights=True)

# Train model and time it


start_time = time.time()
history = model.fit(x_train, y_train, epochs=max_epoch, batch_size=64,
validation_split=0.2,
callbacks=[early_stop], verbose=1)
train_time = time.time() - start_time

# Evaluate model and time it


start_time = time.time()
test_loss, test_accuracy = model.evaluate(x_test, y_test, verbose=0)
eval_time = time.time() - start_time

# Count model parameters


num_param = model.count_params()

# Print key metrics


print(f"{dataset_name.upper()} Test Accuracy: {test_accuracy * 100:.2f}
%")
print(f"{dataset_name.upper()} Number of Parameters: {num_param}")

return model, num_param, x_test, y_test, test_accuracy, train_time,


eval_time, history

# Profile Inference Latency


def profile_workload(model, device, dev_name, image, iterations=30):
print(f"Profiling on {dev_name}...")
latencies = []
with tf.device(device):

# Warm-up
for _ in tqdm(range(10), desc="Warm-up..."):
_ = model(image, training=False)

# Actual profiling
for _ in tqdm(range(iterations), desc="Profiling"):
start = time.time()
_ = model(image, training=False)
latencies.append((time.time() - start) * 1000)
avg_latency = np.mean(latencies)
print(f"Average Latency on {dev_name}: {avg_latency:.2f} ms")

# Predict a single sample to verify model is working


prediction = model(image, training=False)
predicted_class = tf.argmax(prediction, axis=1).numpy()[0]
print(f"Predicted Class: {predicted_class}")
return avg_latency

# Plot Training Curves


def plot_training_curves(history, dataset):
fig, axs = plt.subplots(1, 2, figsize=(14,5))

# Loss plot
sns.lineplot(x=range(len(history.history['loss'])),
y=history.history['loss'], label='Train Loss', ax=axs[0])
sns.lineplot(x=range(len(history.history['val_loss'])),
y=history.history['val_loss'], label='Val Loss', ax=axs[0])
axs[0].set_title(f'{dataset.upper()} Loss Curves (Phase 1)')
axs[0].set_xlabel('Epoch')
axs[0].legend()

# Accuracy plot
sns.lineplot(x=range(len(history.history['accuracy'])),
y=history.history['accuracy'], label='Train Accuracy', ax=axs[1])
sns.lineplot(x=range(len(history.history['val_accuracy'])),
y=history.history['val_accuracy'], label='Val Accuracy', ax=axs[1])
axs[1].set_title(f'{dataset.upper()} Accuracy Curves (Phase 1)')
axs[1].set_xlabel('Epoch')
axs[1].legend()

plt.show()

# Plot Confusion Matrix


def plot_confusion_matrix(y_true, y_pred_logits, dataset):
y_pred = np.argmax(y_pred_logits, axis=1)
y_true = np.argmax(y_true, axis=1)

cm = confusion_matrix(y_true, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm)
disp.plot(cmap='Blues', colorbar=True, xticks_rotation='horizontal',
values_format='.0f')
plt.grid(False)
plt.title(f'{dataset.upper()} Confusion Matrix (Phase 1)')
plt.show()

# --- MAIN CODE ---

# Device priority: CUDA > MPS > CPU


if tf.config.list_physical_devices('GPU'):
device = '/GPU:0'
dev_name = 'GPU'
elif tf.config.list_physical_devices('MPS'):
device = '/MPS:0'
dev_name = 'Apple MPS'
else:
device = '/CPU:0'
dev_name = 'CPU'
print(f'Using {dev_name}')
# Process datasets
datasets = ['fashion_mnist', 'cifar10']
for dataset in datasets:
print(f"\nProcessing {dataset}...")
model, num_param, x_test, y_test, acc, train_t, eval_t, history =
evaluate_model(dataset, max_epoch=25, device=device)
test_image = tf.convert_to_tensor(x_test[:1], dtype=tf.float32)
profile_workload(model, device, dev_name, test_image)

# Plot training curves


plot_training_curves(history, dataset)

# Plot confusion matrix


preds = model.predict(x_test)
plot_confusion_matrix(y_test, preds, dataset)

Using GPU

Processing fashion_mnist...

/usr/local/lib/python3.11/dist-packages/keras/src/layers/convolutional/
base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to
a layer. When using Sequential models, prefer using an `Input(shape)` object as the
first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)

Epoch 1/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 6s 5ms/step - accuracy: 0.2690 - loss: 1.8617 -
val_accuracy: 0.4932 - val_loss: 1.2464
Epoch 2/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.5282 - loss: 1.1878 -
val_accuracy: 0.5634 - val_loss: 1.0459
Epoch 3/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.6135 - loss: 1.0204 -
val_accuracy: 0.6611 - val_loss: 0.9355
Epoch 4/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.6758 - loss: 0.9117 -
val_accuracy: 0.6761 - val_loss: 0.8660
Epoch 5/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.6896 - loss: 0.8498 -
val_accuracy: 0.6996 - val_loss: 0.8167
Epoch 6/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.7000 - loss: 0.8085 -
val_accuracy: 0.6949 - val_loss: 0.7866
Epoch 7/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - accuracy: 0.7092 - loss: 0.7762 -
val_accuracy: 0.7139 - val_loss: 0.7606
Epoch 8/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7223 - loss: 0.7422 -
val_accuracy: 0.7097 - val_loss: 0.7435
Epoch 9/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.7254 - loss: 0.7172 -
val_accuracy: 0.7230 - val_loss: 0.7250
Epoch 10/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7302 - loss: 0.7048 -
val_accuracy: 0.7233 - val_loss: 0.7121
Epoch 11/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7307 - loss: 0.6927 -
val_accuracy: 0.7243 - val_loss: 0.7012
Epoch 12/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7368 - loss: 0.6827 -
val_accuracy: 0.7296 - val_loss: 0.6947
Epoch 13/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7388 - loss: 0.6714 -
val_accuracy: 0.7285 - val_loss: 0.6849
Epoch 14/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.7430 - loss: 0.6567 -
val_accuracy: 0.7322 - val_loss: 0.6778
Epoch 15/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7401 - loss: 0.6531 -
val_accuracy: 0.7357 - val_loss: 0.6683
Epoch 16/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7448 - loss: 0.6419 -
val_accuracy: 0.7332 - val_loss: 0.6697
Epoch 17/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7472 - loss: 0.6391 -
val_accuracy: 0.7381 - val_loss: 0.6587
Epoch 18/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7455 - loss: 0.6312 -
val_accuracy: 0.7364 - val_loss: 0.6561
Epoch 19/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.7496 - loss: 0.6197 -
val_accuracy: 0.7350 - val_loss: 0.6502
Epoch 20/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7502 - loss: 0.6154 -
val_accuracy: 0.7389 - val_loss: 0.6410
Epoch 21/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7519 - loss: 0.6093 -
val_accuracy: 0.7408 - val_loss: 0.6331
Epoch 22/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - accuracy: 0.7528 - loss: 0.6010 -
val_accuracy: 0.7415 - val_loss: 0.6320
Epoch 23/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7538 - loss: 0.5953 -
val_accuracy: 0.7418 - val_loss: 0.6329
Epoch 24/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - accuracy: 0.7481 - loss: 0.6008 -
val_accuracy: 0.7440 - val_loss: 0.6209
Epoch 25/25
750/750 ━━━━━━━━━━━━━━━━━━━━ 3s 3ms/step - accuracy: 0.7548 - loss: 0.5843 -
val_accuracy: 0.7551 - val_loss: 0.6144
FASHION_MNIST Test Accuracy: 74.48%
FASHION_MNIST Number of Parameters: 5600
Profiling on GPU...

Warm-up...: 100%|██████████| 10/10 [00:00<00:00, 144.78it/s]


Profiling: 100%|██████████| 30/30 [00:00<00:00, 194.65it/s]

Average Latency on GPU: 5.10 ms


Predicted Class: 9

[]

313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step

[]
Processing cifar10...

/usr/local/lib/python3.11/dist-packages/keras/src/layers/convolutional/
base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to
a layer. When using Sequential models, prefer using an `Input(shape)` object as the
first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)

Epoch 1/25
625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 6ms/step - accuracy: 0.0980 - loss: 2.3030 -
val_accuracy: 0.0977 - val_loss: 2.3027
Epoch 2/25
625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.0996 - loss: 2.3027 -
val_accuracy: 0.0952 - val_loss: 2.3027
Epoch 3/25
625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.0997 - loss: 2.3027 -
val_accuracy: 0.0952 - val_loss: 2.3027
Epoch 4/25
625/625 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step - accuracy: 0.0969 - loss: 2.3027 -
val_accuracy: 0.0952 - val_loss: 2.3028
Epoch 5/25
625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 4ms/step - accuracy: 0.0950 - loss: 2.3027 -
val_accuracy: 0.0952 - val_loss: 2.3028
CIFAR10 Test Accuracy: 10.00%
CIFAR10 Number of Parameters: 7680
Profiling on GPU...

Warm-up...: 100%|██████████| 10/10 [00:00<00:00, 134.05it/s]


Profiling: 100%|██████████| 30/30 [00:00<00:00, 210.89it/s]

Average Latency on GPU: 4.71 ms


Predicted Class: 2

[]

313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step

[]

Phase-2 Enhanced Model

# Import necessary libraries


import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import fashion_mnist, cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
import time
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
from tqdm import tqdm

# Define the Enhanced Model Architecture


def create_enhanced_model(input_shape, num_classes):
model = models.Sequential([
layers.Input(shape=input_shape),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2,2)),
layers.Dropout(0.25),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2,2)),
layers.Dropout(0.25),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.5),
layers.Dense(num_classes, activation='softmax')
])

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model

# Function to load and preprocess dataset


def prepare_dataset(dataset_name):
if dataset_name == 'fashion_mnist':
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
num_classes = 10
input_shape = (28, 28, 1)
elif dataset_name == 'cifar10':
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
num_classes = 10
input_shape = (32, 32, 3)
else:
raise ValueError(f"Unsupported dataset: {dataset_name}")

x_train = x_train.astype('float32') / 255


x_test = x_test.astype('float32') / 255
y_train = to_categorical(y_train, num_classes)
y_test = to_categorical(y_test, num_classes)

return (x_train, y_train), (x_test, y_test), input_shape, num_classes

# Evaluate model on the test set


def evaluate_model(model, x_test, y_test, device):
with tf.device(device):
start_time = time.time()
loss, acc = model.evaluate(x_test, y_test, verbose=0)
eval_time = time.time() - start_time
return acc, eval_time

# Profile model inference time (latency)


def profile_workload(model, device, dev_name, image, iterations=30):
print(f"Profiling on {dev_name}...")
latencies = []
with tf.device(device):
for _ in tqdm(range(10), desc="Warm-up"):
_ = model(image, training=False)
for _ in tqdm(range(iterations), desc="Profiling"):
start = time.time()
_ = model(image, training=False)
latencies.append((time.time() - start) * 1000)

avg_latency = np.mean(latencies)
print(f"Average Latency on {dev_name}: {avg_latency:.2f} ms")
return avg_latency

# Plot Training Curves


def plot_training_curves(history, dataset):
sns.set_style('whitegrid')
plt.figure(figsize=(12,5))

# Loss
plt.subplot(1,2,1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title(f'{dataset.upper()} Loss Curves (Phase 2)')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()

# Accuracy
plt.subplot(1,2,2)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title(f'{dataset.upper()} Accuracy Curves (Phase 2)')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

plt.tight_layout()
plt.show()

# Plot Confusion Matrix


def plot_confusion_matrix(y_true_onehot, y_pred_logits, dataset):
y_pred = np.argmax(y_pred_logits, axis=1) # Convert model output to
predicted class
y_true = np.argmax(y_true_onehot, axis=1) # Convert one-hot ground truth
to class

cm = confusion_matrix(y_true, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm)

disp.plot(cmap='Blues', colorbar=True, xticks_rotation='horizontal',


values_format='.0f')
plt.grid(False) # Remove grid lines
plt.title(f'{dataset.upper()} Confusion Matrix (Phase 2)')
plt.show()

# Select device (GPU preferred, fallback to MPS or CPU)


if tf.config.list_physical_devices('GPU'):
device = '/GPU:0'
dev_name = 'GPU'
elif tf.config.list_physical_devices('MPS'):
device = '/MPS:0'
dev_name = 'Apple MPS'
else:
device = '/CPU:0'
dev_name = 'CPU'
print(f"Using {dev_name}")

# Main Execution Loop


datasets = ['fashion_mnist', 'cifar10']

for dataset in datasets:


print(f"\nProcessing {dataset}...")

(x_train, y_train), (x_test, y_test), input_shape, num_classes =


prepare_dataset(dataset)

with tf.device(device):
model = create_enhanced_model(input_shape, num_classes)

early_stop = EarlyStopping(monitor='val_loss', patience=5,


restore_best_weights=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5,
patience=3, verbose=1)

start_train = time.time()
history = model.fit(x_train, y_train, epochs=50, batch_size=64,
validation_split=0.2,
callbacks=[early_stop, reduce_lr], verbose=1)
train_time = time.time() - start_train

# Plot training curves


plot_training_curves(history, dataset)

# Evaluate model
test_acc, eval_time = evaluate_model(model, x_test, y_test, device)
num_params = model.count_params()

# Profile Inference Latency


test_image = tf.convert_to_tensor(x_test[:1], dtype=tf.float32)
latency = profile_workload(model, device, dev_name, test_image)

# Display Summary
print("\nSummary:")
print(f"Test Accuracy: {test_acc*100:.2f}%")
print(f"Number of Parameters: {num_params}")
print(f"Training Time (s): {train_time:.2f}")
print(f"Evaluation Time (s): {eval_time:.4f}")
print(f"Inference Latency (ms): {latency:.2f}")

# Plot Confusion Matrix


preds = model.predict(x_test)
plot_confusion_matrix(y_test, preds, dataset)

Using GPU

Processing fashion_mnist...
Epoch 1/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 18s 8ms/step - accuracy: 0.7663 - loss: 0.6970 -
val_accuracy: 0.8913 - val_loss: 0.3070 - learning_rate: 0.0010
Epoch 2/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 6s 7ms/step - accuracy: 0.8826 - loss: 0.3333 -
val_accuracy: 0.8991 - val_loss: 0.2752 - learning_rate: 0.0010
Epoch 3/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - accuracy: 0.8990 - loss: 0.2830 -
val_accuracy: 0.8879 - val_loss: 0.3033 - learning_rate: 0.0010
Epoch 4/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - accuracy: 0.9080 - loss: 0.2568 -
val_accuracy: 0.9229 - val_loss: 0.2173 - learning_rate: 0.0010
Epoch 5/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 6s 7ms/step - accuracy: 0.9150 - loss: 0.2366 -
val_accuracy: 0.9102 - val_loss: 0.2428 - learning_rate: 0.0010
Epoch 6/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9241 - loss: 0.2139 -
val_accuracy: 0.9224 - val_loss: 0.2136 - learning_rate: 0.0010
Epoch 7/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9254 - loss: 0.2075 -
val_accuracy: 0.9276 - val_loss: 0.2028 - learning_rate: 0.0010
Epoch 8/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9278 - loss: 0.1977 -
val_accuracy: 0.9293 - val_loss: 0.1921 - learning_rate: 0.0010
Epoch 9/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - accuracy: 0.9356 - loss: 0.1837 -
val_accuracy: 0.9277 - val_loss: 0.2006 - learning_rate: 0.0010
Epoch 10/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 6s 8ms/step - accuracy: 0.9351 - loss: 0.1784 -
val_accuracy: 0.9338 - val_loss: 0.1873 - learning_rate: 0.0010
Epoch 11/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - accuracy: 0.9403 - loss: 0.1619 -
val_accuracy: 0.9284 - val_loss: 0.1991 - learning_rate: 0.0010
Epoch 12/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 11s 8ms/step - accuracy: 0.9416 - loss: 0.1608 -
val_accuracy: 0.9295 - val_loss: 0.2028 - learning_rate: 0.0010
Epoch 13/50
743/750 ━━━━━━━━━━━━━━━━━━━━ 0s 6ms/step - accuracy: 0.9443 - loss: 0.1513
Epoch 13: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.
750/750 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - accuracy: 0.9443 - loss: 0.1513 -
val_accuracy: 0.9309 - val_loss: 0.1889 - learning_rate: 0.0010
Epoch 14/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9512 - loss: 0.1384 -
val_accuracy: 0.9392 - val_loss: 0.1815 - learning_rate: 5.0000e-04
Epoch 15/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9576 - loss: 0.1174 -
val_accuracy: 0.9388 - val_loss: 0.1844 - learning_rate: 5.0000e-04
Epoch 16/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9573 - loss: 0.1167 -
val_accuracy: 0.9398 - val_loss: 0.1748 - learning_rate: 5.0000e-04
Epoch 17/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - accuracy: 0.9607 - loss: 0.1094 -
val_accuracy: 0.9406 - val_loss: 0.1788 - learning_rate: 5.0000e-04
Epoch 18/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9620 - loss: 0.1052 -
val_accuracy: 0.9406 - val_loss: 0.1804 - learning_rate: 5.0000e-04
Epoch 19/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 0s 6ms/step - accuracy: 0.9649 - loss: 0.0971
Epoch 19: ReduceLROnPlateau reducing learning rate to 0.0002500000118743628.
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9649 - loss: 0.0971 -
val_accuracy: 0.9406 - val_loss: 0.1819 - learning_rate: 5.0000e-04
Epoch 20/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9667 - loss: 0.0897 -
val_accuracy: 0.9408 - val_loss: 0.1834 - learning_rate: 2.5000e-04
Epoch 21/50
750/750 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.9696 - loss: 0.0834 -
val_accuracy: 0.9410 - val_loss: 0.1859 - learning_rate: 2.5000e-04

[]

Profiling on GPU...

Warm-up: 100%|██████████| 10/10 [00:00<00:00, 57.81it/s]


Profiling: 100%|██████████| 30/30 [00:00<00:00, 56.47it/s]

Average Latency on GPU: 17.58 ms

Summary:
Test Accuracy: 93.30%
Number of Parameters: 469098
Training Time (s): 157.49
Evaluation Time (s): 1.1331
Inference Latency (ms): 17.58
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step

[]

Processing cifar10...
Epoch 1/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 14s 10ms/step - accuracy: 0.3902 - loss: 1.8721 -
val_accuracy: 0.5798 - val_loss: 1.1792 - learning_rate: 0.0010
Epoch 2/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 15s 8ms/step - accuracy: 0.6122 - loss: 1.1075 -
val_accuracy: 0.6852 - val_loss: 0.8951 - learning_rate: 0.0010
Epoch 3/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6794 - loss: 0.9217 -
val_accuracy: 0.6859 - val_loss: 0.8830 - learning_rate: 0.0010
Epoch 4/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.7081 - loss: 0.8315 -
val_accuracy: 0.7120 - val_loss: 0.8233 - learning_rate: 0.0010
Epoch 5/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7291 - loss: 0.7760 -
val_accuracy: 0.7384 - val_loss: 0.7469 - learning_rate: 0.0010
Epoch 6/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7554 - loss: 0.7018 -
val_accuracy: 0.7227 - val_loss: 0.8069 - learning_rate: 0.0010
Epoch 7/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7694 - loss: 0.6594 -
val_accuracy: 0.7664 - val_loss: 0.6669 - learning_rate: 0.0010
Epoch 8/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7835 - loss: 0.6223 -
val_accuracy: 0.7508 - val_loss: 0.7126 - learning_rate: 0.0010
Epoch 9/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.7969 - loss: 0.5898 -
val_accuracy: 0.7854 - val_loss: 0.6301 - learning_rate: 0.0010
Epoch 10/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8098 - loss: 0.5453 -
val_accuracy: 0.7903 - val_loss: 0.6180 - learning_rate: 0.0010
Epoch 11/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8192 - loss: 0.5194 -
val_accuracy: 0.7843 - val_loss: 0.6289 - learning_rate: 0.0010
Epoch 12/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.8278 - loss: 0.4920 -
val_accuracy: 0.7220 - val_loss: 0.8376 - learning_rate: 0.0010
Epoch 13/50
621/625 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step - accuracy: 0.8322 - loss: 0.4761
Epoch 13: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8321 - loss: 0.4762 -
val_accuracy: 0.7785 - val_loss: 0.6464 - learning_rate: 0.0010
Epoch 14/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.8507 - loss: 0.4199 -
val_accuracy: 0.8118 - val_loss: 0.5489 - learning_rate: 5.0000e-04
Epoch 15/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8678 - loss: 0.3774 -
val_accuracy: 0.8094 - val_loss: 0.5727 - learning_rate: 5.0000e-04
Epoch 16/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8720 - loss: 0.3729 -
val_accuracy: 0.8013 - val_loss: 0.6117 - learning_rate: 5.0000e-04
Epoch 17/50
618/625 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step - accuracy: 0.8696 - loss: 0.3616
Epoch 17: ReduceLROnPlateau reducing learning rate to 0.0002500000118743628.
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.8696 - loss: 0.3617 -
val_accuracy: 0.8058 - val_loss: 0.5872 - learning_rate: 5.0000e-04
Epoch 18/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8836 - loss: 0.3266 -
val_accuracy: 0.8167 - val_loss: 0.5460 - learning_rate: 2.5000e-04
Epoch 19/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.8888 - loss: 0.3134 -
val_accuracy: 0.8215 - val_loss: 0.5323 - learning_rate: 2.5000e-04
Epoch 20/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8927 - loss: 0.3032 -
val_accuracy: 0.8161 - val_loss: 0.5628 - learning_rate: 2.5000e-04
Epoch 21/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.8948 - loss: 0.2987 -
val_accuracy: 0.8209 - val_loss: 0.5410 - learning_rate: 2.5000e-04
Epoch 22/50
621/625 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step - accuracy: 0.8959 - loss: 0.2926
Epoch 22: ReduceLROnPlateau reducing learning rate to 0.0001250000059371814.
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 7ms/step - accuracy: 0.8959 - loss: 0.2926 -
val_accuracy: 0.8235 - val_loss: 0.5381 - learning_rate: 2.5000e-04
Epoch 23/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.9047 - loss: 0.2714 -
val_accuracy: 0.8240 - val_loss: 0.5401 - learning_rate: 1.2500e-04
Epoch 24/50
625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.9049 - loss: 0.2708 -
val_accuracy: 0.8257 - val_loss: 0.5364 - learning_rate: 1.2500e-04

[]

Profiling on GPU...

Warm-up: 100%|██████████| 10/10 [00:00<00:00, 58.61it/s]


Profiling: 100%|██████████| 30/30 [00:00<00:00, 48.89it/s]

Average Latency on GPU: 20.15 ms

Summary:
Test Accuracy: 82.06%
Number of Parameters: 592554
Training Time (s): 138.92
Evaluation Time (s): 1.4751
Inference Latency (ms): 20.15
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step

[]

Phase-3 code starter template

The below code is for your reference; please feel free to change it partially or
fully.

Please make sure it does not have any bugs or mistakes. Code authors DO NOT claim
the code is bug-free. It is the student's responsibility to ensure its correctness.

import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import fashion_mnist, cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.callbacks import EarlyStopping
import time
import numpy as np
import os
from tqdm import tqdm

assert tf.__version__=='2.15.0', 'WARNING!!! different TensorFlow version may


produce an error while quantizing.'

---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-4-677d461a0085> in <cell line: 0>()
----> 1 assert tf.__version__=='2.15.0', 'WARNING!!! different TensorFlow
version may produce an error while quantizing.'

AssertionError: WARNING!!! different TensorFlow version may produce an error


while quantizing.

Install TensorFlow 2.15.0

! pip uninstall tensorflow -y # Uninstall Current TensorFlow


! pip install tensorflow==2.15.0 # Install TensorFlow 2.15.0

Found existing installation: tensorflow 2.18.0


Uninstalling tensorflow-2.18.0:
Successfully uninstalled tensorflow-2.18.0
Collecting tensorflow==2.15.0
Downloading tensorflow-2.15.0-cp311-cp311-
manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.4 kB)
Requirement already satisfied: absl-py>=1.0.0 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (1.4.0)
Requirement already satisfied: astunparse>=1.6.0 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (1.6.3)
Requirement already satisfied: flatbuffers>=23.5.26 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (25.2.10)
Requirement already satisfied: gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (0.6.0)
Requirement already satisfied: google-pasta>=0.1.1 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (0.2.0)
Requirement already satisfied: h5py>=2.9.0 in /usr/local/lib/python3.11/dist-
packages (from tensorflow==2.15.0) (3.13.0)
Requirement already satisfied: libclang>=13.0.0 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (18.1.1)
Collecting ml-dtypes~=0.2.0 (from tensorflow==2.15.0)
Downloading ml_dtypes-0.2.0-cp311-cp311-
manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (20 kB)
Collecting numpy<2.0.0,>=1.23.5 (from tensorflow==2.15.0)
Downloading numpy-1.26.4-cp311-cp311-
manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.0/61.0 kB 5.0 MB/s eta 0:00:00
ent already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.11/dist-
packages (from tensorflow==2.15.0) (3.4.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-
packages (from tensorflow==2.15.0) (24.2)
Collecting protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!
=4.21.5,<5.0.0dev,>=3.20.3 (from tensorflow==2.15.0)
Downloading protobuf-4.25.7-cp37-abi3-manylinux2014_x86_64.whl.metadata (541
bytes)
Requirement already satisfied: setuptools in /usr/local/lib/python3.11/dist-
packages (from tensorflow==2.15.0) (75.2.0)
Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.11/dist-
packages (from tensorflow==2.15.0) (1.17.0)
Requirement already satisfied: termcolor>=1.1.0 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (3.0.1)
Requirement already satisfied: typing-extensions>=3.6.6 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (4.13.2)
Collecting wrapt<1.15,>=1.11.0 (from tensorflow==2.15.0)
Downloading wrapt-1.14.1-cp311-cp311-
manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.w
hl.metadata (6.7 kB)
Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (0.37.1)
Requirement already satisfied: grpcio<2.0,>=1.24.3 in
/usr/local/lib/python3.11/dist-packages (from tensorflow==2.15.0) (1.71.0)
Collecting tensorboard<2.16,>=2.15 (from tensorflow==2.15.0)
Downloading tensorboard-2.15.2-py3-none-any.whl.metadata (1.7 kB)
Collecting tensorflow-estimator<2.16,>=2.15.0 (from tensorflow==2.15.0)
Downloading tensorflow_estimator-2.15.0-py2.py3-none-any.whl.metadata (1.3
kB)
Collecting keras<2.16,>=2.15.0 (from tensorflow==2.15.0)
Downloading keras-2.15.0-py3-none-any.whl.metadata (2.4 kB)
Requirement already satisfied: wheel<1.0,>=0.23.0 in
/usr/local/lib/python3.11/dist-packages (from astunparse>=1.6.0-
>tensorflow==2.15.0) (0.45.1)
Requirement already satisfied: google-auth<3,>=1.6.3 in
/usr/local/lib/python3.11/dist-packages (from tensorboard<2.16,>=2.15-
>tensorflow==2.15.0) (2.38.0)
Requirement already satisfied: google-auth-oauthlib<2,>=0.5 in
/usr/local/lib/python3.11/dist-packages (from tensorboard<2.16,>=2.15-
>tensorflow==2.15.0) (1.2.2)
Requirement already satisfied: markdown>=2.6.8 in
/usr/local/lib/python3.11/dist-packages (from tensorboard<2.16,>=2.15-
>tensorflow==2.15.0) (3.8)
Requirement already satisfied: requests<3,>=2.21.0 in
/usr/local/lib/python3.11/dist-packages (from tensorboard<2.16,>=2.15-
>tensorflow==2.15.0) (2.32.3)
Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in
/usr/local/lib/python3.11/dist-packages (from tensorboard<2.16,>=2.15-
>tensorflow==2.15.0) (0.7.2)
Requirement already satisfied: werkzeug>=1.0.1 in
/usr/local/lib/python3.11/dist-packages (from tensorboard<2.16,>=2.15-
>tensorflow==2.15.0) (3.1.3)
Requirement already satisfied: cachetools<6.0,>=2.0.0 in
/usr/local/lib/python3.11/dist-packages (from google-auth<3,>=1.6.3-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (5.5.2)
Requirement already satisfied: pyasn1-modules>=0.2.1 in
/usr/local/lib/python3.11/dist-packages (from google-auth<3,>=1.6.3-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (0.4.2)
Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.11/dist-
packages (from google-auth<3,>=1.6.3->tensorboard<2.16,>=2.15->tensorflow==2.15.0)
(4.9.1)
Requirement already satisfied: requests-oauthlib>=0.7.0 in
/usr/local/lib/python3.11/dist-packages (from google-auth-oauthlib<2,>=0.5-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (2.0.0)
Requirement already satisfied: charset-normalizer<4,>=2 in
/usr/local/lib/python3.11/dist-packages (from requests<3,>=2.21.0-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (3.4.1)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-
packages (from requests<3,>=2.21.0->tensorboard<2.16,>=2.15->tensorflow==2.15.0)
(3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in
/usr/local/lib/python3.11/dist-packages (from requests<3,>=2.21.0-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (2.3.0)
Requirement already satisfied: certifi>=2017.4.17 in
/usr/local/lib/python3.11/dist-packages (from requests<3,>=2.21.0-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (2025.1.31)
Requirement already satisfied: MarkupSafe>=2.1.1 in
/usr/local/lib/python3.11/dist-packages (from werkzeug>=1.0.1-
>tensorboard<2.16,>=2.15->tensorflow==2.15.0) (3.0.2)
Requirement already satisfied: pyasn1<0.7.0,>=0.6.1 in
/usr/local/lib/python3.11/dist-packages (from pyasn1-modules>=0.2.1->google-
auth<3,>=1.6.3->tensorboard<2.16,>=2.15->tensorflow==2.15.0) (0.6.1)
Requirement already satisfied: oauthlib>=3.0.0 in
/usr/local/lib/python3.11/dist-packages (from requests-oauthlib>=0.7.0->google-
auth-oauthlib<2,>=0.5->tensorboard<2.16,>=2.15->tensorflow==2.15.0) (3.2.2)
Downloading tensorflow-2.15.0-cp311-cp311-
manylinux_2_17_x86_64.manylinux2014_x86_64.whl (475.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 475.3/475.3 MB 1.3 MB/s eta 0:00:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 84.0 MB/s eta 0:00:00
l_dtypes-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.0
MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.0/1.0 MB 34.8 MB/s eta 0:00:00
py-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (18.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 18.3/18.3 MB 104.0 MB/s eta 0:00:00
anylinux2014_x86_64.whl (294 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 294.6/294.6 kB 29.0 MB/s eta 0:00:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.5/5.5 MB 111.5 MB/s eta 0:00:00
ator-2.15.0-py2.py3-none-any.whl (441 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 442.0/442.0 kB 38.3 MB/s eta 0:00:00

anylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.wh
l (78 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.4/78.4 kB 7.9 MB/s eta 0:00:00
ator, protobuf, numpy, keras, ml-dtypes, tensorboard, tensorflow
Attempting uninstall: wrapt
Found existing installation: wrapt 1.17.2
Uninstalling wrapt-1.17.2:
Successfully uninstalled wrapt-1.17.2
Attempting uninstall: protobuf
Found existing installation: protobuf 5.29.4
Uninstalling protobuf-5.29.4:
Successfully uninstalled protobuf-5.29.4
Attempting uninstall: numpy
Found existing installation: numpy 2.0.2
Uninstalling numpy-2.0.2:
Successfully uninstalled numpy-2.0.2
Attempting uninstall: keras
Found existing installation: keras 3.8.0
Uninstalling keras-3.8.0:
Successfully uninstalled keras-3.8.0
Attempting uninstall: ml-dtypes
Found existing installation: ml-dtypes 0.4.1
Uninstalling ml-dtypes-0.4.1:
Successfully uninstalled ml-dtypes-0.4.1
Attempting uninstall: tensorboard
Found existing installation: tensorboard 2.18.0
Uninstalling tensorboard-2.18.0:
Successfully uninstalled tensorboard-2.18.0
ERROR: pip's dependency resolver does not currently take into account all the
packages that are installed. This behaviour is the source of the following
dependency conflicts.
tensorstore 0.1.73 requires ml_dtypes>=0.3.1, but you have ml-dtypes 0.2.0
which is incompatible.
grpcio-status 1.71.0 requires protobuf<6.0dev,>=5.26.1, but you have protobuf
4.25.7 which is incompatible.
thinc 8.3.6 requires numpy<3.0.0,>=2.0.0, but you have numpy 1.26.4 which is
incompatible.
ydf 0.11.0 requires protobuf<6.0.0,>=5.29.1, but you have protobuf 4.25.7 which
is incompatible.
tensorflow-text 2.18.1 requires tensorflow<2.19,>=2.18.0, but you have
tensorflow 2.15.0 which is incompatible.
tensorflow-decision-forests 1.11.0 requires tensorflow==2.18.0, but you have
tensorflow 2.15.0 which is incompatible.
tf-keras 2.18.0 requires tensorflow<2.19,>=2.18, but you have tensorflow 2.15.0
which is incompatible.
jax 0.5.2 requires ml_dtypes>=0.4.0, but you have ml-dtypes 0.2.0 which is
incompatible.
Successfully installed keras-2.15.0 ml-dtypes-0.2.0 numpy-1.26.4 protobuf-
4.25.7 tensorboard-2.15.2 tensorflow-2.15.0 tensorflow-estimator-2.15.0 wrapt-
1.14.1

{"id":"5640b6359d3d448895ddf93e3d8e59e3","pip_warning":{"packages":
["keras","ml_dtypes","tensorflow","wrapt"]}}

# Verify Installation
import tensorflow as tf
print(tf.__version__)

2.15.0

Install model optimization tools

! pip install -q tensorflow-model-optimization # Install model optimization


tools

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/242.5 kB ? eta -:--:--


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 242.5/242.5 kB 17.8 MB/s eta 0:00:00
# Changes: Replaced simple CNN with deeper model + BatchNorm + Dropout, added
model pruning and quantization steps,
# added learning rate scheduling, training curves, confusion matrix, model size
visualization, and sparsity reporting.

from tensorflow.keras.callbacks import ReduceLROnPlateau


import tensorflow_model_optimization as tfmot
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

# Set Seaborn style


sns.set_style('whitegrid')

# TensorFlow version check


if not tf.__version__.startswith('2.15'):
print(f"WARNING: Your TensorFlow version is {tf.__version__}")

# Create the enhanced model


def create_enhanced_model(input_shape, num_classes):
model = models.Sequential([
layers.Input(shape=input_shape),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2,2)),
layers.Dropout(0.25),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2,2)),
layers.Dropout(0.25),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.5),
layers.Dense(num_classes, activation='softmax')
])
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy', metrics=['accuracy'])
return model

# Prepare dataset
def prepare_dataset(name):
if name == 'fashion_mnist':
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train = x_train[..., np.newaxis]
x_test = x_test[..., np.newaxis]
input_shape = (28,28,1)
elif name == 'cifar10':
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
input_shape = (32,32,3)
else:
raise ValueError(f"Unsupported dataset: {name}")

x_train, x_test = x_train/255.0, x_test/255.0


y_train, y_test = to_categorical(y_train, 10), to_categorical(y_test, 10)
return (x_train, y_train), (x_test, y_test), input_shape

# Apply pruning
def apply_pruning(model):
pruning_schedule = tfmot.sparsity.keras.PolynomialDecay(
initial_sparsity=0.0, final_sparsity=0.5, begin_step=0, end_step=1000
)
pruned_model = tfmot.sparsity.keras.prune_low_magnitude(model,
pruning_schedule=pruning_schedule)

pruned_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy', metrics=['accuracy'])
return pruned_model

# Save model
def save_model(model, name):
model.save(name)
size_kb = os.path.getsize(name) / 1024
return size_kb

# Quantize model
def quantize_model(model, rep_data, name='model_int8.tflite'):
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = rep_data
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
quant_model = converter.convert()
with open(name, 'wb') as f:
f.write(quant_model)
size_kb = os.path.getsize(name) / 1024
return size_kb

# Representative data for quantization


def rep_data_gen(x_train):
for i in range(100):
yield [tf.cast(x_train[i:i+1] * 255.0, tf.float32)]

# Evaluate model
def evaluate_model(model, x_test, y_test):
loss, acc = model.evaluate(x_test, y_test, verbose=0)
return acc

# Plot training curves


def plot_training_curves(history, dataset):
fig, axs = plt.subplots(1, 2, figsize=(14,5))
sns.lineplot(x=range(len(history.history['loss'])),
y=history.history['loss'], label='Train Loss', ax=axs[0])
sns.lineplot(x=range(len(history.history['val_loss'])),
y=history.history['val_loss'], label='Val Loss', ax=axs[0])
axs[0].set_title(f'{dataset.upper()} Loss Curves')
axs[0].set_xlabel('Epoch')
axs[0].legend()

sns.lineplot(x=range(len(history.history['accuracy'])),
y=history.history['accuracy'], label='Train Acc', ax=axs[1])
sns.lineplot(x=range(len(history.history['val_accuracy'])),
y=history.history['val_accuracy'], label='Val Acc', ax=axs[1])
axs[1].set_title(f'{dataset.upper()} Accuracy Curves')
axs[1].set_xlabel('Epoch')
axs[1].legend()

plt.show()

# Plot model size bar chart


def plot_model_sizes(fp32_size, pruned_size, quant_size, dataset):
sns.barplot(x=['FP32','Pruned','Quantized'], y=[fp32_size, pruned_size,
quant_size])
plt.title(f'{dataset.upper()} Model Size Comparison (KB)')
plt.ylabel('Size (KB)')
plt.show()

# Calculate sparsity
def calculate_sparsity(model):
total = 0
zeros = 0
for w in model.get_weights():
total += np.prod(w.shape)
zeros += np.sum(w==0)
sparsity = zeros/total
return sparsity

# Confusion Matrix
def plot_confusion_matrix(y_true, y_pred, dataset):
cm = confusion_matrix(np.argmax(y_true, axis=1), np.argmax(y_pred, axis=1))
plt.figure(figsize=(8,6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title(f'{dataset.upper()} Confusion Matrix')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

# --- MAIN EXECUTION ---

datasets = ['fashion_mnist', 'cifar10']

for dataset in datasets:


print(f"\nProcessing {dataset}...")
(x_train, y_train), (x_test, y_test), input_shape =
prepare_dataset(dataset)

# Create base model


model = create_enhanced_model(input_shape, 10)

# Train base model


early_stop = EarlyStopping(monitor='val_loss', patience=5,
restore_best_weights=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3)
history = model.fit(x_train, y_train, epochs=50, batch_size=64,
validation_split=0.2,
callbacks=[early_stop, reduce_lr], verbose=1)

# Save original model


fp32_size = save_model(model, f'{dataset}_model_fp32.h5')
acc_fp32 = evaluate_model(model, x_test, y_test)
plot_training_curves(history, dataset)
# Apply pruning
pruned_model = apply_pruning(model)
pruning_callbacks = [
tfmot.sparsity.keras.UpdatePruningStep(),
EarlyStopping(monitor='val_loss', patience=5,
restore_best_weights=True)
]
pruned_model.fit(x_train, y_train, epochs=10, batch_size=64,
validation_split=0.2,
callbacks=pruning_callbacks, verbose=0)

# Save pruned model


stripped_model = tfmot.sparsity.keras.strip_pruning(pruned_model)

stripped_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
pruned_size = save_model(stripped_model, f'{dataset}_model_pruned.h5')
acc_pruned = evaluate_model(stripped_model, x_test, y_test)

# Quantize pruned model


quant_size = quantize_model(stripped_model, lambda: rep_data_gen(x_train),
name=f'{dataset}_model_pruned_quant.tflite')

# Evaluate quantized model


interpreter =
tf.lite.Interpreter(model_path=f'{dataset}_model_pruned_quant.tflite')
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

correct = 0
for i in tqdm(range(len(x_test)), desc="Evaluating Quantized Model"):
input_data = np.round(x_test[i:i+1]*255).astype(np.int8)
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
output = interpreter.get_tensor(output_details[0]['index'])
pred = np.argmax(output)
true = np.argmax(y_test[i])
if pred == true:
correct += 1

acc_quant = correct / len(x_test)

# Print Results
print(f"{dataset.upper()} Results:")
print(f"FP32 Acc: {acc_fp32*100:.2f}% | Pruned Acc: {acc_pruned*100:.2f}% |
Quantized Acc: {acc_quant*100:.2f}%")
print(f"FP32 Size: {fp32_size:.2f} KB | Pruned Size: {pruned_size:.2f} KB |
Quantized Size: {quant_size:.2f} KB")
plot_model_sizes(fp32_size, pruned_size, quant_size, dataset)

# Sparsity
sparsity = calculate_sparsity(stripped_model)
print(f"Sparsity after pruning: {sparsity*100:.2f}%")

# Confusion matrix
preds = stripped_model.predict(x_test)
plot_confusion_matrix(y_test, preds, dataset)
Processing fashion_mnist...
Epoch 1/50
750/750 [==============================] - 163s 214ms/step - loss: 0.4873 -
accuracy: 0.8322 - val_loss: 0.3307 - val_accuracy: 0.8799 - lr: 0.0010
Epoch 2/50
750/750 [==============================] - 158s 211ms/step - loss: 0.3198 -
accuracy: 0.8878 - val_loss: 0.2471 - val_accuracy: 0.9103 - lr: 0.0010
Epoch 3/50
750/750 [==============================] - 152s 203ms/step - loss: 0.2748 -
accuracy: 0.9018 - val_loss: 0.2745 - val_accuracy: 0.9001 - lr: 0.0010
Epoch 4/50
750/750 [==============================] - 151s 201ms/step - loss: 0.2489 -
accuracy: 0.9111 - val_loss: 0.2142 - val_accuracy: 0.9222 - lr: 0.0010
Epoch 5/50
750/750 [==============================] - 152s 202ms/step - loss: 0.2339 -
accuracy: 0.9166 - val_loss: 0.2092 - val_accuracy: 0.9230 - lr: 0.0010
Epoch 6/50
750/750 [==============================] - 167s 222ms/step - loss: 0.2190 -
accuracy: 0.9216 - val_loss: 0.2264 - val_accuracy: 0.9171 - lr: 0.0010
Epoch 7/50
750/750 [==============================] - 158s 211ms/step - loss: 0.2055 -
accuracy: 0.9261 - val_loss: 0.2065 - val_accuracy: 0.9267 - lr: 0.0010
Epoch 8/50
750/750 [==============================] - 157s 210ms/step - loss: 0.1930 -
accuracy: 0.9303 - val_loss: 0.2127 - val_accuracy: 0.9211 - lr: 0.0010
Epoch 9/50
750/750 [==============================] - 158s 211ms/step - loss: 0.1856 -
accuracy: 0.9321 - val_loss: 0.2035 - val_accuracy: 0.9270 - lr: 0.0010
Epoch 10/50
750/750 [==============================] - 159s 212ms/step - loss: 0.1765 -
accuracy: 0.9375 - val_loss: 0.2308 - val_accuracy: 0.9172 - lr: 0.0010
Epoch 11/50
750/750 [==============================] - 156s 208ms/step - loss: 0.1710 -
accuracy: 0.9374 - val_loss: 0.1930 - val_accuracy: 0.9299 - lr: 0.0010
Epoch 12/50
750/750 [==============================] - 159s 212ms/step - loss: 0.1620 -
accuracy: 0.9408 - val_loss: 0.1867 - val_accuracy: 0.9331 - lr: 0.0010
Epoch 13/50
750/750 [==============================] - 158s 211ms/step - loss: 0.1524 -
accuracy: 0.9445 - val_loss: 0.1795 - val_accuracy: 0.9384 - lr: 0.0010
Epoch 14/50
750/750 [==============================] - 158s 210ms/step - loss: 0.1459 -
accuracy: 0.9467 - val_loss: 0.1852 - val_accuracy: 0.9352 - lr: 0.0010
Epoch 15/50
750/750 [==============================] - 161s 214ms/step - loss: 0.1440 -
accuracy: 0.9486 - val_loss: 0.1809 - val_accuracy: 0.9386 - lr: 0.0010
Epoch 16/50
750/750 [==============================] - 157s 209ms/step - loss: 0.1377 -
accuracy: 0.9500 - val_loss: 0.1891 - val_accuracy: 0.9341 - lr: 0.0010
Epoch 17/50
750/750 [==============================] - 160s 213ms/step - loss: 0.1152 -
accuracy: 0.9574 - val_loss: 0.1743 - val_accuracy: 0.9399 - lr: 5.0000e-04
Epoch 18/50
750/750 [==============================] - 156s 208ms/step - loss: 0.1054 -
accuracy: 0.9627 - val_loss: 0.1729 - val_accuracy: 0.9415 - lr: 5.0000e-04
Epoch 19/50
750/750 [==============================] - 158s 210ms/step - loss: 0.1026 -
accuracy: 0.9629 - val_loss: 0.1708 - val_accuracy: 0.9429 - lr: 5.0000e-04
Epoch 20/50
750/750 [==============================] - 160s 213ms/step - loss: 0.0953 -
accuracy: 0.9654 - val_loss: 0.1771 - val_accuracy: 0.9407 - lr: 5.0000e-04
Epoch 21/50
750/750 [==============================] - 153s 204ms/step - loss: 0.0935 -
accuracy: 0.9657 - val_loss: 0.1767 - val_accuracy: 0.9423 - lr: 5.0000e-04
Epoch 22/50
750/750 [==============================] - 155s 206ms/step - loss: 0.0914 -
accuracy: 0.9664 - val_loss: 0.2037 - val_accuracy: 0.9358 - lr: 5.0000e-04
Epoch 23/50
750/750 [==============================] - 152s 203ms/step - loss: 0.0805 -
accuracy: 0.9710 - val_loss: 0.1765 - val_accuracy: 0.9437 - lr: 2.5000e-04
Epoch 24/50
750/750 [==============================] - 154s 205ms/step - loss: 0.0748 -
accuracy: 0.9729 - val_loss: 0.1827 - val_accuracy: 0.9439 - lr: 2.5000e-04

/usr/local/lib/python3.11/dist-packages/keras/src/engine/training.py:3103:
UserWarning: You are saving your model as an HDF5 file via `model.save()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')`.
saving_api.save_model(

[]

/usr/local/lib/python3.11/dist-packages/keras/src/engine/training.py:3103:
UserWarning: You are saving your model as an HDF5 file via `model.save()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')`.
saving_api.save_model(
/usr/local/lib/python3.11/dist-packages/tensorflow/lite/python/convert.py:953:
UserWarning: Statistics for quantized inputs were expected, but not specified;
continuing anyway.
warnings.warn(
Evaluating Quantized Model: 100%|██████████| 10000/10000 [00:09<00:00,
1069.29it/s]

FASHION_MNIST Results:
FP32 Acc: 94.01% | Pruned Acc: 93.57% | Quantized Acc: 19.21%
FP32 Size: 5593.32 KB | Pruned Size: 1893.95 KB | Quantized Size: 470.85 KB

[]

Sparsity after pruning: 49.83%


313/313 [==============================] - 7s 22ms/step

[]

Processing cifar10...
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170498071/170498071 [==============================] - 13s 0us/step
Epoch 1/50
625/625 [==============================] - 171s 270ms/step - loss: 1.5605 -
accuracy: 0.4681 - val_loss: 1.2150 - val_accuracy: 0.5588 - lr: 0.0010
Epoch 2/50
625/625 [==============================] - 168s 268ms/step - loss: 1.0821 -
accuracy: 0.6182 - val_loss: 1.0336 - val_accuracy: 0.6346 - lr: 0.0010
Epoch 3/50
625/625 [==============================] - 170s 272ms/step - loss: 0.9392 -
accuracy: 0.6694 - val_loss: 0.8469 - val_accuracy: 0.7039 - lr: 0.0010
Epoch 4/50
625/625 [==============================] - 172s 275ms/step - loss: 0.8459 -
accuracy: 0.7046 - val_loss: 1.0365 - val_accuracy: 0.6367 - lr: 0.0010
Epoch 5/50
625/625 [==============================] - 171s 273ms/step - loss: 0.7837 -
accuracy: 0.7262 - val_loss: 0.7433 - val_accuracy: 0.7404 - lr: 0.0010
Epoch 6/50
625/625 [==============================] - 166s 266ms/step - loss: 0.7405 -
accuracy: 0.7434 - val_loss: 0.7216 - val_accuracy: 0.7490 - lr: 0.0010
Epoch 7/50
625/625 [==============================] - 169s 271ms/step - loss: 0.6815 -
accuracy: 0.7612 - val_loss: 0.6790 - val_accuracy: 0.7592 - lr: 0.0010
Epoch 8/50
625/625 [==============================] - 166s 266ms/step - loss: 0.6448 -
accuracy: 0.7761 - val_loss: 0.6292 - val_accuracy: 0.7822 - lr: 0.0010
Epoch 9/50
625/625 [==============================] - 169s 271ms/step - loss: 0.6086 -
accuracy: 0.7896 - val_loss: 0.6860 - val_accuracy: 0.7622 - lr: 0.0010
Epoch 10/50
625/625 [==============================] - 168s 269ms/step - loss: 0.5793 -
accuracy: 0.7984 - val_loss: 0.6227 - val_accuracy: 0.7843 - lr: 0.0010
Epoch 11/50
625/625 [==============================] - 173s 277ms/step - loss: 0.5480 -
accuracy: 0.8066 - val_loss: 0.6504 - val_accuracy: 0.7769 - lr: 0.0010
Epoch 12/50
625/625 [==============================] - 170s 272ms/step - loss: 0.5220 -
accuracy: 0.8170 - val_loss: 0.6107 - val_accuracy: 0.7923 - lr: 0.0010
Epoch 13/50
625/625 [==============================] - 170s 272ms/step - loss: 0.4981 -
accuracy: 0.8260 - val_loss: 0.6414 - val_accuracy: 0.7856 - lr: 0.0010
Epoch 14/50
625/625 [==============================] - 167s 267ms/step - loss: 0.4744 -
accuracy: 0.8337 - val_loss: 0.5971 - val_accuracy: 0.8009 - lr: 0.0010
Epoch 15/50
625/625 [==============================] - 166s 266ms/step - loss: 0.4530 -
accuracy: 0.8403 - val_loss: 0.6300 - val_accuracy: 0.7919 - lr: 0.0010
Epoch 16/50
625/625 [==============================] - 166s 266ms/step - loss: 0.4347 -
accuracy: 0.8469 - val_loss: 0.6441 - val_accuracy: 0.7842 - lr: 0.0010
Epoch 17/50
625/625 [==============================] - 166s 265ms/step - loss: 0.4218 -
accuracy: 0.8522 - val_loss: 0.6185 - val_accuracy: 0.7963 - lr: 0.0010
Epoch 18/50
625/625 [==============================] - 167s 267ms/step - loss: 0.3652 -
accuracy: 0.8703 - val_loss: 0.6453 - val_accuracy: 0.7959 - lr: 5.0000e-04
Epoch 19/50
625/625 [==============================] - 167s 267ms/step - loss: 0.3400 -
accuracy: 0.8806 - val_loss: 0.6101 - val_accuracy: 0.8038 - lr: 5.0000e-04

/usr/local/lib/python3.11/dist-packages/keras/src/engine/training.py:3103:
UserWarning: You are saving your model as an HDF5 file via `model.save()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')`.
saving_api.save_model(

[]
/usr/local/lib/python3.11/dist-packages/keras/src/engine/training.py:3103:
UserWarning: You are saving your model as an HDF5 file via `model.save()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')`.
saving_api.save_model(
/usr/local/lib/python3.11/dist-packages/tensorflow/lite/python/convert.py:953:
UserWarning: Statistics for quantized inputs were expected, but not specified;
continuing anyway.
warnings.warn(
Evaluating Quantized Model: 100%|██████████| 10000/10000 [00:11<00:00,
908.71it/s]

CIFAR10 Results:
FP32 Acc: 79.70% | Pruned Acc: 80.72% | Quantized Acc: 16.78%
FP32 Size: 7039.21 KB | Pruned Size: 2377.39 KB | Quantized Size: 591.62 KB

[]

Sparsity after pruning: 49.86%


313/313 [==============================] - 9s 28ms/step

[]

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy