Exam project for the Machine Learning, Artificial Neural Networks and Deep Learning course, part of the Bachelor's degree in Artificial Intelligence — a joint program between the University of Pavia, the University of Milano-Bicocca, and the University of Milano Statale.
Given a dataset of 186 images belonging to 3 classes (63, 62, and 61 images respectively), design and train a deep neural network that jointly predicts, for each image:
- the class of the main object it contains, and
- the bounding box coordinates (bottom-left and top-right corners) of that object.
Each input image is 227×227×3. The full assignment specification is in docs/assigment_specs.pdf.
-
Preprocessing: pixel values scaled from [0, 255] to [0, 1]; bounding box coordinates scaled from [1, 227] to [0, 1]; class labels remapped from {1, 2, 3} to {0, 1, 2}.
-
Data augmentation to compensate for the small dataset size, followed by a train/test split.
-
Model: a single multi-output CNN with a shared convolutional backbone (
Conv2D+MaxPooling2D+Dropoutblocks, ReLU activations, He-uniform initialization) that branches into two dense heads:- a classification head (sigmoid-activated dense layers + softmax output) trained with sparse categorical cross-entropy,
- a regression head (sigmoid-activated dense layers + sigmoid output) trained with mean squared error, predicting the 4 bounding box coordinates.
Both heads share the flattened convolutional features. Optimized with Adam and gradient clipping (
clipnorm=1.0). -
Hyperparameter tuning: a custom scikit-learn-compatible estimator wraps the Keras model so it can be tuned with
RandomizedSearchCV(used instead of a full grid search due to Colab's time/memory constraints) over: number of conv/pool layers, number of dense layers, filter dimensions, hidden layer sizes, batch size, learning rate, and dropout rate. -
Final training & evaluation: the best configuration found by the search is retrained for more epochs on the full training set, then evaluated on the held-out test set.
| Metric | Value |
|---|---|
| Classification F1 (weighted) | 0.9645 |
| Bounding box MSE | 0.0101 |
Predicted class and bounding box on two test images:
.
├── data/
│ └── input_data.zip # image dataset (classes + bounding boxes)
├── docs/
│ ├── assigment_specs.pdf # original exam assignment
│ └── images/ # architecture diagram + sample predictions
├── notebook/
│ └── classification-and-bounding-boxes.ipynb # full implementation
└── .gitattributes
tensorflow
scikit-learn
numpy
matplotlib
Unzip data/input_data.zip, then open notebook/classification-and-bounding-boxes.ipynb and run the cells top to bottom (originally developed on Google Colab).


