Traffic sign classification using EfficientNet on the Mapillary Traffic Sign Dataset (MTSD).
Traffic sign classification using EfficientNet on the Mapillary Traffic Sign Dataset (MTSD)
Features • Installation • Usage • Results • Contributing
This project implements a two-stage traffic sign recognition pipeline:
- YOLOPX - Detects traffic signs (bounding boxes)
- EfficientNet - Classifies detected signs into categories
This repository focuses on Stage 2: Classification with EfficientNet.
Source: Mapillary Traffic Sign Dataset (MTSD) v2 Fully Annotated
- Training: 36,589 images → 21,582 traffic sign patches
- Validation: 5,319 images → 3,114 traffic sign patches
- Categories: 15 traffic sign types
| Category | Train Patches | Val Patches |
|---|---|---|
| Speed Limit | 5,634 | 819 |
| Pedestrian Crossing | 3,522 | 496 |
| Yield | 2,428 | 347 |
| Do Not Enter | 2,231 | 317 |
| Turn Right Only | 1,306 | 185 |
| Turn Left Only | 1,290 | 198 |
| Stop | 1,302 | 189 |
| Go Straight Only | 947 | 134 |
| Railroad Crossing | 839 | 128 |
| No U-Turn | 560 | 77 |
| Roadwork | 506 | 75 |
| No Left Turn | 502 | 74 |
| No Right Turn | 408 | 57 |
| No Straight | 93 | 17 |
| Detour | 14 | 1 |
eff_sign_detection/
├── tools/
│ ├── explore_mapillary.py # Dataset exploration
│ ├── create_class_mapping.py # Class mapping analysis
│ ├── generate_patch_dataset.py # Extract patches from MTSD
│ └── README.md # Tools documentation
├── train.py # Training script
├── evaluate.py # Evaluation script
├── requirements.txt # Python dependencies
├── results/
│ ├── visualizations/ # Dataset visualizations
│ ├── statistics/ # Dataset statistics
│ └── CLASS_MAPPING_SUMMARY.md # Detailed analysis
└── experiments/ # Training checkpoints & logs
conda create -n eff_sign_det python=3.10
conda activate eff_sign_detpip install -r requirements.txtRequired packages:
- PyTorch >= 2.0.0 (with CUDA support recommended)
- torchvision >= 0.15.0
- OpenCV
- NumPy, Matplotlib, Seaborn
- TensorBoard
- scikit-learn
python tools/explore_mapillary.pyGenerates:
results/visualizations/mapillary_dataset_analysis.pngresults/visualizations/mapillary_sample_patches.pngresults/statistics/{train,val,test}_statistics.json
python tools/create_class_mapping.pyGenerates:
results/statistics/class_mapping.json- Console output with recommendations
python tools/generate_patch_dataset.pyWhat it does:
- Extracts 1.2x expanded crops around each bounding box
- Resizes to 128×128 with padding
- Organizes into train/val splits by category
- Computes class weights for training
Output: /data/datasets/mtsd_patches_128/
Options:
# Custom expansion
python tools/generate_patch_dataset.py --expansion 1.3
# Larger patches (for EfficientNet-B2)
python tools/generate_patch_dataset.py --patch-size 224
# Include ambiguous signs
python tools/generate_patch_dataset.py --no-skip-ambiguous# Basic training (EfficientNet-B0)
python train.py
# With custom parameters
python train.py \
--model efficientnet_b0 \
--epochs 50 \
--batch-size 32 \
--lr 0.001 \
--use-class-weights
# Train EfficientNet-B1
python train.py --model efficientnet_b1 --image-size 240
# Resume training
python train.py --resume experiments/efficientnet_b0_YYYYMMDD_HHMMSS/best.pthTraining options:
--model: efficientnet_b0, efficientnet_b1, efficientnet_b2--epochs: Number of epochs (default: 50)--batch-size: Batch size (default: 32)--lr: Learning rate (default: 0.001)--use-class-weights: Use inverse frequency weighting--scheduler: step, cosine, plateau--pretrained: Use ImageNet pretrained weights (default: True)
Outputs:
experiments/efficientnet_b0_YYYYMMDD_HHMMSS/
├── best.pth # Best model checkpoint
├── last.pth # Last epoch checkpoint
├── config.json # Training configuration
└── logs/ # TensorBoard logs
Monitor training:
tensorboard --logdir experiments/efficientnet_b0_YYYYMMDD_HHMMSS/logspython evaluate.py --checkpoint experiments/efficientnet_b0_YYYYMMDD_HHMMSS/best.pthOutputs:
evaluation_results.json- Detailed metricsconfusion_matrix.png- Confusion matrix heatmapper_class_metrics.png- Per-class performance chartmisclassified_samples.json- Top-100 confident mistakes
- Random rotation (±15°)
- Color jitter (brightness, contrast, saturation)
- Random sharpness adjustment
- Gaussian blur
- Standard ImageNet normalization
Automatically computed inverse frequency weights to handle class imbalance:
weight = total_samples / (num_classes * class_count)- EfficientNet-B0: 128×128 input, ~5.3M parameters
- EfficientNet-B1: 240×240 input, ~7.8M parameters
- EfficientNet-B2: 260×260 input, ~9.2M parameters
All models use ImageNet pretrained weights by default.
- Step: LR decay at fixed intervals
- Cosine: Cosine annealing
- Plateau: Reduce on validation plateau
(To be updated after training)
Expected performance:
- Overall Accuracy: >90% on validation set
- Rare classes (detour, no_straight): Lower accuracy due to limited data
- Detour: Only 14 training samples - consider dropping
- No Straight: 93 samples - needs heavy augmentation
- Speed Limit: 5,634 samples - well represented
The dataset contains 22 different speed limit values. Two approaches:
- Flat classification: Treat each speed as a separate class
- OCR approach: Single "speed_limit" class + OCR for digit recognition
Recommendation: OCR approach for flexibility and scalability.
For classes with <500 examples:
- Rotation: ±15°
- Brightness: ±30%
- Contrast: ±30%
- Gaussian blur
- Simulated occlusion
DO NOT use horizontal flip - it changes sign meaning!
- YOLOPX detects sign bounding boxes
- Extract 1.2x crop from original image
- Resize to 128×128
- Feed to EfficientNet classifier
- Return sign category
- Dataset: Mapillary Traffic Sign Dataset
- Paper: The Mapillary Traffic Sign Dataset for Detection and Classification on a Global Scale
- EfficientNet: EfficientNet: Rethinking Model Scaling for CNNs
✅ 1.2x Crop Strategy: Implemented in generate_patch_dataset.py
✅ 128×128 Patches: Default size (configurable)
✅ Class Weighting: Automatic computation and application
✅ Offline Dataset Creation: Uses MTSD labels, not YOLOPX predictions
✅ Train/Val Splits: Organized by MTSD splits
✅ EfficientNet/MobileNet: EfficientNet-B0/B1/B2 supported
This project uses the Mapillary Traffic Sign Dataset, which is provided under its own license. Please refer to the dataset documentation for details.
For questions about this implementation, refer to the project documentation or consult with your professor.