【动手学PaddleX】谁都能学会的基于迁移学习的老人摔倒目标检测

本项目使用PaddleX搭建目标检测模块,在一个精选的数据集上进行初步训练,并在另一个老年人跌倒检测的数据集上进行参数微调,实现了迁移学习的目标检测项目。

1.项目介绍

迁移学习是非常有用的方法,在实际生活中由于场景多样,环境复杂,一些场景复杂或者人体姿态不一的数据集较少,因此直接训练的难度较大,且效果往往不如迁移学习。

2.项目流程

  1. 我们使用两个数据集,一个是精选的精选的跌倒检测数据集Fall detection Dataset,一个是老年人跌倒数据集,在界面左侧数据集标签页可看到。
  2. 检查标签名称,看是否满足我们的需要,如不满足则需要处理数据集将标签统一和格式化,并检查文件夹名称是否符合我们的规范。
  3. 本项目使用的格式是PascalVOC格式

具体流程如下:首先部署开发环境,安装PaddleX;切割数据集、构建数据读取器;搭建PPYolo模型;使用其他场景数据集训练、验证模型;使用跌倒数据集进行微调并验证;使用微调后的模型进行推理。

3.项目环境

本项目的实验环境如下表所示

名称版本功能说明
AIStudioBML Codelab代码实现的基础平台与环境
PaddlePaddle2.3.2在新建项目时选择,2.4.0会出现bug
python3.7默认选择
PaddleX2.1.0PaddleX套件用于搭建模型

4.预训练阶段

利用跌倒检测数据集Fall detection Dataset得到预训练模型,为后续模型的微调做准备。

4.1 环境安装

PaddleX集成飞桨智能视觉领域图像分类、目标检测、语义分割、实例分割任务能力,将深度学习开发全流程从数据准备、模型训练与优化到多端部署端到端打通,并提供统一任务API接口。无需分别安装不同套件,以低代码的形式即可快速完成飞桨全流程开发。

本项目主要采用PaddleX来实现目标预测项目。

In [ ]

# 安装相关包,在持久化文件夹下安装
!pip install pycocotools -t /home/aistudio/external-libraries
!pip install cython -t /home/aistudio/external-libraries
!pip install pyproject -t /home/aistudio/external-libraries
!pip install --user --upgrade pyarrow==11.0.0# 此处如果使用持久化路径会找不到paddlex命令
!pip install paddlex -i https://pypi.tuna.tsinghua.edu.cn/simple

4.2 数据集预处理

数据集存放在data文件夹下,解压相关数据集并处理成我们想要的格式。

In [ ]

# 解压数据集文件
!unzip -oq /home/aistudio/data/data182907/Fall_Dataset.zip -d Fall_Dataset/
!unzip -oq /home/aistudio/data/data94809/pp_fall.zip -d pp_fall/

此时数据集已解压到相关目录,但不符合PAscalVOC格式

  • Annotations 进行detection 任务时的 标签文件,xml文件形式
  • ImageSets 存放数据集的分割文件,比如train,val,test
  • JPEGImages 存放 .jpg格式的图片文件
  • SegmentationClass 存放 按照class 分割的图片
  • SegmentationObject 存放 按照 object 分割的图片

In [ ]

# 对文件结构做处理
%cd /home/aistudio/Fall_Dataset/Fall_Dataset!mv /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets/Main/test.txt /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets
!mv /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets/Main/train.txt /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets
!mv /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets/Main/trainval.txt /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets
!mv /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets/Main/val.txt /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets
!mv /home/aistudio/Fall_Dataset/Fall_Dataset/train.txt /home/aistudio/Fall_Dataset/Fall_Dataset/train_list.txt
!mv /home/aistudio/Fall_Dataset/Fall_Dataset/trainval.txt /home/aistudio/Fall_Dataset/Fall_Dataset/val_list.txt
!rm -rf /home/aistudio/Fall_Dataset/Fall_Dataset/ImageSets/Main!mv /home/aistudio/Fall_Dataset/Fall_Dataset/label_list.txt /home/aistudio/Fall_Dataset/Fall_Dataset/labels.txt

In [ ]

# 检查一下数据集里的objectfrom xml.etree import ElementTree as ET
from collections import defaultdict
import sys
import ossys.path.append('/home/aistudio/external-libraries')path = '/home/aistudio/Fall_Dataset/Fall_Dataset/Annotations/'
path_pp = '/home/aistudio/pp_fall/Annotations/'name_dict = defaultdict(set)
for filename in os.listdir(path_pp):if not os.path.isdir(path_pp + filename):tree = ET.parse(path_pp + filename)root = tree.getroot()ets = root.findall('object')for et in ets:name = et.findall('name')[0].textname_dict[name].add(filename)# 如果有问题可以删除节点# if name.text == 'XX':      # 修改标签#     name.text='XXX'# elif name.text == 'YY':      # 删除无关标签#     root.remove(et)print(name_dict.keys())

In [ ]

!mv /home/aistudio/pp_fall/images /home/aistudio/pp_fall/JPEGImages# 使用paddlex切分数据集,根据37比例划分出验证集和训练集
# 注意,要确定符合PascalVOC格式才会成功裁剪
# Fall_Dataset无须此命令,可以直接用分割好的数据集
!paddlex --split_dataset --format VOC --dataset_dir /home/aistudio/pp_fall/ --val_value 0.3

我们得到了最终的数据集结构,Annotation和JPEGImages分别存放标签和图像文件;labels.txt存放标签名称;而train_list.txt和val_list.txt分别存放训练集和验证集,这两个txt在第4步搭建数据读取器中作为参数传入。

4.3 数据预处理

定义一些数据增强方法,可以使模型的泛化能力更强而不会过拟合。

数据增强方法有多种,具体选择哪几个需要根据任务特点、数据特征来确定。例如:图像竖直翻转之后会和实际严重不符,增加模型的学习难度而对实际表现没有任何帮助。

In [ ]

# 导入python库,如果遇到pyarrow报错,可以试试重启内核
import numpy as np
import paddlex as pdx
from paddlex import transforms as T

In [ ]

# 设置数据增强的方式
# API说明:https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/apis/transforms/transforms.md
train_transforms = T.Compose([T.MixupImage(),            # mixup增强T.RandomDistort(),         # 随机调整亮度、对比度、饱和度、色调T.RandomExpand(),          # 随机扩张图像T.RandomCrop(),            # 随机裁剪图像T.RandomHorizontalFlip(),  # 随机水平翻转T.BatchRandomResize(       # 训练批次图像的输入大小target_sizes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608]),  # 为了确保大目标和小目标都可以有效学习,我们设置了不通的输入大小T.Normalize()              # 对图像进行标准化
])eval_transforms = T.Compose([T.Resize(target_size=480), # 设置验证时输入大小,此处选择了480,平衡了目标大小和计算时间T.Normalize()              # 对图像进行标准化
])

4.4 构建数据读取器

利用准备好的数据构建之后要用的数据集变量,准备了训练集和验证集,所以定义了两个。

In [ ]

%cd
# 定义数据集
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.VOCDetection(data_dir='pp_fall',                   # 数据集存放的路径file_list='pp_fall/train_list.txt',   # 训练集划分的txt文件label_list='pp_fall/labels.txt',      # 训练数据的类别文件transforms=train_transforms,            # 定义数据转换shuffle=True)                           # 随机打乱数据集# 验证数据集的构建和上面训练的一样
eval_dataset = pdx.datasets.VOCDetection(data_dir='pp_fall',                   # 数据集存放的路径 file_list='pp_fall/val_list.txt',     # 训练集划分的txt文件label_list='pp_fall/labels.txt',      # 训练数据的类别文件transforms=eval_transforms,             # 定义数据转换shuffle=False)                          # 验证数据集没有必要打乱

4.5 构建模型

我们这里使用了PPYOLOv2,参考了其它的项目。

PPYOLOv2版本在COCO 2017 test-dev上的精度为49.5%;在640x640的输入尺寸下,FPS达到68.9FPS。PP-YOLOv2在同等速度下,精度超越YOLOv5。满足我们的需求,因此选择PPYOLOv2。

In [ ]

# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标,参考https://github.com/PaddlePaddle/PaddleX/tree/release/2.0.0/tutorials/train#visualdl可视化训练指标# 确定目标类别数
num_classes = len(train_dataset.labels)# 定义PPYOLOv2模型
model = pdx.det.PPYOLOv2(num_classes=num_classes) # 我们只需要修改类别数即可

接下来可以开始训练了,使用PaddleX快速完成训练,具体参数使用请参考单元格,

In [ ]

# API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0.0/paddlex/cv/models/detector.py
# 各参数介绍与调整说明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html
model.train(num_epochs=5,               # 训练轮次train_dataset=train_dataset,  # 导入训练数据集读取器eval_dataset=eval_dataset,    # 导入验证数据集读取器train_batch_size=16,          # 批大小,在32G显存下可以用16,bs越大训练效果越好learning_rate=0.00025,        # 根据批大小和模型复杂度选择合理的学习率warmup_steps=500,             # 预热步数,学习率会逐渐增大。预热是为了训练过程能够更加稳定warmup_start_lr=0.0,          # 预热起始学习率save_interval_epochs=1,       # 每1轮次都保存一次,有验证数据时会进行评估log_interval_steps=50,        # 每迭代50次打印一次日志 lr_decay_epochs=[35, 65],     # step学习率衰减save_dir='output/pp_fall_PPYOLOv2',   # 保存路径use_vdl=False,                # 用visuadl进行可视化训练记录,此处没有使用# resume_checkpoint='output/PPYOLOv2/epoch_4/',  # 重新训练时请把此处改为上一代的地址,并把下一行的pretrain_weights设为None# pretrain_weights=None,pretrain_weights='COCO',      # 预训练权重
)

5.模型微调

接下来读取预训练相关模型进行微调,以达到良好的效果。

同样设置数据增强以及数据读取器。

In [ ]

# 设置数据增强的方式
# API说明:https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/apis/transforms/transforms.md
train_transforms = T.Compose([T.MixupImage(),                                                     # mixup增强T.RandomDistort(),                                                  # 随机调整亮度、对比度、饱和度、色调T.RandomExpand(),                                                   # 随机扩张图像T.RandomCrop(),                                                     # 随机裁剪图像T.RandomHorizontalFlip(),                                           # 随机水平翻转T.BatchRandomResize(                                                # 训练批次图像的输入大小target_sizes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608]),  # 为了确保大目标和小目标都可以有效学习,我们设置了不通的输入大小T.Normalize()                                                       # 对图像进行标准化
])eval_transforms = T.Compose([T.Resize(target_size=480),                                          # 设置验证时输入大小,此处选择了480,平衡了目标大小和计算时间T.Normalize()                                                       # 对图像进行标准化
])

In [ ]

%cd
# 定义数据集
# 定义训练和验证所用的数据集
# API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0.0/paddlex/cv/datasets/voc.py
train_dataset = pdx.datasets.VOCDetection(data_dir='Fall_Dataset/Fall_Dataset',                   # 数据集存放的路径file_list='Fall_Dataset/Fall_Dataset/train_list.txt',   # 训练集划分的txt文件label_list='Fall_Dataset/Fall_Dataset/labels.txt',      # 训练数据的类别文件transforms=train_transforms,                     # 定义数据转换shuffle=True)                                    # 随机打乱数据集# 验证数据集的构建和上面训练的一样
eval_dataset = pdx.datasets.VOCDetection(data_dir='Fall_Dataset/Fall_Dataset',                   # 数据集存放的路径        file_list='Fall_Dataset/Fall_Dataset/val_list.txt',     # 验证集划分的txt文件label_list='Fall_Dataset/Fall_Dataset/labels.txt',      # 验证数据的类别文件transforms=eval_transforms,                      # 定义数据转换shuffle=False)                                   # 验证数据集没有必要打乱

微调之前可以看一下模型的初始效果。

In [ ]

# 先使用预训练模型进行测试
# 载入模型
model = pdx.load_model("output/pp_fall_PPYOLOv2/best_model/")
# 进行验证
model.evaluate(eval_dataset, batch_size=1)

接下来进行模型微调的训练。

此处warmup_steps=68最低设置为68.

In [ ]

# API说明:https://github.com/PaddlePaddle/PaddleX/blob/release/2.0.0/paddlex/cv/models/detector.py
# 各参数介绍与调整说明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html
model.train(num_epochs=6,                 # 训练轮次train_dataset=train_dataset,  # 训练数据eval_dataset=eval_dataset,    # 验证数据train_batch_size=16,          # 批大小,在32G显存下可以用16,但是不稳定,容易内存溢出0learning_rate=0.0002,        # 学习率warmup_steps=68,             # 预热步数,学习率会逐渐增大warmup_start_lr=0.0,          # 预热起始学习率save_interval_epochs=1,       # 每1轮次都保存一次,有验证数据时会进行评估log_interval_steps=50,        # 每迭代50次打印一次日志 lr_decay_epochs=[4],     # step学习率衰减 35, 65save_dir='output/Finish_PPYOLOv2',   # 保存路径use_vdl=False,                # 用visuadl进行可视化训练记录,此处没有使用pretrain_weights='output/pp_fall_PPYOLOv2/best_model/model.pdparams',      # 预训练权重
)

之后载入模型,并且在验证集上进行验证。

In [ ]

# 载入模型
model = pdx.load_model("output/Finish_PPYOLOv2/best_model/")
# 进行验证
model.evaluate(eval_dataset, batch_size=1)

6.模型预测

我们已经完成了模型预训练、微调、模型载入,接下来会进行模型预测。在实际生产中,部署完模型文件后,可以使用下面代码进行推理。

In [ ]

%cd
# 导入必要的库
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 = 'test/电力高架线路_31_31.jpg'
image_name = 'test/test-2.png'# 预测模型加载
model = pdx.load_model('output/Finish_PPYOLOv2/best_model')# 读取图片
img = cv2.imread(image_name)
# 预测图片并获得结果
result = model.predict(img)# 解析预测结果,并保存到txt中
keep_results = []
areas = []
# 获取txt文件
f = open('result.txt', 'a')# 计数
count = 0
for dt in np.array(result):      # 遍历结果, 并将结果写入到result.txtcname, bbox, score = dt['category'], dt['bbox'], dt['score']     # 获取目标框的种类、坐标、置信度if score < 0.5:   # 根据置信度过滤掉置信度较低的目标框continuekeep_results.append(dt)    # 将置信度符合的目标框保存下来count += 1f.write(str(dt) + '\n')    # 写入txt中f.write('\n')print(count)
f.write("the total number is :" + str(int(count)))
f.close()# 可视化保存
pdx.det.visualize(image_name, result, threshold=0.5, save_dir='./output/PPYOLOv2')

生成的结果图片保存至./output/PPYOLOv2文件夹下,可进行查看。

7.总结提高

本项目基于PaddleX进行了目标检测的开发,且用了迁移学习以达到良好的效果,从自身体会上来说PaddleX确实是个挺好的框架,能够快速的开发想要的模型,强烈推荐!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[大师C语言(第十三篇)]C语言排序算法比较与技术详解

引言 排序算法是计算机科学中最基础且重要的内容之一。在数据处理、数据库索引、搜索算法等多个领域都有广泛的应用。C语言作为一种高效、底层的编程语言&#xff0c;被广泛用于实现各种排序算法。本文将深入探讨几种常用的排序算法&#xff0c;包括冒泡排序、选择排序和插入排…

Brewer Science将在CS Mantech进行展示

在风景如画的亚利桑那州图森市举办的CS Mantech盛会上&#xff08;2024年5月20日至23日&#xff09;&#xff0c;杰出化合物半导体材料企业Brewer Science&#xff0c;将带来一场名为“化合物半导体制造的创新材料解决方案”的演讲盛宴。这一演讲&#xff0c;定于五月二十一日星…

Fastjson 的 JSONObject 类

在fastjson中 JSONObject类有许多常用的方法用于操作 JSON 对象&#xff0c;下面我们一起了解一下。 1、put(String key, Object value) 用途&#xff1a;在 JSONObject 对象中设置键值对。如果键已存在&#xff0c;则更新其值。示例&#xff1a; JSONObject jsonObject ne…

【Java面试】五、MySQL篇(下)

文章目录 1、事务的特性2、并发事务问题3、事务的隔离级别4、undo log 和 redo log4.1 底层结构4.2 redo log4.3 undo log 5、MVCC5.1 隐式字段5.2 undo log 版本链5.3 ReadView5.4 ReadView的匹配规则实现事务隔离 6、MySQL的主从同步原理7、分库分表7.1 垂直分库7.2 垂直分表…

stm32启动文件

启动文件由汇编编写&#xff0c;是系统上电复位后第一个执行的程序。主要做了以下工作&#xff1a; 初始化堆栈指针SP_initial_sp 初始化PC指针Reset_Handler 初始化中断向量表 配置系统时钟 调用C库函数_main初始化用户堆栈&#xff0c;从而最终调用main函数去到C的世界 …

js内置对象和对象方法

内置对象&#xff08;Math&#xff09; Math.PI 表示圆周率 console.log(Math.PI); // 3.141592653589793 Math.abs()可以用来计算一个数的绝对值 console.log(Math.abs(-3)); // 3 Math.ceil() 可以用来对一个数向上取整&#xff0c;小数位只要有值&#xff0c;就自动进1…

linux下使用cmake-gui编译WXQT

一.编译环境 操作系统&#xff1a;Ubuntu 22.04.3 LTS wxWidgets源码&#xff1a;wxWidgets-3.1.5 编译工具&#xff1a;CMake-gui qt版本&#xff1a;5.13.2 二.编译步骤 1.将源码解压。 2.打开CMake-gui&#xff0c;并设置好源码目录和构建目录 3.点击configure 会弹出…

图解操作系统学习笔记

1、一些系统命令 学习图解操作系统的时候,其中提供了一些查看系统状态的命令,这里做一下笔记,记录一下。 1、strace 查看和记录一个进程的系统调用和信号传递的详细过程 # 查看和记录一个进程的系统调用和信号传递的详细过程 strace -p <pid> # 读取某个命令的系统…

C++模板使用

文章目录 目录 文章目录 前言 一、交换函数(泛型编程) 二、函数模板 2.1 函数模板概念 2.2函数模板格式 2.3使用方法 2.4 函数模板的原理 2.4.1库中的swap 2.5 函数模板的实例化 2.6 模板参数的匹配原则 三、类模板 3.1 类模板的定义格式 3.2类模板声明和定义分离 前言 C语言阶…

前端面试题日常练-day29 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末。 1. 在Vue中&#xff0c;以下哪个选项用于监听用户的输入事件&#xff1f; a) v-on:input b) v-model c) v-bind d) v-show 2. Vue中&#xff0c;以下哪个选项用于为异步操作提供更好的错误处理机…

数据仓库——分层原理

目录 一、什么是数据仓库 二、数仓建模的意义&#xff0c;为什么要对数据仓库分层&#xff1f; 三、ETL 四、技术架构 五、数仓分层架构 数仓逻辑分层 1、数据引入层&#xff08;ODS&#xff0c;Operational Data Store&#xff0c;又称数据基础层&#xff09;&#xff…

解决 WooCommerce 的分析报表失效问题

今天明月的一个境外电商客户反应网站的 WooCommerce 分析报表已经十多天没有更新了&#xff0c;明明每天都有订单交易可分析报表里的数据依旧是十多天前的&#xff0c;好像更新完全停滞了似的。明月也及时的查看了后台的所有设置&#xff0c;确认没有任何问题&#xff0c;WooCo…

机器学习:在Python中sklearn库的使用,纯干货!12个小时的整理!

无监督学习是在没有标签的数据上训练的。其主要目的可能包括聚类、降维、生成模型等。 以下是 6 个重要的无监督学习算法&#xff0c;这些算法都可以通过使用sklearn&#xff08;Scikit-learn&#xff09;库在Python中很好地处理&#xff1a; 目录 K-Means 聚类 层次聚类 …

Android刮刮卡自定义控件

效果图 刮刮卡自定义控件 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import …

类和对象03

六、继承 我们发现&#xff0c;定义这些类时&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性。 这个时候我们就可以考虑利用继承的技术&#xff0c;减少重复代码 6.1 继承的基础语法 例如我们看到很多网站中, 都有公共的头部&#xff0c;公共的底…

vscode配置cc++环境要点和难点常见报错和解决方案

在VSCode中配置C/C++环境,你可以按照以下步骤进行: 下载并安装VSCode: 访问VSCode的官方网站,下载适用于你操作系统的VSCode安装包。 双击下载的安装包,按照提示进行安装。 安装C/C++扩展: 打开VSCode,点击左侧边栏的“Extensions”图标(或使用快捷键Ctrl+Shift+X)…

TypeScript 类

1. 基本用法 在 TypeScript 中&#xff0c;可以使用 class 关键字来定义类&#xff0c;然后通过 new 关键字来创建类的实例。例如&#xff1a; class Person {name: string;age: number;constructor(name: string, age: number) {this.name name;this.age age;}greet() {co…

乡村振兴的乡村人才引进与培养:引进和培养乡村人才,激发乡村发展活力,为乡村振兴提供人才保障

目录 一、引言 二、乡村人才引进与培养的重要性 &#xff08;一&#xff09;人才是乡村振兴的核心动力 &#xff08;二&#xff09;人才是乡村文化传承的载体 &#xff08;三&#xff09;人才是乡村社会治理的基石 三、乡村人才引进与培养的现状 &#xff08;一&#xf…

备战秋招c++ 【持续更新】

T1 牛牛的快递 原题链接&#xff1a;牛牛的快递_牛客题霸_牛客网 (nowcoder.com) 题目类型&#xff1a;模拟 审题&确定思路&#xff1a; 1、超过1kg和不足1kg有两种不同收费方案 ---- 起步价问题 2、超出部分不足1kg的按1kg计算 ----- 向上取整 3、向上取整的实现思路…

一文掌握Java中的CyclicBarrier、CountDownLatch和Semaphore

1.CountDownLatch 1.1 介绍和用途 CountDownLatch 是一个同步助手类&#xff0c;在完成一组正在其他线程中执行的操作之前&#xff0c;它允许一个或多个线程一直等待。 1.2 工作原理 它通过一个计数器来实现&#xff0c;我们初始化 CountDownLatch 对象时指定计数器的值&am…