开学时,给自己定的学习任务,直到今天才有闲空来完成。一方面是yolo代码初看觉得乱糟糟的,不想读;其次,yolo算法对于初触深度学习的我而言,还是有较大的难度。

今天学习成果就是弄懂了,yolov5的Idea+模型的构建+实现源码

类似ViT的阅读,阅读完后觉得,还是自顶向下解析比较清晰。

YOLOv5系列:解析索引

一、Yolo v5 模型结构

模型整体分为:

1.BackBone

2.Neck

3.Head(在代码中,直观上看似乎作者将Neck和Head放在一起实现了)

下方的图中,用四个黄颜色圈出来的部分,分别表示为4个Head部分。

二、Yolo v5 的模块

作者实现为了保证模型的灵活可调,将几乎所有的参数都预设到yaml文件中了,因此在构建模型的时候,只要清楚模块的实现即可,对应参数在yaml文件中已经给出。

核心子模块:

1.Focus: Slice=interlace-stride2-DownSample 步长为2的横纵向交错采样

2.Conv: conv+BN+HardSwish

3.Bottleneck-True: <res0>+<res1>Conv*2</res1>

4.Bottleneck-False: Conv*2

5.C3-True: BCSP3-True

6.C3-False: BCSP3-False

7.BCSPn-True:

<res0>  Concate

<res1>Conv+Bottleneck-True*n+conv</res1> Concate

<res2>conv</res2>

8.BCSPn-False:

Bottleneck-False*n

9.SPP:金字塔池化--通过不同kernal_size的池化结果的拼接

三、Yolo v5  Detect部分源码详解

class Detect(nn.Module):stride = None  # strides computed during buildonnx_dynamic = False  # ONNX export parameterdef __init__(self, nc=80, anchors=(), ch=(), inplace=True):  # detection layersuper().__init__()self.nc = nc  # number of classes# 每一个 预选框预测输出,前nc个01字符对应类别,后5个对应:是否有目标,目标框的中心,目标框的宽高self.no = nc + 5  # number of outputs per anchor# 表示预选层数,yolov5是3层预选self.nl = len(anchors)# 预选框数量,anchors数据中每一对数据表示一个预选框的宽高self.na = len(anchors[0]) // 2# 初始化grid列表大小,空列表self.grid = [torch.zeros(1)] * self.nl# 初始化anchor_grid列表大小,空列表self.anchor_grid = [torch.zeros(1)] * self.nl# 注册常量anchor,并将预选框(尺寸)以数对形式存入 ---- 实际存的是框的宽高self.register_buffer('anchors', torch.tensor(anchors).float().view(self.nl, -1, 2))# 每一张进行三次预测,每一个预测结果包含nc+5个值# (n, 255, 80, 80),(n, 255, 40, 40),(n, 255, 20, 20) --> ch=(255, 255, 255)# 255 -> (nc+5)*3 ===> 为了提取出预测框的位置信息以及预测框尺寸信息self.m = nn.ModuleList(nn.Conv2d(x, self.no * self.na, 1) for x in ch)  # output convself.inplace = inplace  # use in-place ops (e.g. slice assignment)def forward(self, x):z = []  # inference output# 输入的x是来自三层金字塔的预测结果(n, 255, 80, 80),(n, 255, 40, 40),(n, 255, 20, 20)for i in range(self.nl):# 下面3行代码的工作:# (n, 255, _, _) -> (n, 3, nc+5, ny, nx) -> (n, 3, ny, nx, nc+5)# 相当于三层分别预测了80*80、40*40、20*20次,每一次预测都包含3个框x[i] = self.m[i](x[i])bs, _, ny, nx = x[i].shape# contiguous 将数据保证内存中位置连续x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()# self.training 作为nn.Module的参数,默认是True,因此下方代码先不考虑if not self.training:  # inferenceif self.onnx_dynamic or self.grid[i].shape[2:4] != x[i].shape[2:4]:# 为每一层划分网格self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)y = x[i].sigmoid()# 改变原数据if self.inplace:# grid[i] = (3, 20, 20, 2), y = [n, 3, 20, 20, nc+5]# grid实际是 位置基准 或者理解为 cell的预测初始位置,而y[..., 0:2]是作为在grid坐标基础上的位置偏移# anchor_grid实际是 预测框基准 或者理解为 预测框的初始位置,而 y[..., 2:4]是作为预测框位置的调整y[..., 0:2] = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xyy[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # whelse:  # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953# stride应该是一个grid cell的实际尺寸# 经过sigmoid,值范围变成了(0-1),下一行代码将值变成范围(-0.5,1.5),# 相当于预选框上下左右都扩大了0.5倍的移动区域,不易大于0.5倍,否则就重复检验了其他网格的内容了# 此处的1表示一个grid cell的尺寸,尽量让预测框的中心在grid cell中心附近xy = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xy# 范围变成(0-4)倍,设置为4倍的原因是下层的感受野是上层的2倍# 因下层注重检测大目标,相对比上层而言,计算量更小,4倍是一个折中的选择wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # why = torch.cat((xy, wh, y[..., 4:]), -1)z.append(y.view(bs, -1, self.no))return x if self.training else (torch.cat(z, 1), x)def _make_grid(self, nx=20, ny=20, i=0):d = self.anchors[i].deviceif check_version(torch.__version__, '1.10.0'):  # torch>=1.10.0 meshgrid workaround for torch>=0.7 compatibility# 网格标尺坐标# indexing='ij' 表示的是i是同一行,j表示同一列# indexing='xy' 表示的是x是同一列,y表示同一行yv, xv = torch.meshgrid([torch.arange(ny).to(d), torch.arange(nx).to(d)], indexing='ij')else:yv, xv = torch.meshgrid([torch.arange(ny).to(d), torch.arange(nx).to(d)])# grid --> (20, 20, 2), 拓展(复制)成3倍,因为是三个框 -> (3, 20, 20, 2)grid = torch.stack((xv, yv), 2).expand((1, self.na, ny, nx, 2)).float()# 与grid同理anchor_grid = (self.anchors[i].clone() * self.stride[i]) \.view((1, self.na, 1, 1, 2)).expand((1, self.na, ny, nx, 2)).float()return grid, anchor_grid

Yolov5(1):Detect源码逐行解析相关推荐

  1. 超详细preact hook源码逐行解析

    本文通过对preact的hook源码分析,理解和掌握react/preact的hook用法以及一些常见的问题.虽然react和preact的实现上有一定的差异,但是对于hook的表现来说,是基本一致的 ...

  2. YOLOv5目标检测源码重磅发布了!

    YOLOv5目标检测源码重磅发布了! https://github.com/ultralytics/yolov5 该存储库代表了对未来对象检测方法的超解析开源研究,并结合了在使用之前的YOLO存储库在 ...

  3. 《Spring源码深度解析 郝佳 第2版》JDBC、MyBatis原理

    往期博客 <Spring源码深度解析 郝佳 第2版>容器的基本实现与XML文件的加载 <Spring源码深度解析 郝佳 第2版>XML标签的解析 <Spring源码深度解 ...

  4. iOS开发之Masonry框架源码深度解析

    Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...

  5. 【TarsosDSP】TarsosDSP 简介 ( TarsosDSP 功能 | 相关链接 | 源码和相关资源收集 | TarsosDSP 示例应用 | TarsosDSP 源码路径解析 )

    文章目录 I . TarsosDSP 函数库简介 II . TarsosDSP 功能 III . TarsosDSP 相关资源链接 ( 官方资料 ) IV . TarsosDSP 源码和相关资源收集 ...

  6. 机器学习算法源码全解析(三)-范数规则化之核范数与规则项参数选择

    前言 参见上一篇博文,我们聊到了L0,L1和L2范数,这篇我们絮叨絮叨下核范数和规则项参数选择.知识有限,以下都是我一些浅显的看法,如果理解存在错误,希望大家不吝指正.谢谢. 机器学习算法源码全解析( ...

  7. 从源码角度解析Android中APK安装过程

    从源码角度解析Android中APK的安装过程 1. Android中APK简介 Android应用Apk的安装有如下四种方式: 1.1 系统应用安装 没有安装界面,在开机时自动完成 1.2 网络下载 ...

  8. dubbo源码深度解析_Spring源码深度解析:手把手教你搭建Spring开发环境

    Spring环境搭建流程,如果是第一次接触spring源码的环境搭建,确实还是比较麻烦的. 作者使用的编译器为目前流行的lntelliJ IDEA,版本为2018旗舰版.Eclipse用户还需要自己揣 ...

  9. Jdk1.8 JUC源码增量解析(1)-atomic-Striped64

    转载自  Jdk1.8 JUC源码增量解析(1)-atomic-Striped64 功能简介: Striped64是jdk1.8提供的用于支持如Long累加器,Double累加器这样机制的基础类. S ...

最新文章

  1. 字节跳动喜欢招聘这样的机器学习工程师
  2. Oracle误删除数据的恢复方法
  3. Java基础-Java中的堆内存和离堆内存机制
  4. 企业网络推广——企业网络推广出于四大目的旨在做好网站营销
  5. ChartDirector Python创建建多层甘特图的代码
  6. AI理论知识整理(5)-对称矩阵-对角化
  7. 信息学奥赛一本通(1145:字符串p型编码)
  8. python模拟账号登录_用Python(Tornado)模拟登录小米帐号
  9. 计算机不识别固态硬盘,电脑经常不识别固态硬盘
  10. 2小时完成的第一个副业单子:Python修正excel表格数据
  11. java延迟1秒_java 等待一秒方法
  12. 执念与释然,一念之间
  13. Laravel版本更新异常4.2.8- 4.2.9 Declaration of ... CompilerEngine ... should be compa
  14. 写一段情人节耳钉礼物文案,要求100字左右,以小红书的形式展示,带emoji表情包,带分段,吸引眼球,情绪化,最后加一些tag...
  15. 微信公众号推文(编辑+排版教程)
  16. 《程序员脱发指南》--饮食篇
  17. Java.IO.InputStream-OutputStream
  18. vb修改计算机时间,如何在VB里进行日期格式转换
  19. The quieter you become,The more you are able to hear.
  20. 综合案例 -- 北京租房数据统计分析

热门文章

  1. java中load_Load Java参数描述的细节
  2. viper4android md,【超级街霸4安卓版】超级街霸4安卓完整移植版游戏下载-街机中国...
  3. 微信模板消息推送接口说明
  4. 解决:SCRIPT5011: Can't execute code from a freed script
  5. Swagger2 3.0的使用
  6. vue+flask微博大数据舆情监控+情感分析可视化系统+爬虫
  7. 金蝶云星空与盘古MES系统数据集成对接方案
  8. 大数据云平台数据治理规划方案(PPT)
  9. 膨胀珍珠岩板(EPB) 保温材料英国UKCA 认证-EN 13169
  10. Eeprom(at24c04)调试小记