Перейти к содержанию

Прунинг и разреженность моделей в 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% весов установлены в ноль):

Скриншот, показывающий код для обрезки YOLOv5x до 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%)
  • Уменьшение размера модели: Для усеченной модели требуется меньше памяти для хранения

Это демонстрирует, что прунинг может значительно снизить сложность модели лишь с незначительным влиянием на производительность, что делает его эффективным методом оптимизации для развертывания в средах с ограниченными ресурсами.

Тонкая настройка урезанных моделей

Для достижения наилучших результатов обрезанные модели следует дообучать после обрезки для восстановления точности. Это можно сделать следующим образом:

  1. Применение pruning с желаемым уровнем sparsity
  2. Обучение усеченной модели в течение нескольких эпох с более низкой скоростью обучения
  3. Оценка точности усеченной модели по сравнению с базовой

Этот процесс помогает оставшимся параметрам адаптироваться, чтобы компенсировать удаленные соединения, часто восстанавливая большую часть или всю исходную точность.

Поддерживаемые среды

Ultralytics предоставляет ряд готовых к использованию сред, каждая из которых предварительно установлена с необходимыми зависимостями, такими как CUDA, CUDNN, Python и PyTorch, чтобы дать старт вашим проектам.

Статус проекта

YOLOv5 CI

Этот значок указывает на то, что все тесты непрерывной интеграции (CI) YOLOv5 GitHub Actions успешно пройдены. Эти тесты CI тщательно проверяют функциональность и производительность YOLOv5 по различным ключевым аспектам: обучение, валидация, вывод, экспорт и бенчмарки. Они обеспечивают стабильную и надежную работу в macOS, Windows и Ubuntu, при этом тесты проводятся каждые 24 часа и при каждом новом коммите.



📅 Создано 1 год назад ✏️ Обновлено 2 месяца назад

Комментарии