Yolov5-v6.0模型详解

先看看yaml文件:可以知道6.0模型主要构成为conv、bottlenet、cs3、sppf、detect层

yaml文件如下:

# YOLOv5 v6.0 backbone

backbone:

# [from, number, module, args]

[[-1, 1, Conv, [64[l1] , 6[l2] , 2[l3] , 2[l4] ]],  # 0-P1/2   

#  来自上层,含瓶颈层数,本层类型,【输出通道,核大小,滑动,?分组】

#含瓶颈层数只对c3有效,其他层均为1

[-1, 1, Conv, [128, 3, 2]],  # 1-P2/4

[-1, 3[l5] , C3, [128]],

[-1, 1, Conv, [256, 3, 2]],  # 3-P3/8

[-1, 6, C3, [256]],

[-1, 1, Conv, [512, 3, 2]],  # 5-P4/16

[-1, 9, C3, [512]],

[-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32

[-1, 3, C3, [1024]],

[-1, 1, SPPF, [1024, 5]],  # 9

]

# YOLOv5 v6.0 head

head:

[[-1, 1, Conv, [512, 1, 1]],

[-1, 1, nn.Upsample, [None, 2, 'nearest']],

[[-1, 6], 1, Concat, [1]],  # cat backbone P4

[-1, 3, C3, [512, False]],  # 13

[-1, 1, Conv, [256, 1, 1]],

[-1, 1, nn.Upsample, [None, 2, 'nearest']],

[[-1, 4], 1, Concat, [1]],  # cat backbone P3

[-1, 3, C3, [256, False]],  # 17 (P3/8-small)

[-1, 1, Conv, [256, 3, 2]],

[[-1, 14], 1, Concat, [1]],  # cat head P4

[-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

[-1, 1, Conv, [512, 3, 2]],

[[-1, 10], 1, Concat, [1]],  # cat head P5

[-1, 3, C3, [1024, False]],  # 23 (P5/32-large)

[[17, 20, 23], 1, Detect[l6] , [nc, anchors]],  # Detect(P3, P4, P5)

]

以下根据图示看源码---------------------------------------------------------

class Conv(nn.Module):

# Standard convolution

def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups

super().__init__()

self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)

self.bn = nn.BatchNorm2d(c2)

self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())

def forward(self, x):

return self.act(self.bn(self.conv(x)))

def forward_fuse(self, x):

return self.act(self.conv(x))

class Bottleneck(nn.Module):

# Standard bottleneck

def __init__(self, c1, c2, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, shortcut, groups, expansion

super().__init__()

c_ = int(c2 * e)  # hidden channels  可以增加通道数,扩充网络宽度

self.cv1 = Conv(c1, c_, 1, 1)

self.cv2 = Conv(c_, c2, 3, 1, g=g)  #核是3

self.add = shortcut and c1 == c2

def forward(self, x):

return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))

class C3(nn.Module):

# CSP Bottleneck with 3 convolutions

def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion

super().__init__()

c_ = int(c2 * e)  # hidden channels  可以扩充网络宽度

self.cv1 = Conv(c1, c_, 1, 1)

self.cv2 = Conv(c1, c_, 1, 1)

self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)  concatconv输入通道要是2 * c_,

self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))

#通道数不会变化都是c_

# self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])

def forward(self, x):

return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))

sppf图示:

class SPPF(nn.Module):   # SPPF 输入通道c1,输出通道c2,大小不变

# Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher

def __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))  

super().__init__()

c_ = c1 // 2  # hidden channels

self.cv1 = Conv(c1, c_, 1, 1)  #核1,滑动1

self.cv2 = Conv(c_ * 4, c2, 1, 1) #

self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)  #最大池化,滑动1,此处大小不变

def forward(self, x):

x = self.cv1(x)

with warnings.catch_warnings():

warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warning

y1 = self.m(x)

y2 = self.m(y1)

return self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1))

detect层是最后一层:

如果是训练时,

(1)3个head,经过conv,

(2)每层原来数据为4维:[batch,anchor*(class+5),h,w] 经过处理后变为5维:

[batch,anchor,h,w,class+5]

见下面绿色代码

如果是预测,3个head预测结果经过(1)(2)

(3)conv后sigmoid变为0~1,然后转化到格子空间。

(4)3个头的数据转化为(batch, _ ,85)然后cat在一起

#-----------------detct源码-------------------------------------------------------

class Detect(nn.Module):#如果是训练,输出3个张量,如果是预测输出【【batch,_,类+5】

stride = None  # strides computed during build

onnx_dynamic = False  # ONNX export parameter

def __init__(self, nc=80, anchors=(), ch=(), inplace=True):  # detection layer

#ch=()应该是3个头的通道数

super().__init__()

self.nc = nc  # number of classes

self.no = nc + 5  # number of outputs per anchor

self.nl = len(anchors)  # number of detection layers

self.na = len(anchors[0]) // 2  # number of anchors,一般为3

self.grid = [torch.zeros(1)] * self.nl  # init grid

self.anchor_grid = [torch.zeros(1)] * self.nl  # init anchor grid

self.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 conv

#ch 输入的3个头输出的通道【128,256,512】

self.inplace = inplace  # use in-place ops (e.g. slice assignment)

def forward(self, x):

z = []  # inference output

for i in range(self.nl):  #3个头分别处理 nl是 检测层的数量3

x[i] = self.m[i](x[i])  # conv

bs, _, 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()

#4维转为5维 x(bs,3,20,20,85)

if not self.training:  # inference,如果不是训练,把数据处理成(batch,_,85)

if 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()  #0~1化

#下面把预测映射到格子空间尺度。预测使用下面结果 y

if self.inplace:

y[..., 0:2] = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xy

y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh

else:  # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953

xy = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xy

wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh

y = 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)

#如果是训练直接返回x(3个头),是预测把3个头的数据转化为(batch, _ ,85)然后cat在一起


[l1]输出通道

[l2]核大小

[l3]滑动步长

[l4]可能是分组

[l5]C3中残差模块个数

其他层都为1

[l6]3层预测结果0~1,转为真实的结果输出

Yolov5-v6.0模型详解相关推荐

  1. tensorRT 部署 YOLOV5模型详解

    tensorRT 部署 YOLOV5模型详解 第一步: 下载tensorRT库 https://developer.nvidia.com/nvidia-tensorrt-8x-download 欢迎使 ...

  2. Transformer 模型详解

    Transformer 是 Google 的团队在 2017 年提出的一种 NLP 经典模型,现在比较火热的 Bert 也是基于 Transformer.Transformer 模型使用了 Self- ...

  3. TensorFlow Wide And Deep 模型详解与应用 TensorFlow Wide-And-Deep 阅读344 作者简介:汪剑,现在在出门问问负责推荐与个性化。曾在微软雅虎工作,

    TensorFlow Wide And Deep 模型详解与应用 TensorFlow Wide-And-Deep 阅读344  作者简介:汪剑,现在在出门问问负责推荐与个性化.曾在微软雅虎工作,从事 ...

  4. TensorFlow Wide And Deep 模型详解与应用

    Wide and deep 模型是 TensorFlow 在 2016 年 6 月左右发布的一类用于分类和回归的模型,并应用到了 Google Play 的应用推荐中 [1].wide and dee ...

  5. 数学建模——智能优化之模拟退火模型详解Python代码

    数学建模--智能优化之模拟退火模型详解Python代码 #本功能实现最小值的求解#from matplotlib import pyplot as plt import numpy as np imp ...

  6. 数学建模——智能优化之粒子群模型详解Python代码

    数学建模--智能优化之粒子群模型详解Python代码 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplo ...

  7. 数学建模——支持向量机模型详解Python代码

    数学建模--支持向量机模型详解Python代码 from numpy import * import random import matplotlib.pyplot as plt import num ...

  8. 数学建模——一维、二维插值模型详解Python代码

    数学建模--一维.二维插值模型详解Python代码 一.一维插值 # -*-coding:utf-8 -*- import numpy as np from scipy import interpol ...

  9. 数学建模——线性规划模型详解Python代码

    数学建模--线性规划模型详解Python代码 标准形式为: min z=2X1+3X2+x s.t x1+4x2+2x3>=8 3x1+2x2>=6 x1,x2,x3>=0 上述线性 ...

最新文章

  1. AJAX只支持字符类数据返回,不支持文件下载
  2. 码上用它开始Flutter混合开发——FlutterBoost
  3. json符号解释大全_水电图纸图例大全,电气、弱电、给排水常用图例
  4. 外媒:ATT宣布加入SD-WAN阵营
  5. Linux运行级别介绍和root忘记密码找回方法
  6. 语音识别模型_语音 识别_语音识别 - 云+社区 - 腾讯云
  7. openfiledialog选择文件会占用文件_铁皮文件柜的尺寸规格如何选择?选购花都文件柜要注意的问题...
  8. 小学生c语言编程入门教程_学生编程语言
  9. 基于163邮件服务器实现邮箱验证
  10. 自然语言处理之分词技术
  11. 2021年,各类显卡的计算能力对比,天梯图
  12. 跨时钟域信号处理(二)——异步fifo的Verilog实现(附同步fifo的实现)
  13. 设置等级对照表的表格
  14. java smack 例子_关于JAVA利用smack连接openfire的jar依赖问题
  15. 高德地图车机版增加地标性品牌图标 让你“约会”无压力
  16. Postgresql opm监控工具部署
  17. 《寒江独钓》键盘过滤部分程序修改
  18. 这届铲屎官不错,既舍得花钱,又会科学养猫养狗
  19. WEB前端 HTML 基本标签
  20. Oralcle中特殊字符的处理

热门文章

  1. 《自然杂志》19卷4期的 ‘探索物理学难题的科学意义'的 97个悬而未决的难题
  2. php文字外链,锚文本外链如何制作?
  3. 法大大联合清华大学法学院研讨“电子证据与劳动法”
  4. SaaS是什么?企业为什么要有SaaS系统?
  5. 烦人的后台首页index.jsp弄好了
  6. 解决文字与图片始终不并排的问题
  7. 效用最大化准则:离散选择模型的核心(二项Logit模型)——离散选择模型之九
  8. 自己实现MATLAB支持向量化输入输出的零阶修正贝塞尔函数
  9. 愿随命运颠沛流离——《孤儿列车》读后感
  10. 制作一个银行卡登录系统