← Back to Projects Deep Learning

FashionMNIST Image Classification

A FashionMNIST computer-vision experiment comparing CNN architectures, with a TinyVGG-inspired model and detailed error inspection.

PythonPyTorchCNNComputer Vision
Question How much does a deeper convolutional architecture improve FashionMNIST classification, and where does it still confuse visually similar classes?
Focus Computer vision · CNN architecture · PyTorch
Outcome A TinyVGG-style CNN benchmarked against simpler baselines with prediction and confusion-matrix analysis.

The problem

This project explores image classification using the FashionMNIST dataset, focusing on comparing CNN architectures to improve accuracy and training efficiency. It began as a practical extension of previous work in computer vision, driven by curiosity to deepen my understanding of how convolutional layers and activation functions impact learning. I designed a CNN inspired by the TinyVGG architecture and benchmarked it against two other models on performance and training time.

Question

How much does a deeper convolutional architecture improve FashionMNIST classification, and where does it still confuse visually similar classes?

Approach

Rather than presenting the project as a notebook dump, this case study focuses on the decisions that shaped the analysis.

  1. Import & Setup: Loaded FashionMNIST using torchvision.datasets , transforming PIL images into PyTorch tensors.
  2. Visual Exploration: Used matplotlib.pyplot to visualise images in grayscale and display class names, gaining familiarity with the data distribution (Figures A–C).
  3. Data Loaders: Implemented DataLoader objects with shuffling and batching (batch size = 32) for both training and test datasets.
  4. Model Definition: Constructed a CNN (TinyVGG-inspired) using nn.Sequential blocks for convolution, activation, and pooling, with a dynamically calculated flattened feature size for the final Linear layer.
  5. Model Training: Trained the CNN using a loop with manual timing and CrossEntropyLoss . Tracked model accuracy with a custom accuracy_function .
  6. Model Evaluation: Used a combination of random sample predictions, visual comparisons (Figure 3), and a confusion matrix (Figure 4) using TorchMetrics + MLXtend for deeper analysis.

Key implementation decision

Calculate the flattened feature size dynamically instead of hard-coding it

Convolution and pooling layers change spatial dimensions. Passing a dummy tensor through the feature extractor makes the classifier reusable and avoids manually recalculating the input size every time the convolutional blocks change.

with torch.no_grad():
    dummy_input = torch.randn(1, input_shape, 28, 28)
    x = self.conv_block_1(dummy_input)
    x = self.conv_block_2(x)
    self.flattened_size = x.view(1, -1).shape[1]

self.classifier = nn.Sequential(
    nn.Flatten(),
    nn.Linear(self.flattened_size, output_shape)
)
Why this matters

The project was a practical way to connect convolutional architecture choices with model behaviour. The confusion matrix is especially useful because FashionMNIST contains categories that are visually similar even when overall accuracy is strong.

Results & evidence

The figures below are the project evidence I would show first. The full implementation remains available through the GitHub link at the top of the page.

What challenged me

A key challenge was dynamically computing the flattened input size after the convolutional layers to correctly set up the first Linear layer. To solve this, I used a with torch.no_grad() block to pass dummy input through the conv layers and automatically extract the output shape. This approach prevented manual miscalculation and made the model reusable for different input sizes.

What I learned

  • Deeper convolutional blocks captured spatial structure better than simpler baselines in this experiment.
  • Error analysis exposed confusion between visually similar clothing classes that an aggregate score could hide.
  • Computing the flattened feature size programmatically made the architecture easier to modify safely.

What I would improve next

  • Test targeted augmentation for the classes that are most frequently confused.
  • Use a validation set or cross-validation strategy consistently when comparing architectures.
  • Profile training time and parameter count alongside accuracy so efficiency is part of the comparison.
Full implementation: use the GitHub link in the project header for the complete notebook/code rather than expanding the case study into a full source listing.