飞桨领航团AI达人创造营Day07 | 项目全流程实战:以安全帽检测为例
收藏
模型训练
1、paddlex下载
项目环境:Paddle 2.1.0
参考文档:https://gitee.com/paddlepaddle/PaddleX/tree/release%2F2.0-rc
!pip install paddlex==2.0rc
2、数据集准备
本项目使用的安全帽检测数据集已经按VOC格式进行标注,目录情况如下:
dataset/ ├── annotations/ ├── images/
而使用PaddleX的API,一键进行数据切分时,数据文件夹切分前后的状态如下:
dataset/ dataset/ ├── Annotations/ <-- ├── Annotations/ ├── JPEGImages/ ├── JPEGImages/ ├── labels.txt ├── test_list.txt ├── train_list.txt ├── val_list.txt
将训练集、验证集和测试集按照7:2:1的比例划分。 PaddleX中提供了简单易用的API,方便用户直接使用进行数据划分。下面这行代码正确执行的前提是,PaddleX的版本和Paddle匹配,要么都是2.0+,要么都是1.8.X。
!paddlex --split_dataset --format VOC --dataset_dir MyDataset --val_value 0.2 --test_value 0.1
3、模型训练
import paddlex as pdx from paddlex import transforms as T
# 定义训练和验证时的transforms # API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0-rc/paddlex/cv/transforms/operators.py train_transforms = T.Compose([ T.MixupImage(mixup_epoch=250), T.RandomDistort(), T.RandomExpand(im_padding_value=[123.675, 116.28, 103.53]), T.RandomCrop(), T.RandomHorizontalFlip(), T.BatchRandomResize( target_sizes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608], interp='RANDOM'), T.Normalize( mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) eval_transforms = T.Compose([ T.Resize( 608, interp='CUBIC'), T.Normalize( mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])
# 定义训练和验证所用的数据集 # API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0-rc/paddlex/cv/datasets/voc.py#L29 train_dataset = pdx.datasets.VOCDetection( data_dir='MyDataset', file_list='MyDataset/train_list.txt', label_list='MyDataset/labels.txt', transforms=train_transforms, shuffle=True) eval_dataset = pdx.datasets.VOCDetection( data_dir='MyDataset', file_list='MyDataset/val_list.txt', label_list='MyDataset/labels.txt', transforms=eval_transforms, shuffle=False)
# 初始化模型,并进行训练 # 可使用VisualDL查看训练指标,参考https://github.com/PaddlePaddle/PaddleX/tree/release/2.0-rc/tutorials/train#visualdl可视化训练指标 num_classes = len(train_dataset.labels) model = pdx.models.YOLOv3(num_classes=num_classes, backbone='MobileNetV3_ssld')
# API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0-rc/paddlex/cv/models/detector.py#L155 # 各参数介绍与调整说明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html model.train( num_epochs=270, train_dataset=train_dataset, train_batch_size=2, eval_dataset=eval_dataset, learning_rate=0.001 / 8, warmup_steps=1000, warmup_start_lr=0.0, save_interval_epochs=1, lr_decay_epochs=[216, 243], save_dir='output/yolov3_mobilenet')
4、模型预测
import glob import numpy as np import threading import time import random import os import base64 import cv2 import json import paddlex as pdx # 传入待预测图片 image_name = 'MyDataset/JPEGImages/hard_hat_workers1035.png' # 模型保存位置 model = pdx.load_model('output/yolov3_mobilenet/best_model') img = cv2.imread(image_name) result = model.predict(img) keep_results = [] areas = [] f = open('./output/yolov3_mobilenet/result.txt', 'a') count = 0 for dt in np.array(result): cname, bbox, score = dt['category'], dt['bbox'], dt['score'] if score < 0.5: continue keep_results.append(dt) # 检测到未佩戴安全帽的目标,计数加1 if cname == 'head': count += 1 f.write(str(dt) + '\n') f.write('\n') areas.append(bbox[2] * bbox[3]) areas = np.asarray(areas) sorted_idxs = np.argsort(-areas).tolist() keep_results = [keep_results[k] for k in sorted_idxs] if len(keep_results) > 0 else [] print(keep_results) print(count) f.write("未佩戴安全帽人员总数为: " + str(int(count))) f.close() pdx.visualize_detection( image_name, result, threshold=0.5, save_dir='./output/yolov3_mobilenet')
5、模型裁剪
模型裁剪可以更好地满足在端侧、移动端上部署场景下的性能需求,可以有效得降低模型的体积,以及计算量,加速预测性能。PaddleX集成了PaddleSlim的基于敏感度的通道裁剪算法,通过以下代码,可以在此前训练模型的基础上,加载并进行裁剪,重新开始训练。
# 加载模型 model = pdx.load_model('output/yolov3_mobilenet/best_model') # Step 1/3: 分析模型各层参数在不同的剪裁比例下的敏感度 # API说明:https://github.com/PaddlePaddle/PaddleX/blob/95c53dec89ab0f3769330fa445c6d9213986ca5f/paddlex/cv/models/base.py#L352 model.analyze_sensitivity( dataset=eval_dataset, batch_size=1, save_dir='output/yolov3_mobilenet/prune') # Step 2/3: 根据选择的FLOPs减小比例对模型进行剪裁 # API说明:https://github.com/PaddlePaddle/PaddleX/blob/95c53dec89ab0f3769330fa445c6d9213986ca5f/paddlex/cv/models/base.py#L394 model.prune(pruned_flops=.2) # Step 3/3: 对剪裁后的模型重新训练 # API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0-rc/paddlex/cv/models/detector.py#L154 # 各参数介绍与调整说明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html model.train( num_epochs=270, train_dataset=train_dataset, train_batch_size=8, eval_dataset=eval_dataset, learning_rate=0.001 / 8, warmup_steps=1000, warmup_start_lr=0.0, save_interval_epochs=5, lr_decay_epochs=[216, 243], pretrain_weights=None, save_dir='output/yolov3_mobilenet/prune')
0
收藏
请登录后评论
整挺好