Прунинг и разреженность моделей в YOLOv5
📚 В этом руководстве объясняется, как применить обрезание к моделям YOLOv5 🚀 для создания более эффективных сетей с сохранением производительности.
Что такое обрезка модели?
Удаление незначащих параметров модели — это метод, используемый для уменьшения размера и сложности нейронных сетей путем удаления менее важных параметров (весов и связей). Этот процесс создает более эффективную модель с рядом преимуществ:
- Уменьшенный размер модели для упрощения развертывания на устройствах с ограниченными ресурсами
- Более высокая скорость инференса с минимальным влиянием на точность
- Снижение потребления памяти и энергии
- Повышена общая эффективность для приложений реального времени
Прунинг работает путем идентификации и удаления параметров, которые минимально влияют на производительность модели, в результате чего получается более легкая модель с аналогичной точностью.
Прежде чем начать
Клонируйте репозиторий и установите requirements.txt в окружении Python>=3.8.0, включая PyTorch>=1.8. Модели и наборы данных загружаются автоматически из последнего релиза YOLOv5.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
Тестирование базовой производительности
Перед прунингом установите базовый уровень производительности для сравнения. Эта команда тестирует YOLOv5x на COCO val2017 с размером изображения 640 пикселей. yolov5x.pt
это самая большая и точная из доступных моделей. Другие варианты: yolov5s.pt
, yolov5m.pt
и yolov5l.pt
, или вашу собственную контрольную точку после обучения пользовательскому набору данных ./weights/best.pt
. Подробную информацию обо всех доступных моделях см. в README таблица.
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --half
Вывод:
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 к YOLOv5x (30% Sparsity)
Мы можем применить прунинг к модели, используя torch_utils.prune()
команду. Чтобы протестировать обрезанную модель, мы обновляем val.py
чтобы урезать YOLOv5x до 0,3 разреженности (30% весов установлены в ноль):
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
Анализ результатов
Из результатов можно наблюдать:
- Достигнута разреженность 30%: 30% параметров весов модели в
nn.Conv2d
теперь слои обнулены - Время инференса остается неизменным: Несмотря на обрезку, скорость обработки практически не меняется
- Минимальное влияние на производительность: mAP незначительно снизился с 0,507 до 0,489 (снижение всего на 3,6%)
- Уменьшение размера модели: Для усеченной модели требуется меньше памяти для хранения
Это демонстрирует, что прунинг может значительно снизить сложность модели лишь с незначительным влиянием на производительность, что делает его эффективным методом оптимизации для развертывания в средах с ограниченными ресурсами.
Тонкая настройка урезанных моделей
Для достижения наилучших результатов обрезанные модели следует дообучать после обрезки для восстановления точности. Это можно сделать следующим образом:
- Применение pruning с желаемым уровнем sparsity
- Обучение усеченной модели в течение нескольких эпох с более низкой скоростью обучения
- Оценка точности усеченной модели по сравнению с базовой
Этот процесс помогает оставшимся параметрам адаптироваться, чтобы компенсировать удаленные соединения, часто восстанавливая большую часть или всю исходную точность.
Поддерживаемые среды
Ultralytics предоставляет ряд готовых к использованию сред, каждая из которых предварительно установлена с необходимыми зависимостями, такими как CUDA, CUDNN, Python и PyTorch, чтобы дать старт вашим проектам.
- Бесплатные блокноты GPU:
- Google Cloud: Краткое руководство по GCP
- Amazon: Краткое руководство по AWS
- Azure: Краткое руководство по AzureML
- Docker: Краткое руководство по Docker
Статус проекта
Этот значок указывает на то, что все тесты непрерывной интеграции (CI) YOLOv5 GitHub Actions успешно пройдены. Эти тесты CI тщательно проверяют функциональность и производительность YOLOv5 по различным ключевым аспектам: обучение, валидация, вывод, экспорт и бенчмарки. Они обеспечивают стабильную и надежную работу в macOS, Windows и Ubuntu, при этом тесты проводятся каждые 24 часа и при каждом новом коммите.