Skip to main content

Modell-Pruning und -Sparsity in YOLOv5

📚 Dieser Leitfaden erklärt, wie du Pruning auf YOLOv5 🚀 Modelle anwendest, um effizientere Netzwerke bei gleichbleibender Leistung zu erstellen.

Was ist Modell-Pruning?

Modell-Pruning ist eine Technik zur Reduzierung der Größe und Komplexität neuronaler Netze durch das Entfernen weniger wichtiger Parameter (Gewichte und Verbindungen). Dieser Prozess schafft ein effizienteres Modell mit mehreren Vorteilen:

  • Reduzierte Modellgröße für einfachere Bereitstellung auf Geräten mit begrenzten Ressourcen
  • Schnellere Inferenzgeschwindigkeiten bei minimalen Auswirkungen auf die Genauigkeit
  • Geringerer Speicherbedarf und Energieverbrauch
  • Verbesserte Gesamteffizienz für Echtzeitanwendungen

Pruning funktioniert, indem Parameter identifiziert und entfernt werden, die nur minimal zur Leistung des Modells beitragen, was zu einem leichteren Modell mit ähnlicher Genauigkeit führt.

Bevor du startest

Klone das Repo und installiere requirements.txt in einer Python>=3.8.0 Umgebung, einschließlich PyTorch>=1.8. Modelle und Datensätze automatisch herunterladen von der neuesten YOLOv5 Release.

git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install

Basis-Leistung testen

Bevor du mit dem Pruning beginnst, lege eine Basis-Leistung fest, um Vergleiche anstellen zu können. 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. Weitere Optionen sind yolov5s.pt, yolov5m.pt und yolov5l.pt, oder dein eigener Checkpoint aus dem Training eines benutzerdefinierten Datensatzes ./weights/best.pt. Details zu allen verfügbaren Modellen findest du in der README 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/exp-2/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 mit dem torch_utils.prune() Befehl anwenden, der in utils/torch_utils.py definiert ist. Um ein gepruntes Modell zu testen, aktualisieren wir val.py, um YOLOv5x auf 0.3 Sparsity zu bringen (30% der Gewichte werden auf Null gesetzt):

YOLOv5 model pruning to 30% sparsity code

30% geprunte 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
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/exp-3/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/exp-3

Ergebnisanalyse

Aus den Ergebnissen können wir Folgendes ableiten:

  • 30% Sparsity erreicht: 30% der Gewichtsparameter des Modells in nn.Conv2d Layern sind jetzt Null
  • Inferenzzeit bleibt unverändert: Trotz des Prunings ist die Verarbeitungsgeschwindigkeit im Wesentlichen gleich
  • Minimale Leistungseinbußen: mAP sank leicht von 0.507 auf 0.489 (nur 3,6% Reduzierung)
  • Reduzierung der Modellgröße: Das geprunte Modell benötigt weniger Speicherplatz

Dies zeigt, dass Pruning die Modellkomplexität bei nur geringen Auswirkungen auf die Leistung erheblich reduzieren kann, was es zu einer effektiven Optimierungstechnik für den Einsatz in ressourcenbeschränkten Umgebungen macht.

Geprunte Modelle feinabstimmen

Für optimale Ergebnisse sollten geprunte Modelle nach dem Pruning feinabgestimmt werden, um die Genauigkeit wiederherzustellen. Dies kann erreicht werden durch:

  1. Anwendung des Prunings mit einem gewünschten Sparsity-Level
  2. Training des geprunten Modells für einige Epochen mit einer niedrigeren Lernrate
  3. Evaluierung des feinabgestimmten geprunten Modells im Vergleich zur Basis

Dieser Prozess hilft den verbleibenden Parametern, sich anzupassen, um die entfernten Verbindungen auszugleichen, wodurch oft ein Großteil oder die gesamte ursprüngliche Genauigkeit wiederhergestellt wird.

Unterstützte Umgebungen

Ultralytics bietet eine Reihe sofort einsatzbereiter Umgebungen, jede mit wichtigen Abhängigkeiten wie CUDA, CUDNN, Python, und PyTorch, um deine Projekte zu starten.

Projektstatus

YOLOv5 CI

Dieses Abzeichen zeigt an, dass alle YOLOv5 GitHub Actions Continuous Integration (CI) Tests erfolgreich bestanden wurden. Diese CI-Tests prüfen rigoros die Funktionalität und Leistung von YOLOv5 über verschiedene Schlüsselaspekte: Trainings, Validierung, Inferenz, export, und benchmarks. Sie stellen einen konsistenten und zuverlässigen Betrieb auf macOS, Windows und Ubuntu sicher, mit Tests alle 24 Stunden und bei jedem neuen Commit.

Kommentare