yolo 训练
这里写目录标题
- 分配训练集&Validation数量
- 数据集读取
- 读取全部文件夹
- 替换路径
- loss weight
- NMS
- BBox_IOU
- EIou
- Optimizer
分配训练集&Validation数量
validation_size = training_size * validation_ratio / (1 - validation_ratio)
training_size = 219
validation_ratio = 0.2
validation_size = 219*0.2/(1-0.2)
如果你有 346 张验证图像,使用 k=5 的交叉验证方法,你可以将这些图像分成 5 个不同的折叠(fold),每个折叠包含 69 或 70 张图像。
平均分配图像的方法:
num_images_per_fold = len(val_images) // num_folds
from sklearn.model_selection import KFold# 假设你有 291 个训练图像和 55 个验证图像
train_images = range(291)
valid_images = range(291, 291+55)# 将训练图像分成五个部分
kf = KFold(n_splits=5, shuffle=True)
for fold, (train_idx, valid_idx) in enumerate(kf.split(train_images)):# 选择一个部分作为验证集,其余部分作为训练集train_images_fold = [train_images[i] for i in train_idx]valid_images_fold = [train_images[i] for i in valid_idx]# 在每次交叉验证中,使用训练集进行训练,并使用验证集进行验证# TODO: 训练和验证模型# 记录模型的性能指标# TODO: 记录模型性能指标# 将五个结果的平均值作为模型的性能指标
# TODO: 计算模
数据集读取
读取全部文件夹
p = Path(p) # p = WindowsPath('E:/data/helmet_head/train')
glob.glob(str(p / '**' / '*.*'), recursive=True)
这行 Python 代码使用了 pathlib 模块中的 WindowsPath 类来创建一个 Windows 路径对象 p,表示了一个名为 train 的目录,该目录位于 E:/data/helmet_head/ 目录下。接下来,使用 glob 函数来获取该目录及其所有子目录中的所有文件(包括子目录中的文件)。
p / '**' / '*.*'
表示将 p 对象的路径添加上 '**'
(表示所有子目录),然后再添加上 '*.*'
(表示所有类型的文件)路径,得到一个包含通配符的字符串路径。这个字符串路径会被转换为一个 WindowsPath 对象并传递给 glob 函数。
glob(str(p / '**' / '*.*'
), recursive=True) 表示使用 glob 函数获取符合给定路径模式的文件列表。recursive=True 表示要递归地查找子目录中的文件。
替换路径
x = 'E:\\data\\helmet_head\\train\\collect20120420\\JPEGImages\\000000.jpg'
sa = '\\JPEGImages\\'
sb = '\\Annotations\\'
sb.join(x.rsplit(sa, 1))
将指定路径 x 中的子目录名称 ‘JPEGImages’ 替换为 ‘Annotations’
x.rsplit(sa, 1)
使用 rsplit
函数将路径 x 按照指定的子目录名称 ‘JPEGImages’ 进行分割,并将分割结果作为一个列表返回。其中,sa
是分割字符串,1
表示只分割一次,即只分割最后一次出现的位置。
x.rsplit(sa, 1) 的结果为:
[‘E:\data\helmet_head\train\collect20120420’, ‘000000.jpg’]。
'\\Annotations\\'.join(x.rsplit(sa, 1))
使用 ‘\Annotations\’ 字符串将分割后的列表中的元素连接起来,得到一个新的路径。这个路径将原路径中的子目录名称 ‘JPEGImages’ 替换为 ‘Annotations’。
‘\Annotations\’.join(x.rsplit(sa, 1)) 的结果为:
'E:\data\helmet_head\train\collect20120420\\Annotations\\
000000.jpg’
loss weight
Pytorch: BCEWithLogitsLoss
YOLO v5 中的loss weight 在data/hyp/scratch.yaml 中的cls_pw
,同时 obj_pw
也可以使用同样的vector
通过train.py 中:
model.class_weights = labels_to_class_weights(dataset.labels, nc).to(device) * nc # attach class weights
weights = np.bincount(classes, minlength=nc)
weights[weights == 0] = 1 # replace empty bins with 1
weights = 1 / weights # number of targets per class
weights /= weights.sum()
- 得到3个种类在数量上应该受到的提高为: tensor([0.12096, 2.43440, 0.44464])
- 其中数字越大的代表数据量越少
target = torch.ones([4,3,8,8], dtype=torch.float32)
output = torch.full([4,3,8,8], 1.5)
pos_weight = torch.ones([3,8,8])
criterion = torch.nn.BCEWithLogitsLoss(pos_weight=pos_weight)
criterion(output, target)
这里的pos_weight = torch.ones([3,8,8]) 一定确保倒数的维度和output/target 相同
初始的cls_pw
是一个scalar, 如下:
target = torch.ones([4,3,8,8], dtype=torch.float32)
output = torch.full([4,3,8,8], 1.5)
pos_weight = torch.ones([1])
criterion = torch.nn.BCEWithLogitsLoss(pos_weight=pos_weight)
criterion(output, target)
NMS
以下是torch 版的 NMS, 代替了torchvision.ops.nms(boxes, scores, iou_thres)
def nms(bboxes, scores, iou_thresh=0.5):_, order = scores.sort(0, descending=True)keep = []while order.numel() > 0:if order.numel() == 1: # 保留框只剩一个i = order.item()keep.append(i)breakelse:i = order[0].item() # 保留scores最大的那个框box[i]keep.append(i)iou = bbox_iou_new(bboxes[i], bboxes[order[1:]]).squeeze()idx = (iou <= iou_thresh).nonzero().squeeze() # 注意此时idx为[N-1,] 而order为[N,]if idx.numel() == 0:breakorder = order[idx + 1] # 修补索引之间的差值return keep
以下是计算bbox的,这个function 被用于替换 NMS中计算IOU。这样做可以帮助做些关于IOU相关的ablation 分析
def bbox_iou_new(box1, box2, GIoU=False, DIoU=False, CIoU=False, SIoU=False, EIoU=False, Focal=True, eps=1e-7):# Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4)b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, -1)b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, -1)w1, h1 = b1_x2 - b1_x1, (b1_y2 - b1_y1).clamp(eps)w2, h2 = b2_x2 - b2_x1, (b2_y2 - b2_y1).clamp(eps)# Intersection areainter = (b1_x2.minimum(b2_x2) - b1_x1.maximum(b2_x1)).clamp(0) * \(b1_y2.minimum(b2_y2) - b1_y1.maximum(b2_y1)).clamp(0)# Union Areaunion = w1 * h1 + w2 * h2 - inter + eps# IoUiou = inter / unionif CIoU or DIoU or GIoU or EIoU:cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1) # convex (smallest enclosing box) widthch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1) # convex heightif CIoU or DIoU or EIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squaredrho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center dist ** 2if CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (4 / math.pi ** 2) * (torch.atan(w2 / h2) - torch.atan(w1 / h1)).pow(2)with torch.no_grad():alpha = v / (v - iou + (1 + eps))return iou - (rho2 / c2 + v * alpha) # CIoUelif EIoU:rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2cw2 = cw ** 2 + epsch2 = ch ** 2 + epsif Focal:gamma = 0.5return (iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)) * torch.pow(inter / (union + eps), gamma).mean() # Focal_EIoureturn iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)return iou - rho2 / c2 # DIoUc_area = cw * ch + eps # convex areareturn iou - (c_area - union) / c_area # GIoU https://arxiv.org/pdf/1902.09630.pdfelif SIoU:# SIoU Loss https://arxiv.org/pdf/2205.12740.pdfs_cw = (b2_x1 + b2_x2 - b1_x1 - b1_x2) * 0.5 + epss_ch = (b2_y1 + b2_y2 - b1_y1 - b1_y2) * 0.5 + epssigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)sin_alpha_1 = torch.abs(s_cw) / sigmasin_alpha_2 = torch.abs(s_ch) / sigmathreshold = pow(2, 0.5) / 2sin_alpha = torch.where(sin_alpha_1 > threshold, sin_alpha_2, sin_alpha_1)angle_cost = torch.cos(torch.arcsin(sin_alpha) * 2 - math.pi / 2)rho_x = (s_cw / cw) ** 2rho_y = (s_ch / ch) ** 2gamma = angle_cost - 2distance_cost = 2 - torch.exp(gamma * rho_x) - torch.exp(gamma * rho_y)omiga_w = torch.abs(w1 - w2) / torch.max(w1, w2)omiga_h = torch.abs(h1 - h2) / torch.max(h1, h2)shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w), 4) + torch.pow(1 - torch.exp(-1 * omiga_h), 4)return iou - 0.5 * (distance_cost + shape_cost)return iou # IoU
BBox_IOU
CIOU 弥补了 GIOU 只考虑重合不考虑临近但也可用的框。但是CIOU中的那几个criteria 依然还有缺点:
-
v 不太靠谱
- 如果 w, h 的量级为 ground-truth 的整倍数,那么v 为 0 (无效,一样大才是想要的,但不是倍数大) 比如 K倍:
- w = k w g t , h = k w g t w= kw^{gt}, h = kw^{gt} w=kwgt,h=kwgt v = 4 π 2 ( a r c t a n w g t h g t − a r c t a n k w g t k h g t ) 2 = 0 v = \frac{4}{\pi ^2}(arctan \frac{w^{gt}}{h^{gt}}-arctan\frac{kw^{gt}}{kh^{gt}})^2 = 0 v=π24(arctanhgtwgt−arctankhgtkwgt)2=0
-
还是 v 的这一步在gradient 这里引起的不靠谱
- w, h 会有相反的符号, 当 w 和 h 都比 ground truth 大/小 时,两个量按理也应该同时扩大/缩小。
- 符号导致对w,h 处理不公。
- 细节原因:
做partial gradient 后,w, h 会因为 V中 原本用来算宽高比之差的地方,导致各自在gradient 时,遭遇不公
这里的v 如果不放进训练过程,倒也还是make sense, 可以看作是宽高比的 norm-2 的计算。但放进训练,就要搞gradient,也就是搞partial gradient,就从🆗到不太行了。
EIou
Optimizer
Adam 与 AdamW 都是用于Yolo v5 中的optimiser. 他们在小数据集上可以很快降低loss, 但随着训练增加,他们不如SGD 会 平稳,反而会 oscillation.
Adam 可以看作是extend 自 L2 regularisation 的 optimiser. (Pytorch) (Paper)
AdamW 可以看作是extend自 weight decay 的 optimiser. (Pytorch) (Paper)
论文给 SGD和 Adam 都试了 weight decay 和 L2 regularization.红色的是传统使用 L2 regularization 做法, 绿色是使用weight decay的做法。
L2 regulrisation 都是针对Gradient做。
而 Weight decay 是在对 parameters 做 update时做。
相关文章:

yolo 训练
这里写目录标题 分配训练集&Validation数量数据集读取读取全部文件夹替换路径 loss weightNMSBBox_IOUEIou Optimizer 分配训练集&Validation数量 validation_size training_size * validation_ratio / (1 - validation_ratio)training_size 219 validation_ratio …...

谷歌chrome浏览器升级新版后字体显示不清楚解决方案
谷歌chrome浏览器升级新版后字体显示不清楚解决方案 参考图片: Chrome更新至版本Chrome 109.0.5414.120 字体看不清 浏览器症状与表现 Chrome更新至版本Chrome 109.0.5414.120 字体看不清;会很细,在设置中选择自定义的字体,仍无法…...

在外包干了三年,我废了……不吹不黑!
没错,我也干过外包,一干就是三年,三年后,我废了…… 虽说废的不是很彻底,但那三年我几乎是出差了三年、玩了三年、荒废了三年,那三年,我的技术能力几乎是零成长的。 说起这段三年的外包经历&a…...

【Vue】学习笔记-消息的订阅与发布
消息的订阅与发布(基本不用) 消息订阅与发布(pubsub)消息订阅与发布是一种组件间的通信的方式,适用于任意组件间通信 消息订阅与发布 1.订阅消息∶消息名 2.发布消息︰消息内容 消息订阅与发布的工作流程: (A是订阅者,B是发布…...
大疆无人机 MobileSDK(遥控器/手机端)开发 v5版<1>
文章目录 概要整体架构流程技术细节SDK 架构体系概述层级架构智能任务空白项目集成 MSDK新建空白项目新建 MyApplication.kt 文件修改 build.gradle(Module) 文件修改 AndroidManifest.xml 文件修改 MainActivity.kt 文件导入 UXSDK 开源框架4.X 和 5.X 版本差异说明DJIKey差异…...

azkaban介绍
目录 为什么需要工作流调度系统 什么是azkaban azkaban适用场景 azkaban特点 常见的工作流调度系统 azkaban和Ooize特性对比 azkaban的架构 azkaban调度的任务有可能有那些类型 总结 为什么需要工作流调度系统 一个完整的大数据分析系统,必然由很多任务单…...

自学黑客(网络安全)必学内容
随着时代的发展,经济、社会、生产、生活越来越依赖网络。而随着万物互联的物联网技术的兴起,线上线下已经打通,虚拟世界和现实世界的边界正变得模糊。这使得来自网络空间的攻击能够穿透虚拟世界的边界,直接影响现实世界的安全。 …...

Java每日一练(20230518) 移除元素、跳跃游戏II、复原IP地址
目录 1. 移除链表元素 🌟 2. 跳跃游戏 II 🌟🌟 3. 复原 IP 地址 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 移…...

diff命令和vimdiff命令
文章目录 diff命令基本用法选项示例 vimdiff命令命令格式选项说明常用操作 diff命令 diff命令是一个文本比较工具,用于比较两个文件的内容,它会逐行比较两个文件的内容并输出它们之间的差异。下面是diff命令的常用选项和用法: 基本用法 比…...
AcWing 797.差分(C++)
目录 1.题目描述 2.AC 1.题目描述 797.差分 输入一个长度为 nn 的整数序列。 接下来输入 mm 个操作,每个操作包含三个整数 l,r,cl,r,c,表示将序列中 [l,r][l,r] 之间的每个数加上 cc。 请你输出进行完所有操作后的序列。 输入格式 第一行包含两…...

Python每日一练(20230515) 只出现一次的数字 I\II\III
目录 1. 只出现一次的数字 Single Number 2. 只出现一次的数字 II Single Number II 3. 只出现一次的数字 III Single Number III 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 leetcod…...

基于【EasyDL】【图像分类】实现农作物病害识别小程序
内容、数据集来源:基于飞桨的农作物病害智能识别系统 - 飞桨AI Studio 项目背景 联合国粮食及农业组织的一份报告表明,每年农业生产的自然损失中有三分之一以上是由农业病虫害造成的,使这些成为当前影响农业生产和农业生产的最重要因素。需要考虑的农业…...

元宇宙又“死”了!Epic老板:你当6亿用户是摆设?
“扎克伯格花了数年时间试图让Metaverse成为现实,但现在它已被AI取代,并走向科技创意的坟墓。”一篇表达“元宇宙已死”的文章近期在推特上引发热议,而游戏制作公司Epic Games CEO Tim Sweeney的还击更是让这个话题热上加热。 “搞一次在线守…...
阶段小结2022
工作马上一年,对于一年工作能力提升可能逐步在提升,业务能力也在慢慢提升,虽然没有一年前想象的飞起状态,但是刚接触这一行,希望越来越好。 之前每次的遇到的问题其实都会在笔记或者博客中记录,但是没有整体…...

linux0.12-8-11-vsprintf.c
[383页] 1、 这一小节可以不看代码如何实现,因为标准的C库函数; 2、 等自己看完的这本书,有兴趣过来研究研究也是可以的。 8-11 vsprintf.c程序 8-11-1 功能描述 该程序主要包括vsprintf(),用于对参数产生格式化的输出。由于该函数是C函数…...

Node.js 与 WebAssembly
目录 1、简介 2、关键概念 3、生成WebAssembly模块 4、如何使用它 5、与操作系统交互 1、简介 首先,让我们了解为什么WebAssembly是一个很棒的工具,并学会自己使用它。 WebAssembly是一种类似汇编的高性能语言,可以从各种语言编译&…...

OpenCL编程指南-4.4矢量操作符
矢量操作符 如下描述了可用于矢量数据类型或矢量和标量数据类型组合的各类操作符。 算术操作符 算术操作符(加()、减(–)、乘(*)和除(/)),可以作用于内置整数、浮点标量和矢量数…...

索洛模型(二)
索洛模型(二) 文章目录 索洛模型(二)[toc]1 事实2 假设2.1 对生产函数的假设2.2对投入要素的假设 3 索洛模型的动态学3.1 k k k的动态学3.2 平衡增长路径 4 储蓄率变化的影响4.1 对产出的影响4.2 对消费的影响 索罗经济增长模型(Solow growth model)&am…...

【多微电网】基于粒子群优化算法的面向配电网的多微电网协调运行与优化(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

使用Atmel Studio开发Arduino的ATmega328P单片机
摘要:我们知道Arduino开发板常用的芯片是Atmel公司生产的AVR微控制器系列。最常见的是ATmega328P,被广泛用于Arduino Uno开发板。其他常用的AVR芯片包括ATmega2560和ATmega32U4。使用Arduino平台开发AVR的单片机非常方便。Arduino IDE提供了一个非常简洁…...

FineReport模板认证找不到模板
水善利万物而不争,处众人之所恶,故几于道💦 文章目录 1.现象及排查过程2. 解决办法 1.现象及排查过程 FR模板认证下面找不到模板 由于是集群部署的FR,所以后台查看了sftp服务器,测试连接,连接成功。 但是…...

TomatoSCI数据分析实战:探索社交媒体成瘾
今天我们尝试对一份社交媒体成瘾的调查数据进行几项简单的分析,看看可以得出哪些有意思的结论?图1A是这份数据的说明,因为篇幅太长只把部分数据贴出来(图1B)。 01 不同性别的成瘾程度会不同吗? 我们使用bo…...

vue+elementui 网站首页顶部菜单上下布局
菜单集合后台接口动态获取,保存到store vuex状态管理器 <template><div id"app"><el-menu:default-active"activeIndex2"class"el-menu-demo"mode"horizontal"select"handleSelect"background-…...
【时时三省】(C语言基础)局部变量和全局变量
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 以前所见到的程序大多数是一个程序只包含一个main函数,变量是在函数的开头处定义的。这些变量在本函数范围内有效,即在本函数开头定义的变量,在本函数中可…...

《数据挖掘》- 房价数据分析
这里写目录标题 采用的技术1. Python编程语言2. 网络爬虫库技术点对比与区别项目技术栈的协同工作流程 代码解析1. 导入头文件2. 读取原始数据3. 清洗数据4. 数据分割4.1 统计房屋信息的分段数量4.2 将房屋信息拆分为独立列4.3 处理面积字段4.4 删除原始房屋信息列 5. 可视化分…...
php中实现邮件发送功能
要在php项目中实现邮件发送功能,推荐使用phpmailer库通过smtp协议配置。首先安装phpmailer扩展,可通过composer命令composer require phpmailer/phpmailer安装;若未使用composer则手动引入源码。接着配置smtp信息,包括服务器地址&…...

Code Composer Studio CCS 工程设置,如何设置h文件查找路径?
右键工程,选Properties,在Build>MSP430 Compiler>Optinizution Include Options 设置头文件的搜索路径。 比如我设置了这些: ${CCS_BASE_ROOT}/msp430/include ${PROJECT_ROOT} ${CG_TOOL_ROOT}/include "${workspace_loc:/${ProjName}/F5xx_F6xx_Core_Lib}&quo…...
精益数据分析(95/126):Socialight的定价转型启示——B2B商业模式的价格策略与利润优化
精益数据分析(95/126):Socialight的定价转型启示——B2B商业模式的价格策略与利润优化 在创业过程中,从B2C转向B2B不仅是商业模式的转变,更是定价策略与成本结构的全面重构。今天,我们将通过Socialight的实…...
每日算法 -【Swift 算法】三数之和
Swift|三数之和(3Sum)详细题解 注释 拓展(LeetCode 15) ✨题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a, b, c,使得 a b c 0。请你找出所有和为 0 且不重…...
PostgreSQL 技术峰会,为您打造深度交流优质平台
峰会背景 PostgreSQL 作为全球领先的开源关系型数据库管理系统,凭借其强大的功能、高度的扩展性和稳定性,在云计算、大数据、人工智能等领域得到了广泛应用。随着数字化转型的加速,企业对数据库技术的需求日益复杂和多样化,Postg…...