飞桨领航团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
收藏
请登录后评论
整挺好