Poda y dispersión de modelos en YOLOv5
📚 Esta guía explica cómo aplicar pruning (poda) a los modelos YOLOv5 🚀 para crear redes más eficientes manteniendo el rendimiento.
¿Qué es el "Model Pruning" (Poda de Modelos)?
La poda de modelos es una técnica utilizada para reducir el tamaño y la complejidad de las redes neuronales mediante la eliminación de parámetros (pesos y conexiones) menos importantes. Este proceso crea un modelo más eficiente con varios beneficios:
- Tamaño de modelo reducido para facilitar la implementación en dispositivos con recursos limitados
- Velocidades de inferencia más rápidas con un impacto mínimo en la precisión
- Menor uso de memoria y consumo de energía
- Mayor eficiencia general para aplicaciones en tiempo real
La poda funciona identificando y eliminando los parámetros que contribuyen mínimamente al rendimiento del modelo, lo que da como resultado un modelo más ligero con una precisión similar.
Antes de empezar
Clona el repositorio e instala requirements.txt en un entorno Python>=3.8.0, incluyendo PyTorch>=1.8. Los modelos y los conjuntos de datos se descargan automáticamente desde la última versión de YOLOv5.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
Probar el rendimiento de referencia
Antes de la poda, establece un rendimiento de referencia para comparar. Este comando prueba YOLOv5x en COCO val2017 con un tamaño de imagen de 640 píxeles. yolov5x.pt
es el modelo más grande y preciso disponible. Otras opciones son yolov5s.pt
, yolov5m.pt
y yolov5l.pt
, o su propio punto de control del entrenamiento de un conjunto de datos personalizado ./weights/best.pt
. Para obtener detalles sobre todos los modelos disponibles, consulte el README tabla.
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --half
Salida:
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
Aplicar Poda a YOLOv5x (30% de Esparcidad)
Podemos aplicar el pruning al modelo utilizando el torch_utils.prune()
comando. Para probar un modelo podado, actualizamos val.py
para podar YOLOv5x a 0.3 de esparcimiento (30% de los pesos establecidos en cero):
Salida podada al 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/exp3
Análisis de Resultados
De los resultados, podemos observar:
- : Se alcanzó una dispersión del 30%: 30% de los parámetros de peso del modelo en
nn.Conv2d
las capas ahora son cero - El tiempo de inferencia permanece sin cambios: A pesar de la poda, la velocidad de procesamiento es esencialmente la misma
- Impacto mínimo en el rendimiento: El mAP disminuyó ligeramente de 0.507 a 0.489 (solo una reducción del 3.6%)
- Reducción del tamaño del modelo: El modelo podado requiere menos memoria para el almacenamiento
Esto demuestra que la poda puede reducir significativamente la complejidad del modelo con solo un impacto menor en el rendimiento, lo que la convierte en una técnica de optimización eficaz para la implementación en entornos con recursos limitados.
Ajuste Fino de Modelos Podados
Para obtener los mejores resultados, los modelos podados deben ajustarse después de la poda para recuperar la precisión. Esto se puede hacer mediante:
- Aplicando la poda con un nivel de esparcidad deseado
- Entrenamiento del modelo podado durante algunas épocas con una tasa de aprendizaje más baja
- Evaluación del modelo podado y ajustado en comparación con la línea base
Este proceso ayuda a que los parámetros restantes se adapten para compensar las conexiones eliminadas, a menudo recuperando la mayor parte o la totalidad de la precisión original.
Entornos Compatibles
Ultralytics proporciona una gama de entornos listos para usar, cada uno preinstalado con dependencias esenciales como CUDA, CUDNN, Python y PyTorch, para poner en marcha sus proyectos.
- Notebooks GPU gratuitos:
- Google Cloud: Guía de inicio rápido de GCP
- Amazon: Guía de inicio rápido de AWS
- Azure: Guía de inicio rápido de AzureML
- Docker: Guía de inicio rápido de Docker
Estado del Proyecto
Esta insignia indica que todas las pruebas de Integración Continua (CI) de YOLOv5 GitHub Actions están pasando exitosamente. Estas pruebas de CI verifican rigurosamente la funcionalidad y el rendimiento de YOLOv5 en varios aspectos clave: entrenamiento, validación, inferencia, exportación y benchmarks. Aseguran un funcionamiento consistente y confiable en macOS, Windows y Ubuntu, con pruebas realizadas cada 24 horas y con cada nuevo commit.