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 [Link] import layers, models
from [Link] import fashion_mnist, cifar10
from [Link] import to_categorical
from [Link] import EarlyStopping
import time
import numpy as np
from tqdm import tqdm
import [Link] as plt
import seaborn as sns
from [Link] import confusion_matrix, ConfusionMatrixDisplay
# Set Seaborn style
sns.set_style('whitegrid')
# Create Base Model
def create_base_model(input_shape, num_classes):
model = [Link]([
layers.Conv2D(16, (3, 3), activation='relu', input_shape=input_shape),
layers.MaxPooling2D((2, 2)),
[Link](),
[Link](2, activation='relu'),
[Link](num_classes, activation='softmax')
])
[Link](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 [Link](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 = [Link]()
history = [Link](x_train, y_train, epochs=max_epoch, batch_size=64,
validation_split=0.2,
callbacks=[early_stop], verbose=1)
train_time = [Link]() - start_time
# Evaluate model and time it
start_time = [Link]()
test_loss, test_accuracy = [Link](x_test, y_test, verbose=0)
eval_time = [Link]() - 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 [Link](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 = [Link]()
_ = model(image, training=False)
[Link](([Link]() - start) * 1000)
avg_latency = [Link](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 = [Link](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 = [Link](1, 2, figsize=(14,5))
# Loss plot
[Link](x=range(len([Link]['loss'])),
y=[Link]['loss'], label='Train Loss', ax=axs[0])
[Link](x=range(len([Link]['val_loss'])),
y=[Link]['val_loss'], label='Val Loss', ax=axs[0])
axs[0].set_title(f'{[Link]()} Loss Curves (Phase 1)')
axs[0].set_xlabel('Epoch')
axs[0].legend()
# Accuracy plot
[Link](x=range(len([Link]['accuracy'])),
y=[Link]['accuracy'], label='Train Accuracy', ax=axs[1])
[Link](x=range(len([Link]['val_accuracy'])),
y=[Link]['val_accuracy'], label='Val Accuracy', ax=axs[1])
axs[1].set_title(f'{[Link]()} Accuracy Curves (Phase 1)')
axs[1].set_xlabel('Epoch')
axs[1].legend()
[Link]()
# Plot Confusion Matrix
def plot_confusion_matrix(y_true, y_pred_logits, dataset):
y_pred = [Link](y_pred_logits, axis=1)
y_true = [Link](y_true, axis=1)
cm = confusion_matrix(y_true, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm)
[Link](cmap='Blues', colorbar=True, xticks_rotation='horizontal',
values_format='.0f')
[Link](False)
[Link](f'{[Link]()} Confusion Matrix (Phase 1)')
[Link]()
# --- MAIN CODE ---
# Device priority: CUDA > MPS > CPU
if [Link].list_physical_devices('GPU'):
device = '/GPU:0'
dev_name = 'GPU'
elif [Link].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 = [Link](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 [Link] import layers, models
from [Link] import fashion_mnist, cifar10
from [Link] import to_categorical
from [Link] import EarlyStopping, ReduceLROnPlateau
import time
import numpy as np
import [Link] as plt
import seaborn as sns
from [Link] import confusion_matrix, ConfusionMatrixDisplay
from tqdm import tqdm
# Define the Enhanced Model Architecture
def create_enhanced_model(input_shape, num_classes):
model = [Link]([
[Link](shape=input_shape),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
[Link](),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
[Link](),
layers.MaxPooling2D((2,2)),
[Link](0.25),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
[Link](),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
[Link](),
layers.MaxPooling2D((2,2)),
[Link](0.25),
[Link](),
[Link](128, activation='relu'),
[Link](),
[Link](0.5),
[Link](num_classes, activation='softmax')
])
[Link](optimizer=[Link](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 [Link](device):
start_time = [Link]()
loss, acc = [Link](x_test, y_test, verbose=0)
eval_time = [Link]() - 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 [Link](device):
for _ in tqdm(range(10), desc="Warm-up"):
_ = model(image, training=False)
for _ in tqdm(range(iterations), desc="Profiling"):
start = [Link]()
_ = model(image, training=False)
[Link](([Link]() - start) * 1000)
avg_latency = [Link](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')
[Link](figsize=(12,5))
# Loss
[Link](1,2,1)
[Link]([Link]['loss'], label='Train Loss')
[Link]([Link]['val_loss'], label='Validation Loss')
[Link](f'{[Link]()} Loss Curves (Phase 2)')
[Link]('Epoch')
[Link]('Loss')
[Link]()
# Accuracy
[Link](1,2,2)
[Link]([Link]['accuracy'], label='Train Accuracy')
[Link]([Link]['val_accuracy'], label='Validation Accuracy')
[Link](f'{[Link]()} Accuracy Curves (Phase 2)')
[Link]('Epoch')
[Link]('Accuracy')
[Link]()
plt.tight_layout()
[Link]()
# Plot Confusion Matrix
def plot_confusion_matrix(y_true_onehot, y_pred_logits, dataset):
y_pred = [Link](y_pred_logits, axis=1) # Convert model output to
predicted class
y_true = [Link](y_true_onehot, axis=1) # Convert one-hot ground truth
to class
cm = confusion_matrix(y_true, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm)
[Link](cmap='Blues', colorbar=True, xticks_rotation='horizontal',
values_format='.0f')
[Link](False) # Remove grid lines
[Link](f'{[Link]()} Confusion Matrix (Phase 2)')
[Link]()
# Select device (GPU preferred, fallback to MPS or CPU)
if [Link].list_physical_devices('GPU'):
device = '/GPU:0'
dev_name = 'GPU'
elif [Link].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 [Link](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 = [Link]()
history = [Link](x_train, y_train, epochs=50, batch_size=64,
validation_split=0.2,
callbacks=[early_stop, reduce_lr], verbose=1)
train_time = [Link]() - 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 = [Link](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 [Link] import layers, models
from [Link] import fashion_mnist, cifar10
from [Link] import to_categorical
from [Link] 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.[Link] (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.[Link] (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.[Link] (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.[Link] (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
[Link] (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 [Link] (1.7 kB)
Collecting tensorflow-estimator<2.16,>=2.15.0 (from tensorflow==2.15.0)
Downloading tensorflow_estimator-[Link] (1.3
kB)
Collecting keras<2.16,>=2.15.0 (from tensorflow==2.15.0)
Downloading [Link] (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
[Link] (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 [Link] import ReduceLROnPlateau
import tensorflow_model_optimization as tfmot
import [Link] as plt
import seaborn as sns
from [Link] 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 = [Link]([
[Link](shape=input_shape),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
[Link](),
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
[Link](),
layers.MaxPooling2D((2,2)),
[Link](0.25),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
[Link](),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
[Link](),
layers.MaxPooling2D((2,2)),
[Link](0.25),
[Link](),
[Link](128, activation='relu'),
[Link](),
[Link](0.5),
[Link](num_classes, activation='softmax')
])
[Link](optimizer=[Link](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[..., [Link]]
x_test = x_test[..., [Link]]
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 = [Link](
initial_sparsity=0.0, final_sparsity=0.5, begin_step=0, end_step=1000
)
pruned_model = [Link].prune_low_magnitude(model,
pruning_schedule=pruning_schedule)
pruned_model.compile(optimizer=[Link](learning_rate=0.001),
loss='categorical_crossentropy', metrics=['accuracy'])
return pruned_model
# Save model
def save_model(model, name):
[Link](name)
size_kb = [Link](name) / 1024
return size_kb
# Quantize model
def quantize_model(model, rep_data, name='model_int8.tflite'):
converter = [Link].from_keras_model(model)
[Link] = [[Link]]
converter.representative_dataset = rep_data
converter.target_spec.supported_ops = [[Link].TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
quant_model = [Link]()
with open(name, 'wb') as f:
[Link](quant_model)
size_kb = [Link](name) / 1024
return size_kb
# Representative data for quantization
def rep_data_gen(x_train):
for i in range(100):
yield [[Link](x_train[i:i+1] * 255.0, tf.float32)]
# Evaluate model
def evaluate_model(model, x_test, y_test):
loss, acc = [Link](x_test, y_test, verbose=0)
return acc
# Plot training curves
def plot_training_curves(history, dataset):
fig, axs = [Link](1, 2, figsize=(14,5))
[Link](x=range(len([Link]['loss'])),
y=[Link]['loss'], label='Train Loss', ax=axs[0])
[Link](x=range(len([Link]['val_loss'])),
y=[Link]['val_loss'], label='Val Loss', ax=axs[0])
axs[0].set_title(f'{[Link]()} Loss Curves')
axs[0].set_xlabel('Epoch')
axs[0].legend()
[Link](x=range(len([Link]['accuracy'])),
y=[Link]['accuracy'], label='Train Acc', ax=axs[1])
[Link](x=range(len([Link]['val_accuracy'])),
y=[Link]['val_accuracy'], label='Val Acc', ax=axs[1])
axs[1].set_title(f'{[Link]()} Accuracy Curves')
axs[1].set_xlabel('Epoch')
axs[1].legend()
[Link]()
# Plot model size bar chart
def plot_model_sizes(fp32_size, pruned_size, quant_size, dataset):
[Link](x=['FP32','Pruned','Quantized'], y=[fp32_size, pruned_size,
quant_size])
[Link](f'{[Link]()} Model Size Comparison (KB)')
[Link]('Size (KB)')
[Link]()
# Calculate sparsity
def calculate_sparsity(model):
total = 0
zeros = 0
for w in model.get_weights():
total += [Link]([Link])
zeros += [Link](w==0)
sparsity = zeros/total
return sparsity
# Confusion Matrix
def plot_confusion_matrix(y_true, y_pred, dataset):
cm = confusion_matrix([Link](y_true, axis=1), [Link](y_pred, axis=1))
[Link](figsize=(8,6))
[Link](cm, annot=True, fmt='d', cmap='Blues')
[Link](f'{[Link]()} Confusion Matrix')
[Link]('Predicted')
[Link]('True')
[Link]()
# --- 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 = [Link](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 = [
[Link](),
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 = [Link].strip_pruning(pruned_model)
stripped_model.compile(optimizer=[Link](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 =
[Link](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 = [Link](x_test[i:i+1]*255).astype(np.int8)
interpreter.set_tensor(input_details[0]['index'], input_data)
[Link]()
output = interpreter.get_tensor(output_details[0]['index'])
pred = [Link](output)
true = [Link](y_test[i])
if pred == true:
correct += 1
acc_quant = correct / len(x_test)
# Print Results
print(f"{[Link]()} 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/[Link]:
UserWarning: You are saving your model as an HDF5 file via `[Link]()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `[Link]('my_model.keras')`.
saving_api.save_model(
[]
/usr/local/lib/python3.11/dist-packages/keras/src/engine/[Link]:
UserWarning: You are saving your model as an HDF5 file via `[Link]()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `[Link]('my_model.keras')`.
saving_api.save_model(
/usr/local/lib/python3.11/dist-packages/tensorflow/lite/python/[Link]:
UserWarning: Statistics for quantized inputs were expected, but not specified;
continuing anyway.
[Link](
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 [Link]
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/[Link]:
UserWarning: You are saving your model as an HDF5 file via `[Link]()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `[Link]('my_model.keras')`.
saving_api.save_model(
[]
/usr/local/lib/python3.11/dist-packages/keras/src/engine/[Link]:
UserWarning: You are saving your model as an HDF5 file via `[Link]()`. This
file format is considered legacy. We recommend using instead the native Keras
format, e.g. `[Link]('my_model.keras')`.
saving_api.save_model(
/usr/local/lib/python3.11/dist-packages/tensorflow/lite/python/[Link]:
UserWarning: Statistics for quantized inputs were expected, but not specified;
continuing anyway.
[Link](
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
[]