Élagage et parcimonie des modèles dans YOLOv5#
📚 Ce guide explique comment appliquer l'élagage aux modèles YOLOv5 🚀 pour créer des réseaux plus efficaces tout en préservant leurs performances.
Qu'est-ce que l'élagage de modèles ?#
L'élagage de modèles est une technique qui réduit la taille et la complexité des réseaux neuronaux en supprimant les paramètres (poids et connexions) les moins importants. Ce processus permet de créer un modèle plus efficace, avec plusieurs avantages :
- Taille de modèle réduite pour faciliter le déploiement sur des appareils aux ressources limitées
- Inférence plus rapide avec un impact minimal sur la précision
- Utilisation réduite de la mémoire et de l'énergie
- Efficacité globale améliorée pour les applications en temps réel
L'élagage consiste à identifier et à supprimer les paramètres qui contribuent le moins aux performances du modèle, ce qui permet d'obtenir un modèle plus léger offrant une précision similaire.
Avant de commencer#
Clone le dépôt et installe requirements.txt dans un environnement Python>=3.8.0, avec PyTorch>=1.8. Les modèles et les jeux de données sont téléchargés automatiquement depuis la dernière version de YOLOv5.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # installTester les performances de référence#
Avant l'élagage, établis des performances de référence pour les comparer. Cette commande teste YOLOv5x sur COCO val2017 avec une taille d'image de 640 pixels. yolov5x.pt est le modèle disponible le plus grand et le plus précis. Les autres options sont yolov5s.pt, yolov5m.pt et yolov5l.pt, ou ton propre checkpoint issu de l'entraînement sur un jeu de données personnalisé, c'est-à-dire runs/train/exp/weights/best.pt. Pour plus de détails sur tous les modèles disponibles, consulte le tableau du fichier README.
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --halfSortie :
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/exp2Appliquer l'élagage à YOLOv5x (parcimonie de 30 %)#
Tu peux appliquer l'élagage au modèle à l'aide de la fonction prune() définie dans utils/torch_utils.py. Pour tester un modèle élagué, modifie val.py afin d'élaguer YOLOv5x jusqu'à atteindre une parcimonie de 0.3 (30 % des poids mis à zéro) :
Résultat après un élagage de 30 % :
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/exp3Analyse des résultats#
Les résultats montrent que :
- Parcimonie de 30 % atteinte : 30 % des paramètres de poids du modèle dans les couches
nn.Conv2dsont désormais nuls - Le temps d'inférence reste inchangé : malgré l'élagage, la vitesse de traitement reste pratiquement identique
- Impact minimal sur les performances : le mAP a légèrement baissé, de 0.507 à 0.489 (soit une réduction de seulement 3.6 %)
- Taille du modèle inchangée : les poids mis à zéro sont toujours stockés de manière dense ; la taille du fichier ne diminue donc qu'avec des formats ou une compression prenant en charge les représentations creuses
Cela montre que l'élagage peut réduire considérablement la complexité du modèle avec un impact minime sur les performances, ce qui en fait une technique d'optimisation efficace pour le déploiement dans des environnements aux ressources limitées.
Ajustement fin des modèles élagués#
Pour obtenir les meilleurs résultats, les modèles élagués doivent faire l'objet d'un ajustement fin après l'élagage afin de retrouver leur précision. Pour cela :
- Applique l'élagage en définissant le niveau de parcimonie souhaité
- Entraîne le modèle élagué pendant quelques époques avec un taux d'apprentissage plus faible
- Évalue le modèle élagué après ajustement fin en le comparant aux performances de référence
Ce processus permet aux paramètres restants de s'adapter pour compenser les connexions supprimées et de retrouver souvent tout ou partie de la précision d'origine.
Environnements pris en charge#
Ultralytics propose un ensemble d’environnements prêts à l’emploi, chacun préinstallé avec les dépendances essentielles comme CUDA, CUDNN, Python et PyTorch, pour te permettre de démarrer tes projets.
- Notebooks GPU gratuits :
- Google Cloud : Guide de démarrage rapide GCP
- Amazon : Guide de démarrage rapide AWS
- Azure : Guide de démarrage rapide AzureML
- Docker : Guide de démarrage rapide Docker
État du projet#
Ce badge indique que tous les tests d’intégration continue (CI) de GitHub Actions pour YOLOv5 réussissent. Ces tests CI vérifient rigoureusement le fonctionnement et les performances de YOLOv5 dans plusieurs domaines clés : entraînement, validation, inférence, exportation et tests de performance. Ils garantissent un fonctionnement cohérent et fiable sur macOS, Windows et Ubuntu, grâce à des tests effectués toutes les 24 heures et à chaque nouveau commit.
FAQ#
L'élagage non structuré met les poids à zéro, mais conserve la forme des tenseurs : les noyaux denses de PyTorch effectuent donc la même quantité de calculs. Pour accélérer l'exécution, il faut un environnement d'exécution prenant en charge la parcimonie, comme DeepSparse, ou un élagage structuré qui supprime des canaux entiers.
Appelle la fonction utilitaire de
utils/torch_utils.pyavant la validation ou l'exportation :from utils.torch_utils import prune prune(model, amount=0.3) # Parcimonie globale de 30 % sur les poids nn.Conv2dCommence à 0.3 et mesure le mAP. YOLOv5x a perdu environ 3.6 % de mAP avec une parcimonie de 30 % sans ajustement fin ; les niveaux de parcimonie plus élevés nécessitent généralement quelques époques de réentraînement avec un faible taux d'apprentissage pour retrouver la précision.
Oui. Les poids mis à zéro sont enregistrés comme les autres ;
export.pyfonctionne donc sans modification. La taille du fichier ne diminue que si le format cible ou l'environnement d'exécution compresse les tenseurs creux.