从零开始在kitti数据集上训练yolov5

2024-03-06 12:20

本文主要是介绍从零开始在kitti数据集上训练yolov5,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0.准备工作

0.1 在kitti官网下载kitti数据集

KITTI官网:https://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=2d
只需要下载图片和标签
在这里插入图片描述
解压后应该有一个training和和testing文件夹,training文件夹下应该有一个image_2文件夹和一个label_2文件夹,分别对应训练集的图片和标签,图片和标签的名称是一一对应的,因此我们拿这部分图片和标签进行训练。

0.2 clone yolov5代码

Github官网:https://github.com/ultralytics/yolov5

git clone https://github.com/ultralytics/yolov5.git
conda create -n yolov5 python=3.8 -y
conda activate yolov5
cd yolov5
pip install -r requirements.txt

1.转换kitti数据集标签格式

在这里插入图片描述

1.1 kitti数据集标签

首先看kitti数据集的标签,每一行有15个属性:他们的含义如下:

  • [0] 目标类比别(type),共有8种类别,分别是CarVanTruckPedestrianPerson_sittingCyclistTramMiscDontCare。DontCare表示某些区域是有目标的,但是由于一些原因没有做标注,比如距离激光雷达过远。但实际算法可能会检测到该目标,但没有标注,这样会被当作false positive (FP)。这是不合理的。用DontCare标注后,评估时将会自动忽略这个区域的预测结果,相当于没有检测到目标,这样就不会增加FP的数量了。此外,在 2D 与 3D Detection Benchmark 中只针对 Car、Pedestrain、Cyclist 这三类。
  • [1] 截断程度(truncated),表示处于边缘目标的截断程度,取值范围为0~1,0表示没有截断,取值越大表示截断程度越大。处于边缘的目标可能只有部分出现在视野当中,这种情况被称为截断。
  • [2] 遮挡程度(occlude),取值为(0,1,2,3)。0表示完全可见,1表示小部分遮挡,2表示大部分遮挡,3表示未知(遮挡过大)。
  • [3] 观测角度(alpha),取值范围为(-pi, pi)。是在相机坐标系下,以相机原点为中心,相机原点到物体中心的连线为半径,将物体绕相机y轴旋转至相机z轴,此时物体方向与相机x轴的夹角。这相当于将物体中心旋转到正前方后,计算其与车身方向的夹角。
  • [4-7] 二维检测框(bbox),目标二维矩形框坐标,分别对应left、top、right、bottom,即左上(xy)和右下的坐标(xy)。
  • [8-10] 三维物体的尺寸(dimensions),分别对应高度、宽度、长度,以米为单位。
  • [11-13] 中心坐标(location),三维物体底部中心在相机坐标系下的位置坐标(x,y,z),单位为米。
  • [14] 旋转角(rotation_y),取值范围为(-pi, pi)。表示车体朝向,绕相机坐标系y轴的弧度值,即物体前进方向与相机坐标系x轴的夹角。rolation_y与alpha的关系为alpha=rotation_y - theta,theta为物体中心与车体前进方向上的夹角。alpha的效果是从正前方看目标行驶方向与车身方向的夹角,如果物体不在正前方,那么旋转物体或者坐标系使得能从正前方看到目标,旋转的角度为theta。

参考链接:https://blog.csdn.net/u011489887/article/details/126316851

我们需要的是目标类别和2d检测框。

1.2 yolo需要的标签(coco数据集格式)

在这里插入图片描述
包含5个属性

  • [0] 目标类别索引(因此一会还需要一个类别和索引对应表)
  • [1-2] 中心点坐标,x_center,y_center
  • [3-4] 检测框宽、高,width,height

需要注意的是:这里的方框坐标和宽高需要归一化,即需要除以图像的宽高,如图所示
在这里插入图片描述

1.3 转换代码

import glob
import random
import cv2
from tqdm import tqdmdic = {'Car': 0, 'Van': 1, 'Truck': 2, 'Tram': 3, 'Pedestrian': 4, 'Person_sitting': 4, 'Cyclist': 5, 'Misc': 6}def changeformat():img_path = 'PATH/TO/KITTI/training/image_2/*.png'      # 修改为自己的 KITTI数据集图像位置label_path = 'PATH/TO/KITTI/training/label_2/'         # 修改为自己的 KITTI数据集标签位置filename_list = glob.glob(img_path)save_path = 'PATH/TO/NEW/LABELS/'                      # 修改为自己的 标签另存的位置for img_name in tqdm(filename_list, desc='Processing'):image_name = img_name[-10: -4]   # 000000 图片的名字label_file = label_path + image_name + '.txt'     # 根据图像名称查找对应标签savelabel_path = save_path + image_name + '.txt'  # 标签另存的文件with open(label_file, 'r') as f:labels = f.readlines()img = cv2.imread(img_name)h, w, c = img.shapedw = 1.0 / wdh = 1.0 / h        # 方便一会归一化for label in labels:label = label.split(' ')classname = label[0]if classname not in dic: continue  # 我忽略了kitti数据集中的misc和dontcarex1, y1, x2, y2 = label[4: 8]x1 = eval(x1)y1 = eval(y1)x2 = eval(x2)y2 = eval(y2)# 归一化处理bx = (x1 + x2) / 2.0 * dwby = (y1 + y2) / 2.0 * dhbw = (x2 - x1) * dwbh = (y2 - y1) * dh# 这里定义数据保存的精度bx = round(bx, 6)by = round(by, 6)bw = round(bw, 6) bh = round(bh, 6)print('Done convert!')

2.划分数据集,准备训练

2.1 划分训练集和验证集

training文件夹共有7480张图片,按照训练集:验证集=8:2的比例进行划分。
代码如下:

def splitdataset():import randomrandom.seed(1234)label_path = 'PATH/TO/NEW/LABELS/'       # 这里修改为上一步保存的新标签的位置filename_list = glob.glob(label_path)num_file = len(filename_list)val = 0.2      # 验证集的比例try:val_file = open('PATH/TO/KITTI/val.txt', 'w', encoding='utf-8')    # 包含验证集的txt文件,修改为自己想要保存的位置train_file = open('PATH/TO/KITTI/train.txt', 'w', encoding='utf-8')  # 包含训练集的txt文件,修改为自己想要保存的位置for i in range(num_file):if random.random() < val:val_file.write(f'PATH/TO/KITTI/images/{i:06}.png\n')   # 修改为kitti数据集图片的位置,即txt文件里存的是图片的位置else:train_file.write(f'PATH/TO/KITTI/images/{i:06}.png\n')         finally:val_file.close()train_file.close()

2.2 准备配置文件

--datasets|--images          # 7480 images|--labels          # 7480 labels|--train.txt|--val.txt|--kitti.yaml|--yolov5s.yaml

修改coco.yaml文件为kitti.yaml

# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license
# COCO 2017 dataset http://cocodataset.org by Microsoft
# Example usage: python train.py --data coco.yaml
# parent
# ├── yolov5
# └── datasets
path: PATH/TO/KITTI/datasets     # 修改为包含图片和标签的父文件夹
train: train.txt # train images (relative to 'path') 
val: val.txt # val images (relative to 'path') nc: 7      # 修改为类别数量
# Classes
names:0: car1: van2: truck3: tram4: pedestrian5: cyclist6: misc

修改yolov5s.yaml文件,这里根据选用的模型修改对应的文件,只需要修改类别数即可。
在这里插入图片描述

3.clone代码,开始训练

根据选用的模型大小,在github下载对应的预训练权重。
然后开始训练,train.py的相关参数设置可以参考这篇文章https://blog.csdn.net/m0_56175815/article/details/131125861,以及官方网站https://docs.ultralytics.com/zh/yolov5/tutorials/tips_for_best_training_results/

主要需要设置的参数包括:cfg(上一步的kitti.yaml),data(上一步修改的yolov5.yaml),batch-size(-1表示自动计算batch,推荐使用),weights(预训练权重)
其余的是一些调参的超参数:epochs(训练周期),cos-lr(是否使用模拟余弦退火调整学习率),label-smoothing(标签平滑设置,一般取小于0.1的数)

python train.py --weights PATH/TO/pretrained_weight/yolov5s.pt \
--cfg PATH/TO/yolov5s.yaml \
--data PATH/TO/kitti.yaml \
--epochs 300 \
--batch-size -1 \
--name kitti \
--cos-lr \
--label-smoothing 0.05

训练完成后的结果如下:
在这里插入图片描述

这篇关于从零开始在kitti数据集上训练yolov5的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/780050

相关文章

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

Redis事务与数据持久化方式

《Redis事务与数据持久化方式》该文档主要介绍了Redis事务和持久化机制,事务通过将多个命令打包执行,而持久化则通过快照(RDB)和追加式文件(AOF)两种方式将内存数据保存到磁盘,以防止数据丢失... 目录一、Redis 事务1.1 事务本质1.2 数据库事务与redis事务1.2.1 数据库事务1.

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

更改docker默认数据目录的方法步骤

《更改docker默认数据目录的方法步骤》本文主要介绍了更改docker默认数据目录的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1.查看docker是否存在并停止该服务2.挂载镜像并安装rsync便于备份3.取消挂载备份和迁

不删数据还能合并磁盘? 让电脑C盘D盘合并并保留数据的技巧

《不删数据还能合并磁盘?让电脑C盘D盘合并并保留数据的技巧》在Windows操作系统中,合并C盘和D盘是一个相对复杂的任务,尤其是当你不希望删除其中的数据时,幸运的是,有几种方法可以实现这一目标且在... 在电脑生产时,制造商常为C盘分配较小的磁盘空间,以确保软件在运行过程中不会出现磁盘空间不足的问题。但在

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

Mybatis拦截器如何实现数据权限过滤

《Mybatis拦截器如何实现数据权限过滤》本文介绍了MyBatis拦截器的使用,通过实现Interceptor接口对SQL进行处理,实现数据权限过滤功能,通过在本地线程变量中存储数据权限相关信息,并... 目录背景基础知识MyBATis 拦截器介绍代码实战总结背景现在的项目负责人去年年底离职,导致前期规

Redis KEYS查询大批量数据替代方案

《RedisKEYS查询大批量数据替代方案》在使用Redis时,KEYS命令虽然简单直接,但其全表扫描的特性在处理大规模数据时会导致性能问题,甚至可能阻塞Redis服务,本文将介绍SCAN命令、有序... 目录前言KEYS命令问题背景替代方案1.使用 SCAN 命令2. 使用有序集合(Sorted Set)

SpringBoot整合Canal+RabbitMQ监听数据变更详解

《SpringBoot整合Canal+RabbitMQ监听数据变更详解》在现代分布式系统中,实时获取数据库的变更信息是一个常见的需求,本文将介绍SpringBoot如何通过整合Canal和Rabbit... 目录需求步骤环境搭建整合SpringBoot与Canal实现客户端Canal整合RabbitMQSp

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核