Code Architecture — Label Smoothing Notebook
Overview
The notebook implements Label Smoothing Regularization (LSR) from scratch in PyTorch, trains a small image classifier with and without it on Fashion-MNIST, and compares calibration (confidence histograms, reliability diagrams) between the two models. The implementation is GPU-friendly but also runs on CPU within a reasonable time.
Section-by-Section Breakdown
1. Imports & Setup
torch,torch.nn,torch.nn.functional,torchvision,matplotlib,numpy- Device detection (CUDA if available, else CPU)
- Random seed fixing for reproducibility
2. Label Smoothing Loss from Scratch
- Class
LabelSmoothingLoss(nn.Module)__init__(num_classes, smoothing=0.1): stores ε and Kforward(logits, target):- Compute standard log-softmax:
log_probs = F.log_softmax(logits, dim=-1) - Create smoothed target distribution:
q' = (1-ε) * one_hot + ε/K - Compute cross-entropy against the smoothed target:
loss = -sum(q' * log_probs) / batch_size - Key shapes: logits (B, K), target (B,), log_probs (B, K), one_hot (B, K), loss scalar
- Compute standard log-softmax:
- Alternative implementation via
F.kl_divis also shown for comparison
3. NumPy Reference Implementation
- Function
label_smoothing_numpy(logits, target, num_classes, epsilon=0.1)- Demonstrates the same computation in pure NumPy for pedagogical clarity
- Shows the smoothed target matrix explicitly
- Verifies the equivalence: loss = (1-ε)·CE_hard + ε·CE_uniform
4. Dataset Preparation
- Fashion-MNIST via torchvision (28×28 grayscale, 10 classes)
- 60,000 train images, 10,000 test images
- Normalized with mean=0.2860, std=0.3530 (Fashion-MNIST statistics)
- DataLoaders with batch_size=128
5. Model Architecture
- Class
SmallCNN(nn.Module)- Two conv blocks: [Conv2d(1→32, 3×3) → ReLU → MaxPool2d(2×2)] × 2
- Feature dimension: 28→28→14→14→7→7 → flatten to 32×7×7 = 1568
- FC layer: 1568 → 128 → ReLU → Dropout(0.3) → 10
- Output: raw logits (B, 10)
- Total parameters: ~220K — small enough to train quickly on GPU or CPU
6. Training Function
- Function
train_model(model, train_loader, criterion, optimizer, epochs, device)- Standard training loop with per-epoch loss/accuracy tracking
- Returns training history (losses, accuracies)
- Supports both standard CrossEntropyLoss and LabelSmoothingLoss as criterion
7. Evaluation & Calibration Metrics
- Function
evaluate_with_confidence(model, test_loader, device)- Collects: predicted probabilities (softmax), predicted class, true class for all test samples
- Computes: test accuracy, mean confidence, expected calibration error (ECE)
- ECE: bins predictions by confidence (10 bins), computes |accuracy(bin) - confidence(bin)| weighted by bin size
- Returns confidence values, correctness array, ECE
8. Training Two Models
- Model A: trained with standard
nn.CrossEntropyLoss()(hard one-hot labels) - Model B: trained with
LabelSmoothingLoss(num_classes=10, smoothing=0.1) - Same architecture, same optimizer (Adam, lr=1e-3), same number of epochs (10)
- Both models trained on the same data split for fair comparison
9. Visualization & Comparison
- Confidence histograms: distribution of max-softmax probabilities for correct vs incorrect predictions, side by side for both models
- Reliability diagram: 10-bin calibration plot — ideal is a diagonal line; shows how far each model deviates
- Accuracy vs confidence bar chart: per-bin accuracy and confidence for both models
- Training curves: loss and accuracy over epochs for both models
10. Summary Statistics
- Print table: accuracy, mean confidence, ECE for both models
- Discussion: label smoothing should produce slightly lower confidence but better calibration (lower ECE)
Data Flow / Shapes
Input: (B, 1, 28, 28) images
→ Conv1: (B, 32, 28, 28) → ReLU → MaxPool: (B, 32, 14, 14)
→ Conv2: (B, 32, 14, 14) → ReLU → MaxPool: (B, 32, 7, 7)
→ Flatten: (B, 1568)
→ FC1: (B, 128) → ReLU → Dropout
→ FC2: (B, 10) [logits]
→ Softmax: (B, 10) [probabilities]
LabelSmoothingLoss:
logits (B, 10) + target (B,) → log_softmax (B, 10)
→ one_hot (B, 10) → smooth: q' = (1-ε)*one_hot + ε/K (B, 10)
→ loss = -mean(sum(q' * log_softmax, dim=1))
Deliberate Simplifications vs. Full Paper
- Fashion-MNIST instead of ImageNet (ILSVRC 2012): The paper uses 1000-class ImageNet with ~1.2M images. We use 10-class Fashion-MNIST with 60K images for faster training. The label smoothing formula is identical.
- Small CNN instead of Inception-v3: The paper’s main contribution is the Inception-v3 architecture; we focus exclusively on the label smoothing regularizer and use a simple CNN as the classifier. This isolates the effect of label smoothing.
- ε = 0.1 (same as paper): We use the same smoothing value as the paper’s ImageNet experiments.
- 10 epochs instead of 100: The paper trains for 100 epochs on 50 GPUs. We train for 10 epochs on a single GPU/CPU — enough to show the calibration difference.
- ECE instead of top-1/top-5 error: The paper reports top-1/top-5 classification error. We additionally compute Expected Calibration Error (ECE) to directly measure the calibration improvement that label smoothing provides.
- No ensemble or multi-crop evaluation: The paper uses ensembles of 4 models and multi-crop evaluation. We use single-model, single-crop evaluation for simplicity.