目标检测 | YOLOv5 训练自标注数据集实现迁移学习

Hi,大家好,我是源于花海。本文主要了解 YOLOv5 训练自标注数据集(自行车和摩托车两种图像)进行目标检测,实现迁移学习。YOLOv5 是一个非常流行的图像识别框架,这里介绍一下使用 YOLOv5 给使用 Labelme 标注自己的数据集进行训练和测试。


目录

一、YOLOv5 核心基础知识

1. YOLOv5 四种网络模型

2. 核心基础内容

二、YOLOv5 迁移学习过程

1. YOLOv5 框架的下载及结构介绍

2. 创建 YOLOv5 虚拟环境

3. 数据集准备

3.1 数据集下载

3.2 Labelme 数据标注

3.3 json 转 txt

3.4 数据集分割及其对应标签生成

4. 模型配置

4.1 修改数据集配置文件

4.2 修改模型配置文件

4.3 其他修改

5. 模型训练

6. 模型验证

7. 模型预测


一、YOLOv5 核心基础知识

可以参考大白的 深入浅出Yolo系列之Yolov5核心基础知识完整讲解-CSDN博客 这一文章进去详细学习 YOLOv5 相关知识,当然也包含 YOLO 的其他系列的知识。

1. YOLOv5 四种网络模型

  • YOLOv5s
  • YOLOv5m
  • YOLOv5l
  • YOLOv5x

YOLOv5 的四个 pt 格式权重模型:

YOLOv5 作者算法性能测试图:

Yolov5作者也是在COCO数据集上进行的测试COCO数据集的小目标占比)。

YOLOv5s 网络是 YOLOv5 系列中深度最小,特征图的宽度最小的网络(网络最小,速度最少,AP精度也最低)。但如果检测的以大目标为主,追求速度,倒也是个不错的选择。

后面的三种都是在此基础上不断加深、加宽网络AP精度也不断提升,但速度的消耗也在不断增加

2. 核心基础内容

YOLOv5 网络结构图:

我们可以采用 pt->onnx->netron 的折中方式,先使用 YOLOv5 代码中 models/export.py 脚本将 pt文件 转换为 onnx格式,再用 netron工具 打开,这样就可以看全网络的整体架构了。

​上图即 YOLOv5 的网络结构图,可以看出,还是分为输入端、Backbone、Neck、Prediction四个部分。

  • 输入端: Mosaic 数据增强、自适应锚框计算
  • Backbone: Focus 结构,CSP 结构
  • Neck: FPN + PAN 结构
  • Prediction: GIOU_Loss

二、YOLOv5 迁移学习过程

1. YOLOv5 框架的下载及结构介绍

官方介绍文档: YOLOv5官方文档 或者 YOLOv5-master 。

pycharm 里面大致是这样的结构

现在来对代码的整体目录做一个介绍

  • data:主要是存放一些超参数的配置文件(这些文件(yaml文件)是用来配置训练集和测试集还有验证集的路径的,其中还包括目标检测的种类数和种类的名称);还有一些官方提供测试的图片。如果是训练自己的数据集的话,那么就需要修改其中的 yaml 文件。但是自己的数据集不建议放在这个路径下面,而是建议把数据集放到 YOLOv5 项目的同级目录下面。
  • models:里面主要是一些网络构建的配置文件和函数,其中包含了该项目的四个不同的版本,分别为是s、m、l、x。从名字就可以看出,这几个版本的大小。他们的检测测度分别都是从快到慢,但是精确度分别是从低到高。这就是所谓的鱼和熊掌不可兼得。如果训练自己的数据集的话,就需要修改这里面相对应的 yaml 文件来训练自己模型。
  • utils:存放的是工具类的函数,里面有 loss 函数,metrics 函数,plots 函数等等。
  • weights:放置训练好的权重参数。
  • train.py:训练自己的数据集的函数。
  • test.py:测试训练的结果的函数。
  • detect.py:利用训练好的权重参数进行目标检测,可以进行图像、视频和摄像头的检测。
  • requirements.txt:这是一个文本文件,里面是使用 YOLOv5 项目的环境依赖包的一些版本,可以用该文本导入相应版本的包。

以上是 YOLOv5 项目代码的整体介绍。我们训练、验证、测试自己的数据集基本就是利用到如上代码。

2. 创建 YOLOv5 虚拟环境

这边建议使用 conda 创建一个新的虚拟环境。

(1)创建虚拟环境

conda create -n YOLOv5 python=3.9

(2)激活并进入虚拟环境

activate YOLOv5

(3)安装各软件包

 比如使用清华镜像源安装库:

pip install torch==2.1.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install torchvision==0.16.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
······

打开 requirements.txt 文件,里面写有 YOLOv5 运行所需要的各种软件包,输入以下命令到 pycharm 里的终端中运行即可:(我不太记得了,感觉是在 Command Prompt 里面运行的,但是 Windows PowerShell 也可以)

pip install -r requirements.txt

这个过程可快可慢,看网速,静静地等待吧。有几个包的安装可能会出问题,没关系,把报错信息在 CSDN / ChatGPT 上搜一搜都能找到解决办法!

(4)添加此虚拟环境到该项目中

3. 数据集准备

数据集格式:

数据集文件夹的树形结构:

├── BikeMotorcycle        数据集文件夹

        ├── PNGImages     所有图像(两种放一起,命名为(名称+)编号)

        ├── json                  所有图像对应的 json 文件(同上)

        ├── Annotations      由 json 文件转换的 txt 文件(同上)

        ├── images             分割后的数据集(子文件夹里两种放一起,命名同上)

                ├── train          训练集

                ├── val            验证集

                ├── test           测试集

        ├── labels               分割后的数据集对应的 txt 标签文件(同上)

                ├── train          训练集

                ├── val            验证集

                ├── test           测试集

3.1 数据集下载

本项目数据集是在以下链接中的图像分类里面的 VOC2005 车辆数据集(The PASCAL Visual Object Classes Challenge)中选取自行车和摩托车而得:图像处理及深度学习开源数据集大全(四万字呕心沥血整理)-CSDN博客 。

3.2 Labelme 数据标注

① Open Dir(选择并打开数据集图像的文件夹路径)

②③④ File —> Save Automatically —> Change Output Dir

  • Save Automatically:自动保存,减少麻烦
  • Change Output Dir:改变 json 文件输出路径

⑤ Create Rectangle(快捷键:Ctrl+R)(画矩形边界框)

3.3 json 转 txt

json_to_txt.py 代码如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Project : yolov5-master
@File    : json_to_txt.py
@IDE     : PyCharm
@Author  : 源于花海
@Date    : 2023/12/10 19:43
"""
import json
import osname2id = {'bike': 0, 'motorcycle': 1}  # 标签名称def convert(img_size, box):dw = 1. / (img_size[0])dh = 1. / (img_size[1])x = (box[0] + box[2]) / 2.0 - 1y = (box[1] + box[3]) / 2.0 - 1w = box[2] - box[0]h = box[3] - box[1]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, hdef decode_json(json_floder_path, json_name):txt_name = 'D:\\Python_demo\\neural_network\\yolov5-master\\BikeMotorcycle\\Annotations\\' + json_name[0:-5] + '.txt'# 存放txt的绝对路径txt_file = open(txt_name, 'w')json_path = os.path.join(json_floder_path, json_name)data = json.load(open(json_path, 'r', encoding='gb2312', errors='ignore'))img_w = data['imageWidth']img_h = data['imageHeight']for i in data['shapes']:label_name = i['label']if i['shape_type'] == 'rectangle':x1 = int(i['points'][0][0])y1 = int(i['points'][0][1])x2 = int(i['points'][1][0])y2 = int(i['points'][1][1])bb = (x1, y1, x2, y2)bbox = convert((img_w, img_h), bb)txt_file.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n')if __name__ == "__main__":json_floder_path = 'D:\\Python_demo\\neural_network\\yolov5-master\\BikeMotorcycle\\json'# 存放json的文件夹的绝对路径json_names = os.listdir(json_floder_path)for json_name in json_names:decode_json(json_floder_path, json_name)

3.4 数据集分割及其对应标签生成

split+labels.py 代码如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Project : yolov5-master
@File    : split+labels.py
@IDE     : PyCharm
@Author  : 源于花海
@Date    : 2023/12/10 19:29
"""
import shutil
import random
import os# 将图片和标注数据按比例切分为训练集、验证集和测试集
# 数据集路径
image_original_path = './BikeMotorcycle/PNGImages/'
label_original_path = './BikeMotorcycle/Annotations/'
# 训练集路径
train_image_path = './BikeMotorcycle/images/train/'
train_label_path = './BikeMotorcycle/labels/train/'
# 验证集路径
val_image_path = './BikeMotorcycle/images/val/'
val_label_path = './BikeMotorcycle/labels/val/'
# 测试集路径
test_image_path = './BikeMotorcycle/images/test/'
test_label_path = './BikeMotorcycle/labels/test/'# 数据集划分比例,训练集75%,验证集15%,测试集10%,按需修改
train_percent = 0.75
val_percent = 0.15
test_percent = 0.1# 检查文件夹是否存在
def mkdir():if not os.path.exists(train_image_path):os.makedirs(train_image_path)if not os.path.exists(train_label_path):os.makedirs(train_label_path)if not os.path.exists(val_image_path):os.makedirs(val_image_path)if not os.path.exists(val_label_path):os.makedirs(val_label_path)if not os.path.exists(test_image_path):os.makedirs(test_image_path)if not os.path.exists(test_label_path):os.makedirs(test_label_path)def main():mkdir()total_txt = os.listdir(label_original_path)num_txt = len(total_txt)list_all_txt = range(num_txt)  # 范围 range(0, num)num_train = int(num_txt * train_percent)num_val = int(num_txt * val_percent)num_test = num_txt - num_train - num_valtrain = random.sample(list_all_txt, num_train)# 在全部数据集中取出trainval_test = [i for i in list_all_txt if not i in train]# 再从val_test取出num_val个元素,val_test剩下的元素就是testval = random.sample(val_test, num_val)print("训练集数目:{}, 验证集数目:{},测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))for i in list_all_txt:name = total_txt[i][:-4]srcImage = image_original_path + name + '.png'srcLabel = label_original_path + name + '.txt'if i in train:dst_train_Image = train_image_path + name + '.png'dst_train_Label = train_label_path + name + '.txt'shutil.copyfile(srcImage, dst_train_Image)shutil.copyfile(srcLabel, dst_train_Label)elif i in val:dst_val_Image = val_image_path + name + '.png'dst_val_Label = val_label_path + name + '.txt'shutil.copyfile(srcImage, dst_val_Image)shutil.copyfile(srcLabel, dst_val_Label)else:dst_test_Image = test_image_path + name + '.png'dst_test_Label = test_label_path + name + '.txt'shutil.copyfile(srcImage, dst_test_Image)shutil.copyfile(srcLabel, dst_test_Label)if __name__ == '__main__':main()

4. 模型配置

模型配置其实就是一些预训练权重的准备,在 YOLOv5 中,主要是 .yaml 配置文件及一些 .py 文件的参数或路径修改。

4.1 修改数据集配置文件

在 data 目录下复制 VOC.yaml,并粘贴重命名为 BikeMotorcycle.yaml,打开进行修改。

  • path:项目当前的路径
  • train、val、test:对应的训练集、验证集、测试集的路径
  • nc:类别数
  • names:类别名

4.2 修改模型配置文件

在 models 目录下找到 yolov5s.yaml,将其复制一份,并重命名为 BikeMotorcycle.yaml,然后打开它,把 nc 改成数据集类别数。

4.3 其他修改

5. 模型训练

  • ① weights: r'yolov5s.pt'
  • ② cfg: r'models/BikeMotorcycle.yaml''
  • ③ data: r'data/BikeMotorcycle.yaml'
  • ④ epochs: 训练次数:10
  • ⑤ batch-size: 训练的批次:16

修改 train.py 文件上面的信息之后运行,开始训练:

训练结果对应 runs\train\exp 文件夹下:

result.png 结果如下:

由上图可以看出,本项目 YOLOv5 训练效果很好,准确率为 99.1% 

6. 模型验证

评估模型好坏就是在有标注的测试集或者验证集上进行模型效果的评估,在目标检测中最常使用的评估指标为 mAP。

  • ① weights: 训练好的模型的权重 r'runs\train\exp30\weights\best.pt'
  • ② data: r'data/animal_detection.yaml'

val.py 文件中指定数据集配置文件和训练结果模型,运行进行测试某一张图片或某个文件夹里的图片,直接 "右键+运行",或者在终端输入以下命令

python val.py --data data/BikeMotorcycle.yaml --weights runs\train\exp\weights\best.pt --augment

验证结果对应 runs\val\exp 文件夹下:

由上图可以看出,本项目 YOLOv5 验证效果很好,准确率同样接近 100%

7. 模型预测

模型推理和模型测试比较类似,主要区别是模型推理是对那些没有标注的数据集上进行推理,修改detect.py文件的要进行推理的图片和模型的路径:

  • ① weights: 训练好的模型的权重 r'runs\train\exp\weights\best.pt'
  • ② source: r'BikeMotorcycle\images\test'
  • ③ data: r'data/BikeMotorcycle.yaml'

 test.py 文件中指定数据集配置文件和训练结果模型,运行进行推理某一张图片或某个文件夹里的图片,直接 "右键+运行",或者在终端输入以下命令

python detect.py --weights runs\train\exp\weights\best.pt --source BikeMotorcycle\images\test

预测结果对应 runs\detect\exp 文件夹下:

 由上图可以看出,本项目 YOLOv5 预测效果很好,检测类别的准确度达到 100%

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

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

相关文章

一文详解动态 Schema

在数据库中,Schema 常有,而动态 Schema 不常有。 例如,SQL 数据库有预定义的 Schema,但这些 Schema 通常都不能修改,用户只有在创建时才能定义 Schema。Schema 的作用是告诉数据库使用者所希望的表结构,确保…

网络安全红队常用的攻击方法及路径

一、信息收集 收集的内容包括目标系统的组织架构、IT资产、敏感信息泄露、供应商信息等各个方面,通过对收集的信息进行梳理,定位到安全薄弱点,从而实施下一步的攻击行为。 域名收集 1.备案查询 天眼查爱企查官方ICP备案查询 通过以上三个…

Java BIO、NIO、AIO、Netty知识详解(值得珍藏)

1. 什么是IO Java中I/O是以流为基础进行数据的输入输出的,所有数据被串行化(所谓串行化就是数据要按顺序进行输入输出)写入输出流。简单来说就是java通过io流方式和外部设备进行交互。 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领…

YOLOv5改进 | Neck篇 | 利用Damo-YOLO的RepGFPN改进特征融合层

一、本文介绍 本文给大家带来的改进机制是Damo-YOLO的RepGFPN(重参数化泛化特征金字塔网络),利用其优化YOLOv5的Neck部分,可以在不影响计算量的同时大幅度涨点(亲测在小目标和大目标检测的数据集上效果均表现良好涨点幅度超级高!)。RepGFPN不同于以往提出的改进模块,其…

【数据库】聊聊常见的索引优化-上

数据库对于现有互联网应用来说,其实是非常重要的后端存储组件,而大多数系统故障都是由于存储所导致的,而数据库是重中之重,所以为了比较好掌握SQL的基本优化手段,打算用两篇文章从基本的联合索引优化、group by/order …

【Web开发】会话管理与无 Cookie 环境下的实现策略

🍎个人博客:个人主页 🏆个人专栏: Web开发 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 问题: 思路: 方法: 结语 我的其他博客 前言 在当今Web应用程序中,会话…

Go (一) 基础部分5 -- 单元测试,协程(goroutine),管道(channel)

一、单元测试 Go自带一个轻量级的"测试框架testing"和自带的"go test"命令来实现单元测试和性能测试。 1.确保每个函数时可运行,并且运行结果是正确的。 2.确保写出来的代码性能是好的。 3.单元测试能及时的发现程序设计或实现的逻辑错误&#…

程序员副业之无人直播助眠

介绍和概览 大家好,我是小黑,本文给大家介绍一个比较轻松简单的副业,无人直播助眠副业。 这个项目的核心就是通过直播一些助眠素材来赚钱。比如你可以放一些舒缓的雨声之类的,吸引观众进来。然后,咱们可以挂个小程序…

spring boot 集成邮件发送功能

一、首先到QQ邮箱申请开启POP3、SMTP协议 二、安装依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><dependency><groupId>org.springframew…

探索生成式AI:自动化、问题解决与创新力

目录 自动化和效率&#xff1a;生成式AI的颠覆力量 解谜大师生成式AI&#xff1a;如何理解和解决问题 创新与创造力的启迪&#xff1a;生成式AI的无限潜能 自动化和效率&#xff1a;生成式AI的颠覆力量 1. 神奇的代码生成器&#xff1a;生成式AI可以帮助开发人员像魔术一样快…

TemporalKit的纯手动安装

最近在用本地SD安装temporalkit插件 本地安装插件最常见的问题就是&#xff0c;GitCommandError:… 原因就是&#xff0c;没有科学上网&#xff0c;而且即使搭了ladder&#xff0c;在SD的“从网址上安装”或是“插件安装”都不行&#xff0c;都不行&#xff01;&#xff01;&am…

【JAVA】OPENGL+TIFF格式图片,不同阈值旋转效果

有些科学研究领域会用到一些TIFF格式图片&#xff0c;由于是多张图片相互渐变&#xff0c;看起来比较有意思&#xff1a; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.*;/*** 可以自已定义日志打印格式…

窗体控件(表格和控制器)

DataGridView 控件 DataGridView控件是C#中的一个Windows Forms控件&#xff0c;用于在应用程序中显示和编辑表格形式的数据。 先拖出四个label控件和四个TextBox控件和一个ComboBox和一个Button按钮&#xff0c;下面是一个DataGridView控件 准备一个Student类 namespace _窗…

八大算法排序@堆排序(C语言版本)

目录 堆排序大堆排序概念算法思想建堆建堆核心算法建堆的代码 排序代码实现 小堆排序代码实现时间复杂度空间复杂度 特性总结 堆排序 堆排序借用的是堆的特性来实现排序功能的。大堆需要满足父节点大于子节点&#xff0c;因此堆顶是整个数组中的最大元素。小堆则相反&#xff0…

码农的周末日常---2024/1/6

上周总结 按照规划进行开发&#xff0c;处事不惊&#xff0c;稳稳前行 2024.1.6 天气晴 温度适宜 AM 睡觉前不建议做决定是真的&#xff0c;昨天想着睡到中午&#xff0c;今天九点多醒了&#xff0c;得了&#xff0c;不想睡了 日常三连吧&#xff0c;…

【mars3d】new mars3d.layer.GeoJsonLayer({实现多孔面遮罩mask: true,

【mars3d】new mars3d.layer.GeoJsonLayer({实现多孔面遮罩 官网测试示例&#xff1a; 1.功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 测试代码&#xff1a; export function showDraw(isFlyTo) { removeLayer() const geoJsonLayer new mars3d.layer.GeoJsonLaye…

神经网络-搭建小实战和Sequential的使用

CIFAR-10 model structure 通过已知参数&#xff08;高、宽、dilation1、kernel_size&#xff09;推断stride和padding的大小 网络 import torch from torch import nnclass Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 nn.Conv2d(in_chan…

TSConfig 配置(tsconfig.json)

详细总结一下TSConfig 的相关配置项。个人笔记&#xff0c;仅供参考&#xff0c;欢迎批评指正&#xff01; 另外&#xff0c;如果想了解更多ts相关知识&#xff0c;可以参考我的其他笔记&#xff1a; vue3ts开发干货笔记ts相关笔记&#xff08;基础必看&#xff09;ts相关笔记…

LeetCode-有效的字母异位词(242)

题目描述&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 思路&#xff1a; 这题还是比较简单的&#xff0c;首先将两个字符…