yolov5s.yaml 文件

以yolov5s.yaml 为例
其中有设置好的anchor

每一行代表在某一层的anchor. 一行的三组数字分别代表三个anchor的宽和高 基准 
且小anchor 是在大特征图上,大anchor是在小特征图上。以输入图片大小640*640为例:
最终提取三个特征图大小分别为 80 X 80 , 40 X 40, 20X20
那么 [10, 13, 16,30, 33,23] 将应用在80 X 80 的特征图上
[30,61, 62,45, 59,119] 应用在 40 X40 的特征图上
[116,90, 156,198, 373,326] 在 20 X 20 的特征图上

Detect 函数

定义在yolo.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 classesself.no = nc + 5  # number of outputs per anchorself.nl = len(anchors)  # number of detection layersself.na = len(anchors[0]) // 2  # number of anchorsself.grid = [torch.zeros(1)] * self.nl  # init gridself.anchor_grid = [torch.zeros(1)] * self.nl  # init anchor gridself.register_buffer('anchors', torch.tensor(anchors).float().view(self.nl, -1, 2))  # shape(nl,na,2)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 outputfor i in range(self.nl):x[i] = self.m[i](x[i])  # convbs, _, ny, nx = x[i].shape  # x(bs,255,20,20) to x(bs,3,20,20,85)x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()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: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/2953xy = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xywh = (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) #training 的时候返回偏量def _make_grid(self, nx=20, ny=20):d = self.anchors.deviceyv, xv = torch.meshgrid([torch.arange(ny).to(d), torch.arange(nx).to(d)])grid = torch.stack((xv, yv), 2).expand((1, self.na, ny, nx, 2)).float()#anchor_grid时基于self.anchors得到的,那么self.anchorsanchor_grid = (self.anchors.clone() * self.stride) \.view((1, self.na, 1, 1, 2)).expand((1, self.na, ny, nx, 2)).float()return grid, anchor_grid

由yolov5.yaml 中可知 detect 的输入为来自17, 20, 23 提取的三个特征图。参数是[nc, anchor].
详细介绍可参考yolov5 - head 源码解释
注意
1)当training 的时候,返回的是预测的偏量值,当前向推理的时候才会计算实际的bouding box.

2)在_make_grid 时候,anchor_grid 时乘了对应的stride的。 此时的self.anchors是yaml 文件的anchors除以对应特征图的stride的。
3) anchor是用于每一个点对应的三个不同bouding box的基准的。根据预测的偏量y[…, 2:4]和宽高基准self.anchor_grid可以得到预测的宽和高。 再根据x,y中心坐标便可得到bouding box.

 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]  # wh

Detect函数的相关问题

1)Detect 初始化的参数 [nc, anchor, ch]

首先在建立模型时: yolo.parse_model()中找到Detect

由yolov5s.yaml文件可知,Detect的args是[nc, anchors], 然后又传入args.append([ch[x] for x in f])
,在这个函数ch是对应层的输出channel 数. 则这个就是第17, 20, 23层输出的特征图的chanel数量.

在yolo.Detect() 里,我们可以看到,这三个参数是用来建立Detect的三个卷积层用来计算预测值的。

self.m = nn.ModuleList(nn.Conv2d(x, self.no * self.na, 1) for x in ch)  # output

2) detect 的forward输入x为来自17, 20, 23 提取的三个特征图。

在yolo.Model._forward_once 函数里,我们可以看到整个模型的前向传播。

def _forward_once(self, x, profile=False, visualize=False):y, dt = [], []  # outputsfor m in self.model:if m.f != -1:  # if not from previous layerx = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f]  # from earlier layersif profile:self._profile_one_layer(m, x, dt)x = m(x)  # runy.append(x if m.i in self.save else None)  # save output if visualize:feature_visualization(x, m.type, m.i, save_dir=visualize)return x

y 收集了每一层的输出结果。Detect层 m.f 为[17,20,23],则其输入为三层的特征图。

3)Detect 里面的self.anchors

上面提到,yolo.Detect inference 里面的self.anchors是yaml 文件的anchors除以对应特征图的stride的。这个是在yolo.Model()初始化时 m.anchors /= m.sride.view(-1, 1, 1)。
以yolov5s.yaml 为例, 则anchors 转化如下

 if isinstance(m, Detect):s = 256  # 2x min stridem.inplace = self.inplacem.stride = torch.tensor([s / x.shape[-2] for x in self.forward(torch.zeros(1, ch, s, s))])  # forwardm.anchors /= m.stride.view(-1, 1, 1)check_anchor_order(m)self.stride = m.strideself._initialize_biases()  # only run once

4) autoanchor

这个功能实现在units.autoanchor.check_anchors中,通过聚类算法重新计算适合该数据集的anchors.
可参考yolov5自动anchor计算
在yolov5加入了autoanchor, 如果想用自己设置的anchor, 则需要禁止掉这个。
直接在训练时中加入 --noautoanchor就好

否则便会调用check_anchors, 利用聚类算法重新计算适合该数据集的anchors. 如果认为新生成的anchors比原来的好,便会用这个anchors替换原来的anchors.

train.py

yolov5 的 detect 层 与 anchor 机制相关推荐

  1. 修改yolov5的detect层,提高Triton推理服务的性能

    修改yolov5的detect层,提高Triton推理服务的性能 1. 测试方法 2. 修改前的性能指标 3. 具体步骤 3.1 clone ultralytics yolov5 repo 3.2 改 ...

  2. anchor free 目标检测_《目标检测》系列之二:目标检测中的Anchor机制回顾

    前段时间,YOLOv4&v5大火,很多人忽视了yolov5在anchor上的一些细节变化,因此,本文从Faster RCNN着手,逐步分析SSD.YOLOv4&v5的anchor机制. ...

  3. 【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )

    文章目录 一.MessageQueue 的 Java 层机制 二.MessageQueue 的 native 层阻塞机制 三.MessageQueue 的 native 层解除阻塞机制 三.Messa ...

  4. LTE网络RLC层的polling机制

    本文将从UE角度对LTE网络RLC层的polling机制进行详细阐述. 文章目录 前言 Polling的目的 Polling的触发条件 总结 参考文献 前言 在LTE网络中,RLC层提供了两种服务模式 ...

  5. anchor机制讲解

    在faster-rcnn中,有anchor这一知识点,我们在这篇博客中将主要讲解它. 先看以下内容: faster rcnn结构及代码讲解 理论知识 前面提到经过Conv layers后,图片大小变成 ...

  6. yolov5的detect.py代码详解

    目标检测系列之yolov5的detect.py代码详解 前言 哈喽呀!今天又是小白挑战读代码啊!所写的是目标检测系列之yolov5的detect.py代码详解.yolov5代码对应的是官网v6.1版本 ...

  7. yolov5 检测detect.py笔记

    参考 https://github.com/ultralytics/yolov5 带你一行行读懂yolov5代码,yolov5源码 试运行 安装环境 (yolo) ┌──(venv)─(***㉿kal ...

  8. Android系统中的Binder通信机制分析(7)- Java 层的 Binder 机制

    声明 其实对于Android系统Binder通信的机制早就有分析的想法,记得2019年6.7月份Mr.Deng离职期间约定一起对其进行研究的,但因为我个人问题没能实施这个计划,留下些许遗憾- 文中参考 ...

  9. YOLOv5的Tricks | 【Trick13】YOLOv5的detect.py脚本的解析与简化

    如有错误,恳请指出. 在之前介绍了一堆yolov5的训练技巧,train.py脚本也介绍得差不多了.之后还有detect和val两个脚本文件,还想把它们总结完. 在之前测试yolov5训练好的模型时, ...

最新文章

  1. 今日 Paper | 多人线性模型;身体捕捉;会话问答;自然语言解析;神经语义
  2. SSH项目的简单table及其分页框架
  3. 元素的子元素_从暂元里取出子元素 | Stata编程
  4. java数据库初始化参数,oracle数据库初始化参数设置--Java免费学习网
  5. 【深度学习篇】--神经网络中解决梯度弥散问题
  6. 容器私有云和持续发布都要解决哪些基础问题 第一集
  7. 使用rapid-framework自动生成struct2
  8. 统计 Github 2021 贡献过的开源项目
  9. 集腋成裘-10-ECharts -未知-03
  10. Spark精华问答 | Spark和Hadoop的架构区别解读
  11. 2020 华为 一面 二面 面经
  12. mysql ocp考试准备多久_MySQL OCP考试复习系列--开篇:了解MySQL考试
  13. 车载安卓屏刷鸿蒙,车载安卓大屏相比于原车导航种种优势
  14. 网页设计常用色彩搭配表
  15. BZOJ#4816. [Sdoi2017]数字表格
  16. Java 读取jpeg图片 Unsupported Image Type 异常
  17. Zookeeper之ZAB协议详解
  18. 原理图中VCC、VDD、VEE、VSS等符号的意思
  19. [转]谨慎使用Encoding.Default
  20. 什么是数值转换以及数值转换的方法

热门文章

  1. 【Python爬虫】Python网络爬虫案例:维基百科
  2. Android常用开源库整理汇总
  3. 电脑中的计算机为什么打不开怎么办,电脑当中msconfig打不开怎么办-电脑自学网...
  4. 战胜拖延—不要让拖延毁了自己
  5. 最近对物联网文章读后感
  6. 模板四十天之一 KMP
  7. linux 装tomcat吗,linux下安装tomcat的默认安装目录在哪?
  8. 【转】EBS财务系统总账模块(GL)会计期间状态总结
  9. MySQL数据库学习笔记(一)—— 基础概念
  10. 【综合实训】图书管理系统——需求规格说明书