【目标检测】YOLOv5:模型构建解析
前言
最近在看一些目标检测的最新论文和代码,大多数都是在YOLOv5的基础上进行魔改。
改的最多的基本是原版本的网络结构,这篇博文就从源码角度来解析YOLOv5中,模型是如何构建出来的。
本文使用的是YOLOv5-5.0版本。
模型的深度和宽度
在YOLOv5中,模型结构基本是写在了.yaml
中,5.0版本的YOLOv5共有yolov5s,yolov5m,yolov5l和yolov5x四个版本,这四个版本的模型结构一模一样,不同的是两个参数depth_multiple
和width_multiple
,分别表示模型的深度因子和宽度因子。
在yolo.py
中,parse_model
函数下的这行代码将深度因子和宽度因子进行读取和赋值。
anchors, nc, gd, gw = d['anchors'], d['nc'], d['depth_multiple'], d['width_multiple']
depth_multiple
首先看深度因子,深度因子参与运算的是这行代码:
n = max(round(n * gd), 1) if n > 1 else n # depth gain
这里的n表示结构的个数,也就是说,n是个>=1的整数(起码得有一个,否则不存在),depth_multiple越大,那么模型结构的个数也越多,因此网络就更”深“。
width_multiple
再看宽度因子,宽度因子参与运算的是这行代码:
c2 = make_divisible(c2 * gw, 8)
这个c2代表当前层的输出的通道(channel)数,也就是说,width_multiple越大,那么模型结构的通道数越多,因此看起来就更”宽“。
网络构建
下面到了最核心的网络构建部分,从YOLOv3开始,YOLO系列的网络结构都分成骨干(backbone),颈部(neck)和头部(head),但是在代码中,颈部和头部被统一写在了head之中。
backbone
以yolov5s为例:
首先来看backbone部分,backbone的代码如下:
backbone:
# [from, number, module, args]
# from表示当前模块的输入来自那一层的输出,-1表示来自上一层的输出
# number表示本模块重复的次数,1表示只有一个,3表示重复3次
# module: 模块名
[[-1, 1, Focus, [64, 3]], # 0-P1/2 [3, 32, 3]
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [32, 64, 3, 2]
[-1, 3, C3, [128]], # 2 [64, 64, 1]
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [64, 128, 3, 2]
[-1, 9, C3, [256]], # 4 [128, 128, 3]
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16 [128, 256, 3, 2]
[-1, 9, C3, [512]], # 6 [256, 256, 3]
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 [256, 512, 3, 2]
[-1, 1, SPP, [1024, [5, 9, 13]]], # 8 [512, 512, [5, 9, 13]]
[-1, 3, C3, [1024, False]], # 9 [512, 512, 1, False]
]
这里拿【YOLOV5-5.x 源码解读】yolov5s.yaml这个博主绘制的网络结构图进行对比。
图中的四个参数(例如[1,3,640,640])分别表示一个batch中的样本数、通道数、图像长宽。
以第一个卷积层为例,它的参数是这样算的:
输入[1,32,320,320],卷积层参数是128个out_channel,3像素的kernel_size,2像素的stride
卷积计算公式如下:
out_size = (in_size - K + 2P)/ S +1
那么,输出特征图的长宽为round((320-3)/2 + 1)=160,因此输出特征图尺寸为160x160,这里初看可能会产生疑惑的是卷积层定义的out_channel明明是128,为什么输出channel却变成了64?其实,这就是前面提到宽度因子在起作用。yolov5s的宽度因子为0.5,这就导致真实的out_channel = 128x0.5 = 64。
因此,输入结果就变成了(1,64,160,160)
其它模块的计算方式类似。
第一个"-1“表示,输入来自上一个模块,这里全都是-1,即模块是一溜子的顺序下来,和图对比可以一一对应上。
head
首先来看head部分,head的代码如下:
head:
[[-1, 1, Conv, [512, 1, 1]], # 10 [512, 256, 1, 1]
[-1, 1, nn.Upsample, [None, 2, 'nearest']], # 11 [None, 2, 'nearest']
[[-1, 6], 1, Concat, [1]], # 12 cat backbone P4 [1]
[-1, 3, C3, [512, False]], # 13 [512, 256, 1, False]
[-1, 1, Conv, [256, 1, 1]], # 14 [256, 128, 1, 1]
[-1, 1, nn.Upsample, [None, 2, 'nearest']], #15 [None, 2, 'nearest']
[[-1, 4], 1, Concat, [1]], # 16 cat backbone P3 [1]
[-1, 3, C3, [256, False]], # 17 (P3/8-small) [256, 128, 1, False]
[-1, 1, Conv, [256, 3, 2]], # 18 [128, 128, 3, 2]
[[-1, 14], 1, Concat, [1]], # 19 cat head P4 [1]
[-1, 3, C3, [512, False]], # 20 (P4/16-medium) [256, 256, 1, False]
[-1, 1, Conv, [512, 3, 2]], # 21 [256, 256, 3, 2]
[[-1, 10], 1, Concat, [1]], # 22 cat head P5 [1]
[-1, 3, C3, [1024, False]], # 23 (P5/32-large) [512, 512, 1, False]
[[17, 20, 23], 1, Detect, [nc, anchors]], # 24 Detect(P3, P4, P5)
]
我在图中标了序号,对照代码看应该比较清楚。
注,每一个检测头使用1x1的卷积核来调整维度,这个卷积核不包括在.yaml
文件中。
最后一行输出17,20,23,即使用这三个卷积层输出的特征图进行检测,按照论文的说法即是对应大目标,中目标和小目标。
相关文章
- (Hive)史上最难解析的json字符串解析出来了!!
- 爬虫scrapy快速解析
- parseInt()解析整数与parsetFloat()解析浮点数
- kubernetes多节点部署解析
- php url伪静态化解析
- Spark修炼之道(进阶篇)——Spark入门到精通:第九节 Spark SQL运行流程解析
- SAP CRM Survey调查问卷的模型设计原理解析
- Atitit.spring体系结构大总结 1. Spel表达式解析1 2. Srping mvc1 3. Ioc4 3.1. ApplicationContext在BeanFactory的基础
- 揭开SAP Fiori编程模型规范里注解的神秘面纱 - @OData.publish工作原理解析
- 【Android源码解析】一篇就够“路由、网络层、UI层、通信层....百大框架”源码解析,阿里P8神级之作
- Android RecyclerView之SnapHelper原理解析(一)
- 【ChatGPT】ChatGPT的核心算法原理图文解析、大模型训练过程和数据集来源
- 【ChatGPT】GPT 原理解析:Transformer 模型的核心思想:注意力机制(Attention Mechanism)的核心原理是什么?并给出数学公式代码实例。
- 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )
- 【高并发】两种异步模型与深度解析Future接口
- Golang-Channel原理解析
- 目标检测00-09:mmdetection(Foveabox为例)-源码无死角解析(2)-模型构建总览
- 风格迁移2-06:MUNIT(多模态无监督)-源码无死角解析(3)-模型框架(前向传播)
- 风格迁移1-08:Liquid Warping GAN(Impersonator)-源码无死角解析(3)-模型总体结构
- 云计算|OpenStack|社区版OpenStack安装部署文档(十二--- openstack的网络模型解析---Rocky版)
- OSI的物理层 数据通信 数据通信系统的模型 信道的基本概念 编码方式 调制方法 香农公式 信噪比 硬核解析 图解刨析 宫廷解释
- “变形金刚”为何强大:从模型到代码全面解析Google Tensor2Tensor系统
- 布莱克斯科尔斯模型(三)热传导方程的解析解