yolo-v3看不懂?手撕代码逐行讲解,附带网盘完整代码实现

news2025/2/1 15:49:31

目录

一:读取数据

二:初始化模型

Route 层用于将来自不同层的特征图进行连接或拼接。

Shortcut 层用于执行残差连接,将前一层的特征图与当前层的特征图相加。

 最重要的一层 yolo层:

 三:初始化完所有有网络层后,开始处理数据

四:开始训练

五:损失

六:完整代码网盘链接(附带训练集,和测试的demo)


不多说一句话,直接开撕!!!

一:读取数据

读取coco.data文件

二:初始化模型

 接下里继续搭建模型,

卷积后紧跟BN层,V3版本已经丢掉了Dropout层了

Route 层用于将来自不同层的特征图进行连接或拼接。

Shortcut 层用于执行残差连接,将前一层的特征图与当前层的特征图相加。

CBL(conv+BN+Leaky relu)+Res+ResX+上采样下采样

 #当前层与前面的第几层做操作。如果layers是第四层,那么就第四层做拼接操作————————做特征融合的(做乘法法)
        elif module_def["type"] == "route": # 输入1:26*26*256 输入2:26*26*128  输出:26*26*(256+128)
            layers = [int(x) for x in module_def["layers"].split(",")]
            filters = sum([output_filters[1:][i] for i in layers])
            modules.add_module(f"route_{module_i}", EmptyLayer())

        #跟上面的route很像————————做残差网络的(做加法)
        elif module_def["type"] == "shortcut":
            filters = output_filters[1:][int(module_def["from"])]
            modules.add_module(f"shortcut_{module_i}", EmptyLayer())

 最重要的一层 yolo层:

        这表示只选择了锚框列表中索引为6、7、8的三个锚框用于预测目标框。这个选择是根据训练数据集和目标类别的特点进行的。 yolov3是kmean聚类,他们通过经验和实验,对锚框的尺寸进行了调整和优化,以便在特定任务和数据集上获得更好的性能。这种自定义的锚框设置是基于作者的经验和实践,可能是为了在特定任务中获得更好的结果。

提前设置好了输入的图片是416

 进入yolo层的定义,初始化需要的参数

 三:初始化完所有有网络层后,开始处理数据

        collate_fn是一个函数,用于在数据加载器中将多个样本组合成一个批次。它定义了如何对样本进行分组和处理,以确保组合成的批次具有一致的形状和大小。

 

 collate_fn函数

这个就是利用collate_fn分组后的结果

四:开始训练

 首先先加入Darknet的forward函数,将图片传入,输入到定义好的各个网络层,其中重点看yolo层 。

每一层做完后,都需要append到layer_outputs里面存储。

直接跳到看yolo层的训练

打断点,进入到yolo层的forward哈函数:

第一次yolo层,传入的是11*11的图片

         4+1+80 grid_size网格的大小(x+y+w+h+confidence+predictor(80个列别的概率 )=85),后面用sigmoid把self.num_classes + 5个类别转成概率,虽然可以直接在 x.view 中完成维度交换,但是将其分成两个步骤可以更好地表达代码的意图,提高可读性和可维护性。这样的做法也更加符合代码编写的规范和风格。

 获取这6个变量的信息

 最后取出数据保存到pred_boxes中

还原到原始图中,上面先把高宽成了下采样后的,不过这个是保存在output中的。注意:下面传入的pred_boxes值没有改变

 

先筛选一些iou,再拿这些锚框去跟真实框进行iou计算, 也就是说iou是随便生成的,然后才真正的用筛选好的锚框去跟真实框做iou,

def build_targets(pred_boxes, pred_cls, target, anchors, ignore_thres):
    ByteTensor = torch.cuda.ByteTensor if pred_boxes.is_cuda else torch.ByteTensor
    FloatTensor = torch.cuda.FloatTensor if pred_boxes.is_cuda else torch.FloatTensor

    nB = pred_boxes.size(0)   
    nA = pred_boxes.size(1)   
    nC = pred_cls.size(-1)   
    nG = pred_boxes.size(2)   

     
    obj_mask = ByteTensor(nB, nA, nG, nG).fill_(0)   
    noobj_mask = ByteTensor(nB, nA, nG, nG).fill_(1)   
    class_mask = FloatTensor(nB, nA, nG, nG).fill_(0)   
    iou_scores = FloatTensor(nB, nA, nG, nG).fill_(0)   
    tx = FloatTensor(nB, nA, nG, nG).fill_(0)   
    ty = FloatTensor(nB, nA, nG, nG).fill_(0)
    tw = FloatTensor(nB, nA, nG, nG).fill_(0)
    th = FloatTensor(nB, nA, nG, nG).fill_(0)
    tcls = FloatTensor(nB, nA, nG, nG, nC).fill_(0)

     
    target_boxes = target[:, 2:6] * nG   
    gxy = target_boxes[:, :2]
    gwh = target_boxes[:, 2:] 
     
    ious = torch.stack([bbox_wh_iou(anchor, gwh) for anchor in anchors])   
    print(ious.shape)   
    best_ious, best_n = ious.max(0)   
     
    b, target_labels = target[:, :2].long().t()   
    gx, gy = gxy.t()   
    gw, gh = gwh.t()   
    gi, gj = gxy.long().t()   
     
    obj_mask[b, best_n, gj, gi] = 1   
    print(obj_mask.shape)
    noobj_mask[b, best_n, gj, gi] = 0   

     
    for i, anchor_ious in enumerate(ious.t()):   
        noobj_mask[b[i], anchor_ious > ignore_thres, gj[i], gi[i]] = 0   
         
     
    tx[b, best_n, gj, gi] = gx - gx.floor()   
    print(tx.shape)
    ty[b, best_n, gj, gi] = gy - gy.floor() 
     
    tw[b, best_n, gj, gi] = torch.log(gw / anchors[best_n][:, 0] + 1e-16)   
    print(tw.shape)   
    th[b, best_n, gj, gi] = torch.log(gh / anchors[best_n][:, 1] + 1e-16)
     
    tcls[b, best_n, gj, gi, target_labels] = 1   
    print(tcls.shape)
     
    hyt = pred_cls[b, best_n, gj, gi].argmax(-1)
    class_mask[b, best_n, gj, gi] = (pred_cls[b, best_n, gj, gi].argmax(-1) == target_labels).float()
    iou_scores[b, best_n, gj, gi] = bbox_iou(pred_boxes[b, best_n, gj, gi], target_boxes,
                                             x1y1x2y2=False)   

    tconf = obj_mask.float()   
    return iou_scores, class_mask, obj_mask, noobj_mask, tx, ty, tw, th, tcls, tconf

得出来这些值后:

iou_scores:真实值与最匹配的anchor的IOU得分值 class_mask:分类正确的索引 obj_mask:目标框所在位置的最好anchor置为1 noobj_mask obj_mask那里置0,还有计算的iou大于阈值的也置0,其他都为1 tx, ty, tw, th, 对应的对于该大小的特征图的xywh目标值也就是我们需要拟合的值 tconf 目标置信度

五:损失

六:完整代码网盘链接(附带训练集,和测试的demo)

链接:https://pan.baidu.com/s/1pPh9T4cfMJ4TM4KdQHqcAw?pwd=4986 
提取码:4986

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

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

相关文章

从零开始,5分钟轻松实现Spring Boot与RabbitMQ的无缝集成

🌏 环境 docker v4.16.2springboot 2.7.0RabbitMQ 3.9.1 rabbitmq_delayed_message_exchange 3.9.0 ps:代码地址 gitee 🪜 服务架构 使用maven多模块,将生产者、消费者分别以springboot项目启动,两者通过RabbitMQ…

【Spark基础编程】 第8章 Spark MLlib

系列文章目录 文章目录 系列文章目录前言【 第8章 Spark MLlib 】8.1 Spark MLlib简介8.1.1 什么是机器学习8.1.2 基于大数据的机器学习8.1.3 Spark 机器学习库MLLib 8.2 机器学习工作流8.2.1 机器学习流水线概念8.2.2 构建一个机器学习流水线 8.3 特征抽取、转化和选择8.4 分类…

【DBA日常工作职责---读书笔记】

👈【上一篇】 💖The Begin💖点点关注,收藏不迷路💖 【下一篇】👉 🔻DBA 的工作职责是什么?每天 DBA 应该做哪些工作?稳定环境中的 DBA 该如何成长与 优化&#xff1…

Jmeter插件PerfMon Metrics Collector安装使用及报错解决

Jmeter作为一个轻量级的性能测试工具,开源、小巧、灵活的特性使其越来越受到测试人员喜爱。在实际的项目中,特别是跨地区项目,排除合作方指定要求使用Loadrunner作为性能测试工具外,Jmeter会是首选。 本篇文章,就着重…

华为云DevCloud平台部署bootdo博客论坛实战【开发者专属集市】

华为云DevCloud平台部署bootdo博客论坛实战【开发者专属集市】 一、bootdo-blog开源博客介绍二、本次实践所用工具及平台三、购买华为RDS数据库1.购买RDS数据库2.查看RDS数据库状态 四、创建项目1.登录华为云台DevCloud平台2.新建项目3.查看新建项目4.创建代码仓库 五、配置数据…

老话新谈之缓存一致性

前言 缓存一致性常见的更新策略也比较多,如先更新数据库再更新缓存,先删缓存再更新数据库等等,我在理解的时候有些混乱,所以这个文章提供了一些理解上的技巧去理解缓存一致性。 为什么会有缓存一致性的问题 缓存与数据库是两套…

网络安全从业人员2023年后真的会被AI取代吗?

随着ChatGPT的火爆,很多人开始担心网络安全从业人员会被AI取代。如果说网络安全挖洞的话,AI可能真的能取代。但是网络安全不仅仅只是挖洞,所以AI只是能缓解网络安全人员不足的情况,但是是不会取代人类的作用的。 就拿最近很火的C…

【STL】priority_queue的使用及模拟实现

目录 前言 priority_queue的使用 功能解析 基本接口 写点题目 模拟实现 结构解析 插入删除 调整函数结合仿函数 仿函数介绍 结合使用 其他功能 接口补齐 迭代器区间构造 前言 🍾打开 queue 头文件后,我们发现除了我们之前介绍过的普通队列…

用maven安装JUnit 5并运行单元测试

一&#xff1a;首先讲如何安装 JUnit 5 JUnit Platform JUnit Jupiter JUnit Vintage 如果不需要执行基于JUnit 3 和JUnit 4 的用例&#xff0c;那么JUnit Vintage就不需要安装。 1&#xff09;在pom文件dependencies的小节内增加如下依赖&#xff1a; <dependency>&l…

Docker安装ClickHouse22.6.9.11并与SpringBoot、MyBatisPlus集成

背景 上一篇文章CentOS6.10上离线安装ClickHouse19.9.5.36并修改默认数据存储目录记录了在旧版的操作系统上直接安装低版本 ClickHouse &#xff08;脱胎于俄罗斯头号搜索引擎的技术&#xff09;的过程&#xff0c;开启远程访问并配置密码&#xff1b; 其实通过 Docker 运行 …

一文读懂性能测试

01、常见概念 吞吐量&#xff08;TPS, QPS&#xff09; 简单来说就是每秒钟完成的事务数或者查询数。通常吞吐量大表明系统单位时间能处理的请求数越多&#xff0c;所以通常希望TPS越高越好 响应时间 即从请求发出去到收到系统返回的时间。响应时间一般不取平均值&#xff0…

二叉树及其链式结构

目录 一&#xff1a;树概念及结构 1.树的概念 2.树的相关概念 3.树的表示 二&#xff1a;二叉树的概念及结构 1.概念 2.特殊的二叉树 <1>. 满二叉树&#xff1a; <2>. 完全二叉树&#xff1a; 3.二叉树的性质 4.二叉树的存储结构 <1>.顺序结构 <…

win11 无法登录微软账户 终极解决方案

背景&#xff1a;win11突然无法登录微软账户&#xff0c;office无法激活&#xff0c;Edge里的微软账户也无法登录&#xff0c;反馈中心也无法打开等&#xff0c;有网络&#xff0c;浏览器可以访问微软并进行登录。 试过网上的网络配置&#xff08;SSL及TLS协议勾选&#xff09…

数学模型:Python实现线性规划

文章摘要&#xff1a;线性规划的Python实现。 参考书籍&#xff1a;数学建模算法与应用(第3版)司守奎 孙玺菁。 PS&#xff1a;只涉及了具体实现并不涉及底层理论。学习底层理论以及底层理论实现&#xff1a;可以参考1.最优化模型与算法——基于Python实现 渐令 粱锡军2.算法导…

vim复制,剪切觉得麻烦?今天就来教会你:vim复制和剪切教程

上次讲了vim移动光标的快捷键&#xff0c;今天我们来了解一下vim的复制多行的功能。 快速复制多行 第一步&#xff1a;将光标移动到复制的文本开始的地方&#xff0c;按下v进入可视模式&#xff0c;这里的v的意思就是visual的缩写&#xff0c;就是可视的意思。 第二步&#x…

DBSCAN 集群

目录 DBSCAN 集群 主要代码 DBSCAN 绘制结果中的集群 DBSCAN 集群 基于密度的空间聚类应用&#xff08;DBSCAN&#xff09;是一种基于密度的聚类算法&#xff0c;由Martin Ester等人在1996年提出。该算法在半径为ε的圆内找到数据点的相邻点&#xff0c;并将它们加入到同一…

Git原理详解+指令操作,带你快速掌握Git

一、相关概念 版本控制 什么是版本控制&#xff1f; 用于管理多人协同开发项目的技术对文件的版本控制&#xff0c;要对文件进行修改、提交等操作 版本控制的分类 1.本地版本控制 就是放在本地 2.集中版本控制 SVN 所有的版本数据都保存在服务器上&#xff0c;协同开发…

GDAL读取属性表值乱码解决方法

文章目录 方法1&#xff1a;方法2&#xff1a;1.通过在线网网站&#xff0c;查看编码2.参考C中gbk和utf8互相转换文章 gdal示例代码 方法1&#xff1a; 在网上查看的推荐方法&#xff08;C代码&#xff09;&#xff0c;但没解决我遇到的问题&#xff1b; CPLSetConfigOption(&…

SSM整合快速入门案例

文章目录 前言一、设计数据库表二、创建工程三、SSM技术整合四、功能模块开发五、接口测试总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&#xff0c;方便日后回顾。当然&#xff0c;如果能帮到一些萌新进行新技术的学习那也是极好的。作者…

Java网络开发(Tomcat)——登陆和注册功能 的 迭代升级 从Jsp到JavaScript + axios + vue 诸多bug 同步到异步

目录 引出前置工作vueaxiosresp0.vue版本的jsp模板1.导包--Json&#xff1a;pom.xml文件&#xff1a;2.新建一个专门用来处理响应的实体类ResData3.在axios中&#xff0c;所有响应必须是 resp.getWriter().write() 的方式&#xff0c;核心代码如下4.在jsp前端代码中导包&#x…