Steel Surface Defect Detection - NEU-DET checkpoints
Trained checkpoints backing
SteelDefectDetection.
Weights only - all metrics, code and audit trail live in the GitHub repo.
Production model - production/best.pt
Stock YOLO11n @640. TEST mAP@0.5 = 0.7832 +/- 0.0105 (mean +/- std over 5 seeds,
95% CI [0.7701, 0.7962]), mAP@0.5:0.95 0.4079, 2.583 M params, 6.32 GFLOPs, 5.5 MB.
Protocol: stratified 8:1:1 split of NEU-DET (1440/180/180), held-out TEST split,
imgsz 640, no TTA, NMS IoU 0.6. This is the protocol reported by Ma et al. 2025,
whose 0.786 our result is statistically tied with (one-sample t, p = 0.58).
We did not beat that paper, and we lose on model cost (+27% params, +24% GFLOPs).
production/best.pt is the seed-42 checkpoint, selected on the validation split
(VAL 0.7722, best of five). Its TEST score is 0.7837.
Per-class TEST AP@0.5 (5-seed mean)
| patches | pitted_surface | inclusion | scratches | rolled-in_scale | crazing |
|---|
| 0.936 | 0.865 | 0.855 | 0.849 | 0.640 | 0.555 |
crazing is the weak class - treat its non-detections with caution. The 180-image test
set carries a +/-1.4 pp noise floor, so differences under ~3 pp are ties.
Contents
| Path | What |
|---|
production/best.pt | the shipped model (= yolo11n/seed42.pt) |
yolo11n/seed{42,123,777,2025,3407}.pt | the 5-seed production arm |
yolov8n/seed{42,123,777,2025,3407}.pt | the 5-seed comparison arm (superseded) |
Per-seed arms are published so the headline's uncertainty is reproducible and so the
checkpoints can be ensembled - not because any single seed is special.
Usage
1from ultralytics import YOLO
2model = YOLO("production/best.pt")
3results = model.predict("steel.jpg", imgsz=640, iou=0.6)
Inputs are collapsed to grayscale-replicated 3-channel before inference (NEU-DET is a
grayscale dataset and the model was trained that way). Use
src/preprocessing.to_model_input() from the GitHub repo - feeding raw colour is a
train/inference mismatch.
Classes
crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches