Advanced
Full Practice Session
Five complete model-building exercises that simulate the actual exam experience. Each exercise provides a dataset, requirements, and target metrics. Try to complete all five within 5 hours to simulate exam conditions. Solutions are provided after each exercise.
How to use this practice session: Set a 5-hour timer. Open a Jupyter notebook or PyCharm. Work through all 5 exercises without looking at the solutions. Only check the solutions after you have submitted your model (or after the timer runs out). This is the closest you can get to the real exam experience.
Exercise 1: Housing Price Prediction (Category 1)
Task: Build a regression model that predicts housing prices. Target MAE: below 50,000.
# ---- EXERCISE 1: Housing Price Prediction ----
# Category: Regression & Classification
# Time budget: 45 minutes
# Target: MAE < 50,000
import tensorflow as tf
import numpy as np
# Generate dataset
np.random.seed(42)
n = 5000
sq_ft = np.random.uniform(500, 5000, n)
bedrooms = np.random.randint(1, 7, n)
bathrooms = np.random.randint(1, 4, n)
age = np.random.uniform(0, 80, n)
garage = np.random.randint(0, 3, n)
pool = np.random.randint(0, 2, n)
price = (
sq_ft * 150 +
bedrooms * 30000 +
bathrooms * 20000 -
age * 1500 +
garage * 25000 +
pool * 40000 +
np.random.normal(0, 30000, n)
).astype(np.float32)
features = np.column_stack([sq_ft, bedrooms, bathrooms, age, garage, pool]).astype(np.float32)
# Split 80/20
split = int(0.8 * n)
x_train, x_val = features[:split], features[split:]
y_train, y_val = price[:split], price[split:]
# YOUR CODE HERE: Build and train a model
# Requirements:
# 1. Normalize the input features
# 2. Use at least 2 hidden layers
# 3. Achieve MAE < 50,000 on validation set
# 4. Save as 'exercise1_housing.h5'
Show Solution
# ---- SOLUTION: Exercise 1 ----
normalizer = tf.keras.layers.Normalization()
normalizer.adapt(x_train)
model = tf.keras.Sequential([
normalizer,
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(1)
])
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.fit(
x_train, y_train,
validation_data=(x_val, y_val),
epochs=100, batch_size=32,
callbacks=[tf.keras.callbacks.EarlyStopping(
monitor='val_mae', patience=10, restore_best_weights=True
)]
)
val_loss, val_mae = model.evaluate(x_val, y_val)
print(f"Validation MAE: ${val_mae:,.0f}")
model.save('exercise1_housing.h5')
Exercise 2: Image Classification (Category 2)
Task: Build a CNN that classifies CIFAR-10 images into 10 categories. Target accuracy: above 70%.
# ---- EXERCISE 2: CIFAR-10 Image Classification ----
# Category: CNNs
# Time budget: 60 minutes
# Target: Accuracy > 70%
import tensorflow as tf
# Load CIFAR-10
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
print(f"Training: {x_train.shape}") # (50000, 32, 32, 3)
print(f"Classes: 10")
print(f"Labels shape: {y_train.shape}") # (50000, 1)
# YOUR CODE HERE: Build and train a model
# Requirements:
# 1. Normalize pixel values
# 2. Use Conv2D + MaxPooling2D architecture OR transfer learning
# 3. Apply data augmentation
# 4. Achieve accuracy > 70% on test set
# 5. Save as 'exercise2_cifar10.h5'
Show Solution
# ---- SOLUTION: Exercise 2 ----
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
data_augmentation = tf.keras.Sequential([
tf.keras.layers.RandomFlip("horizontal"),
tf.keras.layers.RandomRotation(0.1),
tf.keras.layers.RandomZoom(0.1),
])
model = tf.keras.Sequential([
data_augmentation,
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(32,32,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
model.fit(
x_train, y_train,
validation_data=(x_test, y_test),
epochs=30, batch_size=64,
callbacks=[tf.keras.callbacks.EarlyStopping(
monitor='val_accuracy', patience=5, restore_best_weights=True
)]
)
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {test_acc:.4f}")
model.save('exercise2_cifar10.h5')
Exercise 3: Sentiment Analysis (Category 3)
Task: Build an NLP model for IMDB sentiment classification. Target accuracy: above 83%.
# ---- EXERCISE 3: IMDB Sentiment Analysis ----
# Category: NLP & Sequences
# Time budget: 60 minutes
# Target: Accuracy > 83%
import tensorflow as tf
VOCAB_SIZE = 10000
MAX_LENGTH = 120
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.imdb.load_data(
num_words=VOCAB_SIZE
)
print(f"Training samples: {len(x_train)}")
print(f"Sample sequence length: {len(x_train[0])}")
# YOUR CODE HERE: Build and train a model
# Requirements:
# 1. Pad sequences to MAX_LENGTH
# 2. Use Embedding + LSTM/Bidirectional architecture
# 3. Achieve accuracy > 83% on test set
# 4. Save as 'exercise3_sentiment.h5'
Show Solution
# ---- SOLUTION: Exercise 3 ----
x_train = tf.keras.utils.pad_sequences(x_train, maxlen=MAX_LENGTH,
padding='post', truncating='post')
x_test = tf.keras.utils.pad_sequences(x_test, maxlen=MAX_LENGTH,
padding='post', truncating='post')
model = tf.keras.Sequential([
tf.keras.layers.Embedding(VOCAB_SIZE, 64, input_length=MAX_LENGTH),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, return_sequences=True)),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(
optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy']
)
model.fit(
x_train, y_train,
validation_data=(x_test, y_test),
epochs=10, batch_size=64,
callbacks=[tf.keras.callbacks.EarlyStopping(
monitor='val_accuracy', patience=2, restore_best_weights=True
)]
)
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {test_acc:.4f}")
model.save('exercise3_sentiment.h5')
Exercise 4: Time Series Forecasting (Category 4)
Task: Build a model that forecasts sunspot activity. Target MAE: below 30.
# ---- EXERCISE 4: Sunspot Forecasting ----
# Category: Time Series
# Time budget: 60 minutes
# Target: MAE < 30
import tensorflow as tf
import numpy as np
# Generate synthetic sunspot-like data
np.random.seed(42)
time = np.arange(0, 3000)
series = (
40 + 30 * np.sin(2 * np.pi * time / 132) * # ~11 year cycle
(1 + 0.3 * np.sin(2 * np.pi * time / 1320)) + # Modulated amplitude
np.random.randn(3000) * 10 # Noise
).astype(np.float32)
series = np.maximum(series, 0) # Sunspots can't be negative
SPLIT_TIME = 2400
WINDOW_SIZE = 30
print(f"Series length: {len(series)}")
print(f"Training: {SPLIT_TIME} steps, Validation: {len(series) - SPLIT_TIME} steps")
# YOUR CODE HERE: Build and train a model
# Requirements:
# 1. Create windowed dataset from training portion
# 2. Build a model (Dense, LSTM, or hybrid)
# 3. Achieve MAE < 30 on validation period
# 4. Save as 'exercise4_sunspots.h5'
Show Solution
# ---- SOLUTION: Exercise 4 ----
def windowed_dataset(series, window_size, batch_size, shuffle_buffer):
ds = tf.data.Dataset.from_tensor_slices(series)
ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda w: w.batch(window_size + 1))
ds = ds.map(lambda w: (w[:-1], w[-1]))
ds = ds.shuffle(shuffle_buffer)
ds = ds.batch(batch_size).prefetch(1)
return ds
train_series = series[:SPLIT_TIME]
val_series = series[SPLIT_TIME:]
train_dataset = windowed_dataset(train_series, WINDOW_SIZE, 32, 1000)
model = tf.keras.Sequential([
tf.keras.layers.Lambda(lambda x: tf.expand_dims(x, axis=-1),
input_shape=[WINDOW_SIZE]),
tf.keras.layers.Conv1D(64, 5, padding='causal', activation='relu'),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(1)
])
model.compile(optimizer=tf.keras.optimizers.Adam(1e-3), loss='huber', metrics=['mae'])
model.fit(train_dataset, epochs=100,
callbacks=[tf.keras.callbacks.EarlyStopping(
monitor='loss', patience=10, restore_best_weights=True)])
# Evaluate
forecast = []
for t in range(SPLIT_TIME, len(series)):
window = series[t - WINDOW_SIZE:t][np.newaxis]
forecast.append(model.predict(window, verbose=0)[0, 0])
mae = np.mean(np.abs(np.array(forecast) - val_series[:len(forecast)]))
print(f"Validation MAE: {mae:.2f}")
model.save('exercise4_sunspots.h5')
Exercise 5: Multi-Class with Callbacks (Category 1)
Task: Build a classification model for Fashion MNIST that stops training when accuracy reaches 90%.
# ---- EXERCISE 5: Fashion MNIST with Custom Callback ----
# Category: Regression & Classification
# Time budget: 45 minutes
# Target: Accuracy > 90% with automatic stopping
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
print(f"Training: {x_train.shape}") # (60000, 28, 28)
print(f"Classes: 10")
# YOUR CODE HERE: Build and train a model
# Requirements:
# 1. Normalize pixel values
# 2. Create a custom callback that stops training at 90% accuracy
# 3. Use either Dense or CNN architecture
# 4. Save as 'exercise5_fashion.h5'
Show Solution
# ---- SOLUTION: Exercise 5 ----
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]
# Custom callback
class AccuracyCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
if logs.get('accuracy') and logs['accuracy'] >= 0.90:
print(f"\nReached 90% accuracy at epoch {epoch + 1}, stopping!")
self.model.stop_training = True
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=50, batch_size=64,
callbacks=[AccuracyCallback()])
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {test_acc:.4f}")
model.save('exercise5_fashion.h5')
Key Takeaways
- Practice under timed conditions — 5 hours total for all exercises
- Budget roughly 45-60 minutes per exercise, leaving 30 minutes as buffer
- Start with the category you are most confident in to build momentum
- If a model is not converging, simplify the architecture rather than adding complexity
- Always save your model as
.h5after each exercise - Run these exercises in a Jupyter notebook to simulate the exam environment
Lilly Tech Systems