Modellbeschneidung und -sparsität in YOLOv5
📚 Dieser Leitfaden erklärt, wie man Pruning auf YOLOv5 🚀 Modelle anwendet, um effizientere Netzwerke zu erstellen und gleichzeitig die Leistung aufrechtzuerhalten.
Was ist Modellbeschneidung?
Modellbeschneidung ist eine Technik, mit der die Größe und Komplexität neuronaler Netze reduziert wird, indem weniger wichtige Parameter (Gewichte und Verbindungen) entfernt werden. Dieser Prozess erzeugt ein effizienteres Modell mit mehreren Vorteilen:
- Reduzierte Modellgröße für einfachere Bereitstellung auf Geräten mit beschränkten Ressourcen
- Schnellere Inferenzgeschwindigkeiten bei minimalen Auswirkungen auf die Genauigkeit
- Geringerer Speicherverbrauch und Energieverbrauch
- Verbesserte Gesamteffizienz für Echtzeitanwendungen
Pruning funktioniert, indem Parameter identifiziert und entfernt werden, die nur minimal zur Leistung des Modells beitragen. Dies führt zu einem schlankeren Modell mit ähnlicher Genauigkeit.
Bevor Sie beginnen
Repository klonen und requirements.txt in einer Python>=3.8.0-Umgebung installieren, einschließlich PyTorch>=1.8. Modelle und Datensätze werden automatisch von der neuesten YOLOv5 Version heruntergeladen.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
Testen der Basislinien-Performance
Ermitteln Sie eine Ausgangsleistung, mit der Sie vergleichen können, bevor Sie mit dem Pruning beginnen. Dieser Befehl testet YOLOv5x auf COCO val2017 bei einer Bildgröße von 640 Pixeln. yolov5x.pt
ist das größte und genaueste verfügbare Modell. Andere Optionen sind yolov5s.pt
, yolov5m.pt
und yolov5l.pt
, oder Ihren eigenen Checkpoint aus dem Training eines benutzerdefinierten Datensatzes übergeben ./weights/best.pt
. Einzelheiten zu allen verfügbaren Modellen finden Sie in der README-Datei. Tabelle.
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --half
Ausgabe:
val: data=/content/yolov5/data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, workers=8, single_cls=False, augment=False, verbose=False, save_txt=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True, dnn=False
YOLOv5 🚀 v6.0-224-g4c40933 torch 1.10.0+cu111 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB)
Fusing layers...
Model Summary: 444 layers, 86705005 parameters, 0 gradients
val: Scanning '/content/datasets/coco/val2017.cache' images and labels... 4952 found, 48 missing, 0 empty, 0 corrupt: 100% 5000/5000 [00:00<?, ?it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 157/157 [01:12<00:00, 2.16it/s]
all 5000 36335 0.732 0.628 0.683 0.496
Speed: 0.1ms pre-process, 5.2ms inference, 1.7ms NMS per image at shape (32, 3, 640, 640) # <--- base speed
Evaluating pycocotools mAP... saving runs/val/exp2/yolov5x_predictions.json...
...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.507 # <--- base mAP
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.689
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.552
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.345
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.559
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.652
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.381
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.630
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.682
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.526
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.731
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.829
Results saved to runs/val/exp
Pruning auf YOLOv5x anwenden (30% Sparsity)
Wir können Pruning auf das Modell anwenden, indem wir den torch_utils.prune()
Befehl. Um ein reduziertes Modell zu testen, aktualisieren wir val.py
um YOLOv5x auf 0,3 Sparsity zu reduzieren (30 % der Gewichte auf Null gesetzt):
30% reduzierter Output:
val: data=/content/yolov5/data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, workers=8, single_cls=False, augment=False, verbose=False, save_txt=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True, dnn=False
YOLOv5 🚀 v6.0-224-g4c40933 torch 1.10.0+cu111 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB)
Fusing layers...
Model Summary: 444 layers, 86705005 parameters, 0 gradients
Pruning model... 0.3 global sparsity
val: Scanning '/content/datasets/coco/val2017.cache' images and labels... 4952 found, 48 missing, 0 empty, 0 corrupt: 100% 5000/5000 [00:00<?, ?it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 157/157 [01:11<00:00, 2.19it/s]
all 5000 36335 0.724 0.614 0.671 0.478
Speed: 0.1ms pre-process, 5.2ms inference, 1.7ms NMS per image at shape (32, 3, 640, 640) # <--- prune speed
Evaluating pycocotools mAP... saving runs/val/exp3/yolov5x_predictions.json...
...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.489 # <--- prune mAP
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.677
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.537
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.334
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.542
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.635
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.370
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.612
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.664
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.496
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.722
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.803
Results saved to runs/val/exp3
Ergebnisanalyse
Aus den Ergebnissen können wir Folgendes beobachten:
- 30 % erreichte Sparsity: 30 % der Gewichtungsparameter des Modells in
nn.Conv2d
Layer sind jetzt Null - Die Inferenzzeit bleibt unverändert: Trotz des Prunings bleibt die Verarbeitungsgeschwindigkeit im Wesentlichen gleich.
- Minimale Auswirkung auf die Leistung: mAP sank leicht von 0,507 auf 0,489 (nur 3,6 % Reduktion)
- Reduzierung der Modellgröße: Das reduzierte Modell benötigt weniger Speicherplatz.
Dies zeigt, dass Pruning die Modellkomplexität erheblich reduzieren kann, mit nur geringen Auswirkungen auf die Leistung. Dies macht es zu einer effektiven Optimierungstechnik für den Einsatz in ressourcenbeschränkten Umgebungen.
Feinabstimmung von reduzierten Modellen
Um die besten Ergebnisse zu erzielen, sollten reduzierte Modelle nach der Reduzierung feinabgestimmt werden, um die Genauigkeit wiederherzustellen. Dies kann erfolgen durch:
- Anwenden von Pruning mit einem gewünschten Sparsity-Level
- Trainieren des reduzierten Modells für einige Epochen mit einer niedrigeren Lernrate
- Bewertung des feinabgestimmten, reduzierten Modells im Vergleich zur Basislinie
Dieser Prozess hilft den verbleibenden Parametern, sich anzupassen, um die entfernten Verbindungen zu kompensieren, wodurch oft ein Großteil oder die gesamte ursprüngliche Genauigkeit wiederhergestellt wird.
Unterstützte Umgebungen
Ultralytics bietet eine Reihe von gebrauchsfertigen Umgebungen, die jeweils mit wichtigen Abhängigkeiten wie CUDA, CUDNN, Python und PyTorch vorinstalliert sind, um Ihre Projekte zu starten.
- Kostenlose GPU Notebooks:
- Google Cloud: GCP Quickstart-Anleitung
- Amazon: AWS Quickstart-Anleitung
- Azure: AzureML Quickstart-Anleitung
- Docker: Docker Quickstart-Anleitung
Projektstatus
Dieses Badge zeigt an, dass alle YOLOv5 GitHub Actions Continuous Integration (CI)-Tests erfolgreich bestanden wurden. Diese CI-Tests überprüfen rigoros die Funktionalität und Leistung von YOLOv5 in verschiedenen Schlüsselbereichen: Training, Validierung, Inferenz, Export und Benchmarks. Sie gewährleisten einen konsistenten und zuverlässigen Betrieb unter macOS, Windows und Ubuntu, wobei die Tests alle 24 Stunden und bei jedem neuen Commit durchgeführt werden.