Yolov7训练自己的数据集和ONNX/TRT部署

Yolov7训练自己的数据集和ONNX/Trt部署

一、环境配置

1.1 项目下载

项目原地址:GitHub - WongKinYiu/yolov7: Implementation of paper - YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors

  • 打开终端,输入以下命令将YOLOv7项目源码下载到本地:
git clone https://github.com/WongKinYiu/yolov7.git
# 进入yolov7的文件夹中
cd yolov7 

1.2 环境配置

# 提取自己的项目所需的安装包和版本(针对于已经有环境的项目进行移植,如果第一次弄忽略该步骤)
pip freeze > requirements.txt
# pip批量安装requirements.txt文件中包含的组件依赖
pip install -r requirements.txt# conda批量导出包含环境中所有组件的requirements.txt文件
conda list -e > requirements.txt
# conda批量安装requirements.txt文件中包含的组件依赖
conda install --yes --file requirements.txt

【这里发给出我自己用的代码版本,也可以直接使用官网给出的。缺什么后面自己在配置】

1.3 Docker 使用yolov7【优点是稳定的运行环境,如果是修改yolov7框架的不建议使用】【只是给出官网教程】

# 设置docker环境,确保docker和nvidia-docker的安装,创建启动docker容器
# create the docker container, you can change the share memory size if you have more.
nvidia-docker run --name yolov7 -it -v your_coco_path/:/coco/ -v your_code_path/:/yolov7 --shm-size=64g nvcr.io/nvidia/pytorch:21.08-py3# apt install required packages
# 安装依赖 在Docker容器内部执行以下命令来安装必要的Python包:
apt update
apt install -y zip htop screen libgl1-mesa-glx
# pip install required packages
pip install seaborn thop# go to code folder
cd /yolov7

二、数据准备

2.1 数据集搜寻

🐞高效搜寻数据集的宝藏平台:遇见数据集整合搜索🐞

🔗 https://www.selectdataset.com/

为什么选择遇见数据集?—— 集成搜索的核心优势
  1. 一站式资源聚合
    平台将 Kaggle、UCI、Google Dataset Search 等数十个主流数据集平台的资源整合于一体,无需在多个网站间切换,输入关键词即可同步获取多源结果,大幅提升检索效率。

  2. 智能关联与跳转
    搜索结果直接展示各平台的数据集链接,支持一键跳转至原始页面。例如搜索 “医学影像数据集”,可同时呈现 Kaggle 的公开数据集、UCI 的医学数据库及相关学术机构的资源入口,避免重复筛选。

  3. 精准分类与筛选
    提供领域标签(计算机视觉 / 自然语言处理 / 金融等)、数据格式(CSV/JSON/ 图像)、许可类型(开源 / 学术使用)等多维筛选条件,帮助用户快速定位符合需求的数据集。

2.2 数据标注 [lableimg和CVAT]

2.2.1 常用的Lableimg

使用命令行安装

pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple# 安装完成之后输入下面命令即可启动
labelimg

安装命令行成功图:
在这里插入图片描述

view里面有个auto save mode 点击之后就可以自动保存标签
## 常用快捷键:
A:切换到上一张图片
D:切换到下一张图片
W:调出标注十字架
del :删除标注框

在这里插入图片描述

标注报错问题解决

libpng warning: iCCP: known incorrect sRGB profile
libpng warning: iCCP: known incorrect sRGB profile
Traceback (most recent call last):File "C:\Users\Jorya\.conda\envs\yolov8\Lib\site-packages\libs\canvas.py", line 530, in paintEventp.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height())
TypeError: arguments did not match any overloaded call:drawLine(self, l: QLineF): argument 1 has unexpected type 'float'drawLine(self, line: QLine): argument 1 has unexpected type 'float'drawLine(self, x1: int, y1: int, x2: int, y2: int): argument 1 has unexpected type 'float'drawLine(self, p1: QPoint, p2: QPoint): argument 1 has unexpected type 'float'drawLine(self, p1: Union[QPointF, QPoint], p2: Union[QPointF, QPoint]): argument 1 has unexpected type 'float'

解决方案

  • 这个错误是由于 PyQt5 的drawLine方法需要整数参数,而代码中传入了浮点数导致的。在 Python 3 中,除法运算默认返回浮点数,而 PyQt5 的绘图函数要求坐标点为整数类型。
# 你需要修改canvas.py文件中第 530 行的代码,将浮点数坐标转换为整数。
# 打开文件C:\Users\Jorya\.conda\envs\yolov8\Lib\site-packages\libs\canvas.py,找到第 530 行:
原代码(错误行):
p.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height())
修改后:
p.drawLine(int(self.prev_point.x()), 0, int(self.prev_point.x()), self.pixmap.height())# 文件中第531  行的代码,将浮点数坐标转换为整数。
原代码(错误行):
p.drawLine(0, self.prev_point.y(), self.pixmap.width(), self.prev_point.y())
修改后:
p.drawLine(0, int(self.prev_point.y()), self.pixmap.width(), int(self.prev_point.y()))# 文件中第 526 行的代码,将浮点数坐标转换为整数。
原代码(错误行):
p.drawRect(left_top.x(), left_top.y(), rect_width, rect_height)
修改后:
p.drawRect(int(left_top.x()), int(left_top.y()), int(rect_width), int(rect_height))
  • 标注完整之后会有两个主要的文件夹,一个是图片文件夹另外一个是标签文件夹
    在这里插入图片描述

2.2.2 私有化部署和协同CVAT

官网地址

2.3 数据划分

针对图片和标签都在一个文件夹中

-*- coding: utf-8 -*-
import os
import random
import shutil
from tqdm import tqdm
import re
# 其中数据集和标签都在一个文件夹中,通过读取后缀进行替换
"""
最终划分成yolo可训练数据集格式:
|——images|-test|-train|-valid
|——labels|-test|-train|-valid
|——test.txt
|——train.txt
|——val.txt
## 遇到的yolov7训练问题,已经把预训练模型给下载下来了,进行train训练的时候。
## 一直提示git问题:subprocess.CalledProcessError: Command 'git tag' returned non-zero exit status 128.
## 解决方法:使用git拉取yolov7框架,在进行训练
# nohup python   train.py  --batch 48 --epochs 150 --cfg cfg/deploy/yolov7.yaml --weights yolov7.pt --device 0,1,2 > train.log 2>&1 &
"""
# 数据集文件夹路径
data_dir = "datasets/to/your/path"
# 创建一个空列表来存储有效图片和标签的路径
valid_images = []
valid_labels = []  
# 遍历 data 文件夹下的所有文件
for file_name in os.listdir(data_dir):# 获取文件的完整路径file_path = os.path.join(data_dir, file_name)# 获取文件的扩展名ext = os.path.splitext(file_name)[-1].lower()if ext.lower()  in ['.jpg', '.png' ,'.jpeg']:  # 处理图片文件# 根据扩展名替换成对应的 label 文件名label_name = file_name.replace(ext, ".txt")label_path = os.path.join(data_dir, label_name)# 判断 label 是否存在if not os.path.exists(label_path):# 删除图片os.remove(file_path)print("Deleted:", file_path)else:# 将图片路径添加到列表中valid_images.append(file_path)# 将 label 路径添加到列表中valid_labels.append(label_path)
# 确保每个标签都有对应的图片
valid_labels = [label for label in valid_labels if os.path.exists(label)]
# 创建目标目录结构
base_dir = "newdatasets/to/your/path"
for split in ["train", "valid", "test"]:os.makedirs(os.path.join(base_dir, "images", split), exist_ok=True)os.makedirs(os.path.join(base_dir, "labels", split), exist_ok=True)
# 打开三个txt文件用于存储分配的路径
train_txt = open(os.path.join(base_dir, "train.txt"), "w")
valid_txt = open(os.path.join(base_dir, "val.txt"), "w")
test_txt = open(os.path.join(base_dir, "test.txt"), "w")
# 初始化计数器
train_count = 0
valid_count = 0
test_count = 0
# 遍历每个有效图片路径
for i in tqdm(range(len(valid_images))):image_path = valid_images[i]label_path = re.sub(r'\.(jpg|jpeg|png)$', '.txt', image_path, flags=re.IGNORECASE)# 随机生成一个概率r = random.random()# 判断图片和标签应该移动到哪个文件夹 (train:valid:test = 7:2:1)if r < 0.1:# 移动到 test 文件夹destination = "test"image_destination = os.path.join(base_dir, "images", destination, os.path.basename(image_path))test_txt.write(f"{image_destination}\n")  # 写入到 test.txttest_count += 1elif r < 0.2:# 移动到 valid 文件夹destination = "valid"image_destination = os.path.join(base_dir, "images", destination, os.path.basename(image_path))valid_txt.write(f"{image_destination}\n")  # 写入到 valid.txtvalid_count += 1else:# 移动到 train 文件夹destination = "train"image_destination = os.path.join(base_dir, "images", destination, os.path.basename(image_path))train_txt.write(f"{image_destination}\n")  # 写入到 train.txttrain_count += 1# 生成目标文件夹中 images 和 labels 的路径image_destination_path = os.path.join(base_dir, "images", destination, os.path.basename(image_path))label_destination_path = os.path.join(base_dir, "labels", destination, os.path.basename(label_path))# 移动图片到目标文件夹shutil.move(image_path, image_destination_path)# 移动标签到目标文件夹if os.path.exists(label_path):shutil.move(label_path, label_destination_path)
# 关闭txt文件
train_txt.close()
valid_txt.close()
test_txt.close()
# 输出有效图片和标签的数量
print(f"有效图片数: {len(valid_images)}")
print(f"有效标签数: {len(valid_labels)}")
# 输出 train, valid, test 集合中的图片数量
print(f"训练集图片数: {train_count}")
print(f"验证集图片数: {valid_count}")
print(f"测试集图片数: {test_count}")

三、模型训练

3.1 创建yaml文件

创建一个hat.yaml文件在yolov7文件夹中的data文件夹中
在这里插入图片描述

3.2 模型训练代码和参数解释【单卡训练和多卡训练】

单卡训练:

# train p5 models
python train.py --workers 8 --device 0 --batch-size 32 --data data/hat.yaml --img 640 640 --cfg cfg/training/yolov7.yaml --weights '' --name yolov7 --hyp data/hyp.scratch.p5.yaml# train p6 models
python train_aux.py --workers 8 --device 0 --batch-size 16 --data data/hat.yaml --img 1280 1280 --cfg cfg/training/yolov7-w6.yaml --weights '' --name yolov7-w6 --hyp data/hyp.scratch.p6.yaml

多卡训练

# train p5 models
python -m torch.distributed.launch --nproc_per_node 4 --master_port 9527 train.py --workers 8 --device 0,1,2,3 --sync-bn --batch-size 128 --data data/hat.yaml --img 640 640 --cfg cfg/training/yolov7.yaml --weights '' --name yolov7 --hyp data/hyp.scratch.p5.yaml# train p6 models
python -m torch.distributed.launch --nproc_per_node 8 --master_port 9527 train_aux.py --workers 8 --device 0,1,2,3,4,5,6,7 --sync-bn --batch-size 128 --data data/hat.yaml --img 1280 1280 --cfg cfg/training/yolov7-w6.yaml --weights '' --name yolov7-w6 --hyp data/hyp.scratch.p6.yaml

3.3 模型验证

# 得到的模型进行单张验证
python detect.py --weights best.pt --conf 0.25 --img-size 640 --source inference/images/horses.jpg
# 得到的模型进行文件夹中的图片验证
python detect.py --weights best.pt --conf 0.25 --img-size 640 --source inference/images/

四、部署ONNX和TRT模式的代码

4.1 模型导出

wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt
python export.py --weights ./yolov7-tiny.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640
git clone https://github.com/Linaom1214/tensorrt-python.git
python ./tensorrt-python/export.py -o yolov7-tiny.onnx -e yolov7-tiny-nms.trt -p fp16

4.2 ONNX模型使用代码

import sys
import torch
print(f"Python version: {sys.version}, {sys.version_info} ")
print(f"Pytorch version: {torch.__version__} ")
# Inference for ONNX model
import cv2
cuda = True
w = "/content/yolov7/yolov7-tiny.onnx"
img = cv2.imread('/content/yolov7/inference/images/horses.jpg')
import cv2
import time
import requests
import random
import numpy as np
import onnxruntime as ort
from PIL import Image
from pathlib import Path
from collections import OrderedDict,namedtuple
providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] if cuda else ['CPUExecutionProvider']
session = ort.InferenceSession(w, providers=providers)
def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleup=True, stride=32):# Resize and pad image while meeting stride-multiple constraintsshape = im.shape[:2]  # current shape [height, width]if isinstance(new_shape, int):new_shape = (new_shape, new_shape)# Scale ratio (new / old)r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])if not scaleup:  # only scale down, do not scale up (for better val mAP)r = min(r, 1.0)# Compute paddingnew_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh paddingif auto:  # minimum rectangledw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh paddingdw /= 2  # divide padding into 2 sidesdh /= 2if shape[::-1] != new_unpad:  # resizeim = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))left, right = int(round(dw - 0.1)), int(round(dw + 0.1))im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add borderreturn im, r, (dw, dh)
names = ['hat']
colors = {name:[random.randint(0, 255) for _ in range(3)] for i,name in enumerate(names)}
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
image = img.copy()
image, ratio, dwdh = letterbox(image, auto=False)
image = image.transpose((2, 0, 1))
image = np.expand_dims(image, 0)
image = np.ascontiguousarray(image)
im = image.astype(np.float32)
im /= 255
im.shape
outname = [i.name for i in session.get_outputs()]
outname
inname = [i.name for i in session.get_inputs()]
inname
inp = {inname[0]:im}
# ONNX inference
outputs = session.run(outname, inp)[0]
outputs
ori_images = [img.copy()]
for i,(batch_id,x0,y0,x1,y1,cls_id,score) in enumerate(outputs):image = ori_images[int(batch_id)]box = np.array([x0,y0,x1,y1])box -= np.array(dwdh*2)box /= ratiobox = box.round().astype(np.int32).tolist()cls_id = int(cls_id)score = round(float(score),3)name = names[cls_id]color = colors[name]name += ' '+str(score)cv2.rectangle(image,box[:2],box[2:],color,2)cv2.putText(image,name,(box[0], box[1] - 2),cv2.FONT_HERSHEY_SIMPLEX,0.75,[225, 255, 255],thickness=2)  
Image.fromarray(ori_images[0])

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

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

相关文章

Python - 数据分析三剑客之NumPy

在Python中&#xff0c;NumPy、Pandas和Matplotlib是进行数据分析和数据可视化的三个核心库。它们各自有不同的功能&#xff0c;但经常一起使用来处理和分析数据。 1、NumPy NumPy&#xff08;Numerical Python&#xff09;是一个用于科学计算的库&#xff0c;提供了高性能的…

百度文库智能PPT月访问量超3400万,用户规模翻倍增长

6月27日&#xff0c;极光旗下月狐数据发布《2025年智能PPT行业市场研究报告》。报告显示&#xff0c;智能PPT市场整体增速年同比超50%&#xff0c;市场玩家成倍激增。其中&#xff0c;百度文库智能PPT月访问量超3400万、位列全球第一&#xff0c;市场份额在中国位于断崖式领先。…

远眺科技工业园区数字孪生方案,如何实现智能管理升级?

面对工业园区日益复杂的能耗管控、环境监测、安全运维需求&#xff0c;传统管理模式已经难以为继。而数字孪生技术&#xff0c;正好成为解决上述问题的关键“解药”。本文将以远眺工业园区数字孪生项目为例&#xff0c;为您剖析数字孪生技术如何解决数据孤岛、响应滞后等痛点。…

成都芯谷金融中心文化科技园:打造区域科技活力

在成渝地区双城经济圈建设加速推进的背景下&#xff0c;成都芯谷金融中心文化科技园正以"科技文化金融"的融合创新模式&#xff0c;重塑区域产业生态&#xff0c;成为驱动城市高质量发展的活力源泉。这座总建筑面积达45万平方米的产城综合体&#xff0c;不仅承载着双…

Claude Code 全面指南:从安装到高效开发的实用教程

在 AI 助手逐渐成为开发者标配的今天&#xff0c;Claude Code 作为 Anthropic 推出的一款智能编程工具&#xff0c;凭借其强大的自然语言交互和自动化能力&#xff0c;正迅速改变着软件开发的方式。本文将详细介绍 Claude Code 的功能、安装配置、使用方法及安全与成本管理&…

在Flutter中生成App Bundle并上架Google Play

Ran tool 要在Flutter中生成App Bundle并上架Google Play&#xff0c;请按照以下步骤操作&#xff1a; 1. 准备签名密钥 首先需要创建一个密钥库用于签名&#xff1a; keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias …

kubernetes pod调度基础

目录 Replication Controller 和 ReplicaSet 标签与标签选择器 无状态应用管理Deployment 有状态应用管理StatefulSet 守护进程集DaemonSet Replication Controller 和 ReplicaSet RC用来确保Pod副本数达到期望值,这样可以确保一个或多七个同类Pod总是可用的 如果存在的P…

Vue 3 响应式核心源码详解(基于 @vue/reactivity)

&#x1f9ec; Vue 3 响应式核心源码详解&#xff08;基于 vue/reactivity&#xff09; ⚙️ 整理不易&#xff0c;记得点赞、收藏、关注&#xff0c;揭开 Vue 响应式的神秘面纱&#xff01; &#x1f9ed; 一、源码结构总览&#xff08;relevant files&#xff09; Vue 的响应…

编写shell脚本扫描工具,扫描服务器开放了哪些端口(再尝试用python编写一个)

先将需要扫描的服务器的端口显示出来&#xff0c;然后再显示哪些ip地址对应的服务器的哪些端口已开放或未开放 下面这个shell脚本可以同时扫描多个ip对应的多个服务器的多个端口是否开放&#xff1a; 以下是运行结果&#xff1a; nc 和 nmap 扫描别人的机器开放了哪些端口 ne…

java JNDI高版本绕过 工具介绍 自动化bypass

JNDI高版本rce失效问题 原因&#xff1a; 主要还是协议控制高版本的一般都会关闭如rmi&#xff0c;ldap等协议远程加载的类 RMI限制&#xff1a; com.sun.jndi.rmi.object.trustURLCodebase、com.sun.jndi.cosnaming.object.trustURLCodebase的默认值变为false&#xff0c;即…

JavaWeb笔记02

三、数据库设计 1_简介 1.数据库设计设计什么&#xff1f; 有哪些表 表里有哪些字段 表和表之间是什么关系 2.表关系有哪几种&#xff1f; 一对一 一对多&#xff08;多对一&#xff09; 多对多 2_多表关系实现 表关系之一对多 一对多 (多对一): 如&#xff1a;部门表和员…

Junit_注解_枚举

文章目录 一&#xff1a;Junit单元测试测试分类&#xff1a;Junit的使用Before_After 二&#xff1a;注解什么是注解文档相关的注解IDEA中的javadoc使用&#xff1a;JDK内置的3个注解自定义注解 元注解RetentionTargetRepeatableDocumented&#xff08;用的很少&#xff09;Inh…

将N8N配置为服务【ubuntu】

docker模式不在此讨论。这里讨论的是node安装为n8n后&#xff0c;如何安装为服务&#xff1a; 安装NODE&#xff08;略&#xff09; 安装N8N 一个命令解决&#xff1a; npm install n8n -g 安装服务 vi /etc/systemd/system/n8n.service内容如下 [Unit] Descriptionn8…

Java后端调用外部接口标准流程详解

在Java后端开发中&#xff0c;调用外部HTTP接口&#xff08;如第三方平台API、云服务、微服务等&#xff09;是非常常见的需求。实现这个功能通常遵循一套标准的流程&#xff1a; 1. 准备DTO类&#xff08;数据传输对象&#xff09; 作用&#xff1a; DTO&#xff08;Data Tra…

星火燎原 数智新生 —— 《GB/T 45341—2025》 × AI大模型 × 全域PaaS创新,领码SPARK打造行业数字化转型新范式

【摘要】 数字中国新征程&#xff0c;标准引航数智化。面对企业数字蝶变的关键关口&#xff0c;《GB/T 45341—2025 数字化转型管理 参考架构》引领行业规范发展。爱分析最新数据显示&#xff0c;中国iPaaS市场规模持续高增长&#xff0c;印证PaaS已成为企业数字化基石。 AI大…

25-7-1 论文学习(1)- Fractal Generative Models 何恺明大佬的论文

分形生成模型 Tianhong Li1 Qinyi Sun1 Lijie Fan2 Kaiming He1 摘要 模块化是计算机科学的基石&#xff0c;它将复杂函数抽象为原子构建块。在本文中&#xff0c;我们通过将生成模型抽象为原子生成模块&#xff0c;引入了新的模块化层次。类似于数学中的分形&#xff0c;我…

如何读取运行jar中引用jar中的文件

1.问题发现 项目中有个common包资源文件&#xff0c;然后springboot项目引用了common&#xff0c;那么我们要怎么读取这个资源了。这里需要考虑三个场景&#xff0c;idea运行时、common jar独立运行时、springboot引用common后运行时。 2.问题解决 2.1.idea运行时 Protection…

【学习方法】框架质疑学习法:破解专业学习的“知识厚度”困境

今天博主给大家分享一个&#xff0c;我自己发明了一个比较高效的学习方法,名叫“框架质疑学习法” 本文提出的框架质疑学习法&#xff08;Framework Questioning Learning Method&#xff09;为本文作者&#xff0c;也就是我&#xff0c;董翔首次提出。 在软件专业的学习中&a…

spring-ai 1.0.0 学习(十七)——MCP Client

之前学过了工具调用&#xff08;spring-ai 1.0.0 学习&#xff08;十二&#xff09;——工具调用_springai 1.0 如何判断调用哪一个tool工具-CSDN博客&#xff09;&#xff0c;今天来看一下MCP MCP是什么 MCP全称是模型上下文协议&#xff0c;有点绕&#xff0c;通俗点理解&a…

Git 运行.sh文件

1.在项目文件中右击 Open Git Bash here 显示&#xff08;base&#xff09;环境 2.激活conda环境 3.复制.sh文件的相对路径 4.将路径复制到git终端 先输入sh和空格&#xff0c;然后右击后选paste&#xff0c;不要直接ctrl v 5.开始运行