好的我来结合YOLOv3的知识通过联想和上下文理解把这段口语化、有错别字的讲解内容梳理清楚。YOLOv3 训练与测试代码讲解要点梳理一、损失函数部分三种损失1. 三种损失类型损失对应代码位置说明置信度损失第0个值判断网格是否有目标坐标偏移量损失第1-4个值 (tx, ty, tw, th)边界框位置回归类别损失第5-14个值共10类多分类用BCE而非Softmax2. 关键代码理解核心就是把c类别放在最后并且reshape向量但是其他nhw顺序没有变把45分成3和15 → 输出维度 [B, H, W, 3, 15] - 3每个网格3个锚框anchor - 155xywhconf 10类别3. Alpha参数的作用正负样本平衡阿尔法值就是用来平衡正样本跟负样本的问题图像中背景负样本远多于目标正样本解决alpha给正样本损失加权小目标/稀疏场景alpha ≈ 0.9加大正样本权重正负均衡场景alpha ≈ 0.5-0.6二、数据格式转换NCHW ↔ NHWC1. 转换原因把那个NCHW转成NHWC → PyTorch默认NCHW处理时转NHWC更方便索引2. 具体转换# 输入: [N, C, H, W] [N, 45, 13, 13]以13×13特征图为例outputoutput.permute(0,2,3,1)# [N, 13, 13, 45]outputoutput.view(N,H,W,3,15)# [N, 13, 13, 3, 15]# 现在可以方便地取: output[..., 0]是conf, output[..., 1:5]是坐标三、正负样本判定关键逻辑1. 判定依据标签里面的第0个值大于0...说明它是有目标的# target[..., 0] 存储的是IoU值或是否匹配的标记pos_masktarget[...,0]0# 正样本掩码布尔值neg_masktarget[...,0]0# 负样本掩码2. 损失计算策略样本类型计算哪些损失原因正样本置信度 坐标 类别完整学习检测负样本仅置信度只学习这是背景负样本的话呢只需要让他学习一下他是负样本的这个置信度就可以了一张图里面背景就是负样本目标物体就是正样本往往遇到负样本偏多但是负样本不需要反算原图坐标不需要学习类别。四、类别损失的两种实现BCE vs Softmax1. Softmax CrossEntropyCE使用这个Softmax去做...多分类的交叉熵损失函数特点自动将标签转one-hot有排他性各类别概率和为1问题标签里面有包含关系的就不能用Softmax例“人包含男人”、“女人”Softmax会强制互斥2. BCEBinary Cross Entropy⭐ YOLOv3采用用BCE损失函数去做多分类...各是各的他们之间没有关系特点每个类别独立做二分类0-1之间无排他性优势允许标签有包含关系人女人可同时为高概率输出直接是置信度无需额外转换3. 标签处理差异方法标签格式代码处理Softmax普通索引[batch,]需argmax从one-hot转回BCEone-hot[batch, num_classes]直接用无需转换因为我们这个标签我们是做了one hot的...你要用这个Softmax的话呢你就得又得把它要转回去五、测试/推理代码Detection1. 整体流程图像输入 → 网络前向 → 三尺度输出 → 滤波阈值→ 反算坐标 → NMS → 画框2. 滤波操作Filter# 传进去一个阈值...得到index和偏移量conftorch.sigmoid(output[...,0])# 加sigmoid归一化到0-1maskconfthreshold# 阈值过滤如0.5indextorch.nonzero(mask,as_tupleFalse)# nonzero...拿非零索引offsetsoutput[mask]# 拿到对应偏移量3. 坐标反算Decode通过index和偏移量...反算出来13×13的特征图上的所有box公式对应代码# index: [N, 4] → [batch, y, x, anchor_id]# stride: 13×13特征图对应3226×26对应1652×52对应8Cxindex[:,2]*stride# 网格左上角xW维度Cyindex[:,1]*stride# 网格左上角yH维度# offsets: [tx, ty, tw, th, conf, ...]bx(torch.sigmoid(offsets[:,1])index[:,2])*stride# x中心by(torch.sigmoid(offsets[:,2])index[:,1])*stride# y中心bwanchors[:,0]*torch.exp(offsets[:,3])# 宽bhanchors[:,1]*torch.exp(offsets[:,4])# 高4. 类别和置信度提取conftorch.sigmoid(offsets[:,0])# 目标置信度cls_scoresoffsets[:,5:]# 10个类别分数cls_idtorch.argmax(cls_scores,dim1)# 取最大值的索引六、NMS优化类别感知NMS1. 传统NMS的问题普通的NMS...只要两个目标接的很接近他就把它给丢掉了狗和猫靠在一起 → 只保留一个框 →漏检2. YOLOv3的改进同类别才去做NMS...不同类别的话呢哪怕重合都非常的高也不会把你给丢掉逻辑forclsinunique_classes:# 只对该类别的框做NMSsame_cls_boxesboxes[classescls]keepnms(same_cls_boxes,iou_threshold)狗class0和猫class1互不干扰两只狗同为class0仍会抑制七、多尺度损失相加13×13的特征图上的损失还有26×26还有52×52...三种损失都要加起来# YOLOv3三个检测头loss_13compute_loss(output_13,target_13,anchors[6:9])# 大目标loss_26compute_loss(output_26,target_26,anchors[3:6])# 中目标loss_52compute_loss(output_52,target_52,anchors[0:3])# 小目标total_lossloss_13loss_26loss_52八、下节课预告讲师原话整理内容说明图像缩放对图像进行缩放标签...比较好的一个方法→ LetterBox保持长宽比填充K-meansK-means是怎么样子的→ 锚框聚类算法九、关键术语对照表口语→标准术语口语/错别字标准术语上下文“猫框”锚框(Anchor)anchor box“猫跨”锚框同上口音问题“执行度”置信度(Confidence)目标存在概率“镇压本”正样本Positive sample“负压本/负样本”负样本Negative sample“便宜量”偏移量(Offset)tx, ty, tw, th“反算”解码(Decode)偏移量→真实坐标“滤波”过滤(Filter)阈值筛选“trade的”TensorPyTorch张量“must”mask掩码“low zero”nonzero非零索引“脑子”nonzero口音“MS/NMS”NMS(Non-Maximum Suppression)非极大值抑制“Kimi死”K-meansK均值聚类“阿达姆”Adam优化器“sgd”SGD随机梯度下降“揣个蹬侧”Detector检测器