首页 飞桨领航团 帖子详情
飞桨领航团AI达人创造营Day07 | 项目全流程实战:以安全帽检测为例
收藏
快速回复
飞桨领航团 文章AI达人创造营 589 1
飞桨领航团AI达人创造营Day07 | 项目全流程实战:以安全帽检测为例
收藏
快速回复
飞桨领航团 文章AI达人创造营 589 1

模型训练

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
收藏
回复
全部评论(1)
时间顺序
SuperAI*
#2 回复于2021-08

整挺好

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户