# yolov5_modified-deepsort-state_prediction **Repository Path**: yang-yifan_first/yolo_research ## Basic Information - **Project Name**: yolov5_modified-deepsort-state_prediction - **Description**: 该仓库主要做了两件事: 1.对yolov5做了各种模块及训练策略的调整及优化。 2.添加了deepsort跟踪功能和卡尔曼滤波预测功能。 - **Primary Language**: Python - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2023-02-28 - **Last Updated**: 2024-12-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ![输入图片说明](b64fcc28215be54c0d4b166c452395a8.jpg) # ========================= # # ========================= # 数据集 # ========================= # # ========================= # 一、训练自己的数据集Bdd100k 1.Bdd100k数据集介绍 该数据集为加州大学伯克利分校发布的 BDD100K 数据集,该数据集为迄今规模最大、最多样的自动驾驶数据集之一。 数据集中的视频是从美国各地收集的,涵盖不同时间、不同天气条件(包括晴天、阴天和雨天,以及白天和晚上的不同时间)和驾驶场景。 可以进行2D目标检测,实例分割以及车道线检测。 其中: 目标检测分为:公共汽车、交通灯、交通标志、人、自行车、卡车、摩托车、汽车、火车和乘车人等 100000 张图片上标注 2D 边界框。 实例分割:被用于探索具有像素级和丰富实例级注释,相关图像超过 10000 张;引擎区域是从 10 万张图片中学习复杂的可驾驶决策; 车道标记:是在 10 万张行车指南图片上的多种车道标注。 2.从官网下载数据集 1>训练数据集格式:在data目录下分别创建labels,JPEGimages目录 2>运行data目录下的Bdd2yolo.py文件,会在下载的Bdd100k标签(json格式)文件夹里面转换成yolo格式(txt)的标签文件, 将yolo格式的标签文件(txt)复制到labels文件夹下。 3>将下载的数据集原图放在JPEGimages文件夹下,并将生成的txt标签也复制到此文件夹下。 4>运行data目录下的split.py文件,会生成ImageSets文件夹,并在其子目录Main文件夹下生成训练需要用到的训练集,测试集以及验证集的txt文档。 5>在Bdd.yaml文件里修改对应的参数。 6>在train.py文件里修改对应参数。 # ========================= # # ========================= # 优化策略 # ========================= # # ========================= # 一、在 **loss** 中添加 **Optimal Transport Assignment** 模块 1.首先将loss_OTA中的代码复制到loss.py文件中。 2.如需训练,train.py文件中设置OTA = True即可。相应改动在源码中有标记。 如需验证,val.py文件中设置OTA = True。 3.在data/hyps超参文件下设置fl_gamma > 0打开focal loss。 3.1 focal loss调参经验 *一般对于多分类任务使用focal loss *alpha控制类别不平衡的;gamma控制难易样本的 *alpha越大,recal越高,precision越小;一二分类为背景,当alpha为1时,全是正样本,此时recall为100%,presicion会降低,当alpha为0时,同理相反。 *gamma和alpha互相牵制。gamma负责降低简单样本的损失值, 以解决加总后负样本loss值很大 alpha调和正负样本的不平均,如果设置0.25, 那么就表示负样本为0.75, 对应公式 1-alpha *一般来讲,label越不平衡,gamma项越大 *gamma越大hard case的权重会越大。 二、IOU <1>借鉴focalloss函数的思想改进IOU及其他IOU的变种 思想:损失函数由cla_loss,obj_loss,box_loss三部分组成。 现有回归loss的问题:没有直接优化需要优化的参数。也就是说有很多低质量的样本贡献了大部分梯度,限制了框的回归。 (低质量样本回归的anchors与gt的iou较小,梯度占比较大,回归的难度较大) focal-iou:平衡高质量样本与低质量样本对loss的贡献,给高质量样本(iou大)大权重,低质量样本(iou小)小权重。 (就像我们高考,既然做不了满分,就把大部分时间和精力用在难度较小和适中的题目上,小部分时间用来做难度较大的题目,把该得的分都拿到。) 如何区分低质量与高质量样本。主要思想,可参考x**0.5的图像。 具体代码在bbox_iou中将focal设置为True即可,一般gamma设置为0.5。 <2>yolov5源码中给出了GIou,DIou,CIou,我们再添加SIou,EIou,WIou以及alphaIou. 具体代码在utils下的iou_plus.py文件夹下,我们把bbox_iou函数替换掉源码中的bbox_iou部分即可。 三、借鉴于v7的思想添加辅助训练头 **辅助头(Aux head)** 指使用网络中间层进行损失计算来辅助网络训练(深度监督:监督网络不同深度特征) 对于精度可能会有小幅度的提升。 四、网络结构的改进 轻量化模块:DWConv、ghostConv、ghostC3等 涨点模块(不一定,需要根据自己的数据集去实验验证):C2f、注意力机制、GFPN、Bifpn、ASFF等 一般来讲网络的轻量化,params(参数量)和gflops(模型前向推理计算量)会下降,但同时也会带来精度的损失; 而精度的增加也会带来参数两和gflops的增加。 当然也不一定,针对不同的数据集还是要做具体的实验去验证。 五、加入小目标nwd 在loss.py下ComputeLoss类中。通过控制iou_ratio参数来使用nwd,iou_ratio越小nwd权重越大。 # ==================================== # # ==================================== # 记录一下训练过程以往的知识点和遇到的问题 # ==================================== # # ==================================== # > loss是指预测结果和真是结果之间的差距,是模型拟合程度的一个指标。 * accuracy是指模型的预测结果和真是结果之间的匹配度。 * 通常来讲,loss越小,accuracy越高。除非过拟合和欠拟合。 * loss越小,说明模型的鲁棒性越高。 * 损失函数与精确度没有严格意义上的正比或反比,最后的参考指标以精确率为主,loss为辅。 > 对于val_loss先下降后上升或不下降只上升的问题。 * 大概率是陷入了局部最优,可以调小一些学习率。 > yolo正/负样本分配规则: * 1.将feature划分为S*S个网格,每个网格有三个anchors * 2.通过计算方式(如最大IOU,宽高比等)计算每个anchors与GT的值,规定大于或小于阈值的anchors为正样本或负样本。 * 3.计算该anchors落于哪一个网格内,则该网格就负责预测目标。 > 关闭烦人的wandb * loggers\wandb\wandb_utils.py中添加wandb = None * loggers\__init__.py中一样添加wandb = None * 同时注释相关import wandb代码 # ========================= # # ========================= # 模型剪枝 # ========================= # # ========================= # 一、首先进行稀疏化训练,运行train_sparity.py > 为什么要进行稀疏化训练? * 因为普通的BN层的gamma系数是呈正态分布的,0附近的值非常少,不适合剪枝。在反向传播时采用L1正则化对gamma系数进行 较小,整体向零附近移动。可视化为图一向图二。 ![图一](20210525003400496.png) ![图二](20210525005321346.png) > 稀疏化训练train_sparity.py正常训练对train.py文件的一些重要改动。 * 加入稀疏化训练的代码以及显示bn权重的代码 * 混合精度变为FP32。具体在Optimize功能上体现 -> scaler变量。 * 打印日志方面有一些变化,会打印出bn权重。具体在utils/loggers/__init__.py文件下。 二、对稀疏化训练后的模型进行剪枝,运行prune.py 根据bn层的gamma权重对模型剪枝。 1.首先run,对稀疏化训练剪枝前的模型进行验证推理,保存验证推理结果。 2.接下来run_prune,对模型剪枝。 * 在pruned_yaml字典中输入自己模型的backbone和head。 * 在pruned_common.py文件中**加入自己需要被剪枝的模块**。 目前对Conv,DWConv卷积模块不用进行输入,因为在yolo.py内定义输入通道=输出通道, 被剪枝掉的通道不会对输入输出的通道数造成影响。 * 注意事项: 1.yolov5会自动采用混合精度,这里改用fp32 2.fuse会将conv和bn层进行融合,再训练和保存时不要fuse 3.在prune调试的时候,遇到一个问题,记录一下。 在网络的第十三层,原本应该是c2f的剪枝层,但为了调试用的是c3的剪枝层,所以一直报错。原因是在原网络c2f模块的位置生成的mask与c3对不上。 # ========================= # # ========================= # 可视化 # ========================= # # ========================= # 1.yolov5源码中有自带的可视化工具,在detect.py中开启--visualize参数即可 # ========================= # # ========================= # 相关资料 # ========================= # # ========================= # 一、 [SE模块插入位置总结](https://blog.csdn.net/tangshopping/article/details/126133995) [c3模块中加入attention](https://blog.csdn.net/weixin_43694096/article/details/124695537) [算法改进,期刊](https://blog.csdn.net/m0_53578855/article/details/127405874) [Iou综述](https://blog.csdn.net/athrunsunny/article/details/128872025)