YOLOv5 网络组件与激活函数 代码理解笔记

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 最近在看YOLOv5 第6个版本的代码,记录了一下笔记,分享一下。首先看了网络结构、网络组件,对应代码models\common.py。然后看了激活函数,对应代码utils\activations.py。

注意:请大家,主要看参考链接的内容!请主要看参考链接的内容!请主要看参考链接的内容!

【1】python 把if 写在一行的两种方式

a=1 if a>0 else 0   如果a>0,a赋值1,否则赋值0。

参考:https://www.cnblogs.com/Lara1798/p/12989334.html


【2】Python isinstance() 函数

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。考虑继承关系。

>>>a = 2

>>> isinstance (a,int)

True

>>> isinstance (a,str)

False

>>> isinstance (a,(str,int,list))    # 是元组中的一个返回 True

True

class A:

   pass

 

class B(A):

   pass

isinstance(A(), A)    # returns True

isinstance(B(), A)    # returns True

参考:https://www.runoob.com/python/python-func-isinstance.html


【3】python - 理解python嵌套一行for循环

s.split() for s in raw_sentences

相当于:

for s in raw_sentences:

   s.split()

参考:https://www.coder.work/article/3128601


【4】python 单斜杠/和双斜杆//的区别

不管是单斜杆还是双斜杆,都是属于除法运算符;

单斜杠是我们最常见的除法计算符号;

1、它们最大的区别是返回的结果不一样,单斜杠计算的结果是保留若干小数;而双斜杆的结果是保留最小整数(类似于向下取);

2、A//B的返回类型取决与A和B的数据类型,只有A和B都为int型时结果才是int(此时表示两数正除取商);

参考:https://blog.csdn.net/qq_39284106/article/details/108208239?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link


【5】in的详解

1.用于判断(查找)元素是否在可迭代对象中;

xxx in XXX :判断xxx是否在XXX中, 如果在,返回真,不在,返回假。

xxx not in XXX :判断xxx是否不在XXX中, 如果不在,返回真,在,返回假

if x in X

if x not in X

while x in X

while x not in X

2.用于逐个取可迭代对象的元素, 一般要配合for使用:

我们可能常用到的可迭代的对象包括:string, list, dict, tuple, generator, range函数

list_1 = [n for n in range(10)]

for i in list:

   print(i)


【6】group convolution (分组卷积)

简介:输入feature map分成组,每个卷积核也相应地分成组,在对应的组内做卷积;用了同等的参数量运算量生成了g个feature map;

作用:group conv常用在轻量型高效网络中,因为它用少量的参数量和运算量就能生成大量的feature map,大量的feature map意味着能够编码更多的信息!

参数g:输入参数,分组数量

《深度分离卷积》是分组卷积的一种特殊形式,其分组数,其中是feature map的通道数。

即把每个feature map分为一组,分别在组内做卷积,每组内的单个卷积核尺寸为,组内一个卷积核生成一个feature map。

参考:https://www.jianshu.com/p/a936b7bc54e3


【7】SILU 激活函数(swish)

简介:按元素应用 Sigmoid 线性单元 (SiLU) 函数。SiLU 函数也称为 swish 函数。

公式:silu(x)=x∗σ(x),where σ(x) is the logistic sigmoid.

Swish处处可导,连续光滑。另外还有一个特点就是Swish并非一个单调的函数。但是swish也并非没有任何缺点,最大的缺点就是计算量大,本来sigmoid函数就不容易计算。

参考:https://zhuanlan.zhihu.com/p/387167769

参考:https://pytorch.org/docs/stable/generated/torch.nn.SiLU.html

参考:https://august-us.blog.csdn.net/article/details/106210576?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.fixedcolumn&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.fixedcolumn


【8】DWConv(Depthwise Conv)深度卷积

是分组卷积Group Conv的极端,即分组g =Cin = Cout = 通道数

参考:https://zhuanlan.zhihu.com/p/45209964

参考:https://zhuanlan.zhihu.com/p/149564248

参考:https://zhuanlan.zhihu.com/p/80041030


【9】layer-normlization

Normalization 有很多种,但是它们都有一个共同的目的,那就是把输入转化成均值为 0 方差为1的数据。

我们在把数据送入激活函数之前进行normalization(归一化),因为我们不希望输入数据落在激活函数的饱和区,发生梯度消失的问题,使得我们的模型训练变得困难。

BN的主要思想是: 一个batch里的同一通道 上进行归一化

LN的主要思想是:一个样本里的不同通道上计算均值和方差,而不是 BN 那种在批方向计算均值和方差!

参考:https://blog.csdn.net/weixin_45069761/article/details/107834049


【10】Transformer各层网络结构详解

Transformer模型中也采用了 encoer-decoder 架构。但其结构相比于Attention更加复杂,论文中encoder层由6个encoder堆叠在一起,decoder层也一样。

encoder,包含两层,一个self-attention层和一个前馈神经网络,self-attention能帮助当前节点不仅仅只关注当前的词,从而能获取到上下文的语义。

decoder也包含encoder提到的两层网络,但是在这两层中间还有一层attention层,帮助当前节点获取到当前需要关注的重点内容。

参考:https://www.cnblogs.com/mantch/p/11591937.html


【11】Bottleneck layer结构 瓶颈层

Bottleneck layer又称之为瓶颈层,使用的是1*1的卷积神经网络。之所以称之为瓶颈层,是因为长得比较像一个瓶颈。

经过 1*1 的网络,中间那个看起来比较细。像一个瓶颈一样。

使用 1*1 的网络结构很方便改变维度。灵活设计网络,并且减小计算量。

参考:https://zhuanlan.zhihu.com/p/98692254

参考:https://blog.csdn.net/duan19920101/article/details/104349188

shortcut:是否给bottleneck 结构添加shortcut连接,添加后即为ResNet模块;(shortcut(捷径),跳跃连接,输入直接连接到输出的那条支路)

这里使用的shortcut也成为identity分支,可以理解为恒等映射,另一个分支被称为残差分支(Residual分支)。

参考:https://www.cnblogs.com/dan-baishucaizi/p/14267602.html#3bottleneck%E7%93%B6%E9%A2%88%E5%B1%82


【12】BottleneckCSP

BottlenneckCSP分为两部分,Bottlenneck以及CSP。Bottlenneck其实就是经典的残差结构,先是1x1的卷积层(conv+batch_norm+leaky relu),然后再是3x3的卷积层,最后通过残差结构与初始输入相加。

也就是说将原输入分成两个分支,分别进行卷积操作使得通道数减半,然后分支一进行Bottlenneck x N操作,随后concat分支一和分支二,从而使得BottlenneckCSP的输入与输出是一样的大小,目的是为了让模型学习到更多的特征。

很多人都对yaml文件中[[-1, 3, BottleneckCSP, [1024, False]]False的作用不太理解,其实这就是关闭了shortcut的选项。

CSP瓶颈层结构在Bottleneck部分存在一个可修改的参数n,标识使用的Bottleneck结构个数!

左侧(Bottleneck * n)这一条也是我们的主分支,是对残差进行学习的主要结构,

右侧分支nn.Conv2d实际上是shortcut分支实现不同stage的连接(CSP的思想实现)。

参考:https://www.cnblogs.com/dan-baishucaizi/p/14267602.html#4bottleneckcsp-csp%E7%93%B6%E9%A2%88%E5%B1%82

参考:https://zhuanlan.zhihu.com/p/164627427


【13】C3

C3模块,其结构作用基本相同均为CSP架构,只是在修正单元的选择上有所不同,其包含了3个标准卷积层以及多个Bottleneck模块(数量由配置文件.yaml的n和depth_multiple参数乘积决定)

C3相对于BottleneckCSP模块不同的是,经历过残差输出后的Conv模块被去掉了,concat后的标准卷积模块中的激活函数也由LeakyRelu变为了SiLU(同上)。

该模块是对残差特征进行学习的主要模块,其结构分为两支,一支使用了上述指定多个Bottleneck堆叠和3个标准卷积层,另一支仅经过一个基本卷积模块,最后将两支进行concat操作。

参考:https://blog.csdn.net/zebra_0/article/details/120769404


【14】空间金字塔池化(Spatial Pyramid Pooling, SPP)

卷积神经网络(CNN)由卷积层和全连接层组成,其中卷积层对于输入数据的大小并没有要求,

唯一对数据大小有要求的则是第一个全连接层,因此基本上所有的CNN都要求输入数据固定大小,

例如著名的VGG模型则要求输入数据大小是 (224*224) 。

固定输入数据大小有两个问题:

1.很多场景所得到数据并不是固定大小的,例如街景文字基本上其高宽比是不固定的(图片输入也不固定)

2.可能你会说可以对图片进行切割,但是切割的话很可能会丢失到重要信息。

SPP的提出就是为了解决CNN输入图像大小必须固定的问题,从而可以使得输入图像高宽比和大小任意。

首先是输入层(input image),其大小可以是任意的

进行卷积运算,到最后一个卷积层(图中是\(conv_5\))输出得到该层的特征映射(feature maps),其大小也是任意的

下面进入SPP层

我们先看最左边有16个蓝色小格子的图,它的意思是将从\(conv_5\)得到的特征映射分成16份,另外16X256中的256表示的是channel,即SPP对每一层都分成16份(不一定是等比分,原因看后面的内容就能理解了)。

中间的4个绿色小格子和右边1个紫色大格子也同理,即将特征映射分别分成4X256和1X256份

那么将特征映射分成若干等分是做什么用的呢? 我们看SPP的名字就是到了,是做池化操作,一般选择MAX Pooling,即对每一份进行最大池化

注意上面划分成多少份是可以自己是情况设置的。

参考:https://cloud.tencent.com/developer/article/1076488

参考:https://blog.csdn.net/weixin_43881803/article/details/106350160?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link


【15】Concat

沿维度连接张量列表


【16】深度解读轻量网络GhostNet、Ghost bottlenecks

轻量级卷积神经网络设计,解决“特征图冗余”,减少模型参数和计算量,精度保持差不多。

Ghost Module则分为两步操作来获得与普通卷积一样数量的特征图

第一步:少量卷积(比如正常用32个卷积核,这里就用16个,从而减少一半的计算量);

第二步:cheap operations,如图中的Φ表示,Φ是诸如3*3的卷积,并且是逐个特征图的进行卷积(Depth-wise convolutional)。

参考:https://www.bilibili.com/read/cv5655222/


【17】SPPF

原理和SPP基本一致,但用到的“池化核”设计不一样;(数量)

SPP:  “池化核”k=(5, 9, 13),加上一个1*1的;

SPPF:“池化核”k=(5),加上一个1*1的;

操作:MaxPool2d


【18】Focus

简介:Focus模块在v5中是图片进入backbone前,对图片进行切片操作;

操作:在一张图片中每隔一个像素拿到一个值,类似于邻近下采样,这样就拿到了四张图片,四张图片互补,长的差不多,但是没有信息丢失

效果:x(b,c,w,h) -> y(b,4c,w/2,h/2)

这样一来,将W、H信息就集中到了通道空间,输入通道扩充了4倍,即拼接起来的图片相对于原先的RGB三通道模式变成了12个通道,

最后将得到的新图片再经过卷积操作,最终得到了没有信息丢失情况下的二倍下采样特征图。

参考:https://blog.csdn.net/qq_39056987/article/details/112712817


【19】混合精度

简介:混合精度是指训练时在模型中同时使用 16 位和 32 位浮点类型,从而加快运行速度,减少内存使用的一种训练方法。

 .通过让模型的某些部分保持使用 32 位类型以保持数值稳定性,可以缩短模型的单步用时,而在评估指标(如准确率)方面仍可以获得同等的训练效果。.

效果:内存占用更少,计算更快。( float32和半精度float16 )

通用的模型 fp16 占用的内存只需原来的一半,模型占用的内存更小,训练的时候可以用更大的batchsize。

目前的不少GPU都有针对 fp16 的计算进行优化。论文指出:在近期的GPU中,半精度的计算吞吐量可以是单精度的 2-8 倍;

Float16的问题:

那既然fp16像上面说的那么好,那么是否全部都使用 fp16 即可了呢? 当然不是,如果fp16那么好,那又何来 『混合精度』这么一说呢。

数据溢出问题:Overflow / Underflow。深度学习而言,最大的问题在于 Underflow(下溢出),在训练后期,例如激活函数的梯度会非常小, 甚至在梯度乘以学习率后,值会更加小。

舍入误差(Rounding Error)。

参考:https://zhuanlan.zhihu.com/p/103685761

参考:https://zhuanlan.zhihu.com/p/408610877


【20】消融实验(ablation study)

设立对照组:通过去除某个模块的作用,来证明该模块的必要性,如果消融实验后得到结果不好或者性能大幅下降,说明该模块起到了作用。

有一点像控制变量。

参考:https://blog.csdn.net/DragonGirI/article/details/107356658

参考:https://blog.csdn.net/Cai_deLong/article/details/110903263?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7Eessearch%7Evector-6.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7Eessearch%7Evector-6.essearch_pc_relevant


【21】GFLOPs、FLOPs、FLOPS

FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为计算速度。是一个衡量硬件性能的指标。

FLOPs:注意s小写,是floating point operations的缩写(s表复数),意指浮点运算数,理解为计算量。可以用来衡量算法/模型的复杂度。

1GFlops = 1,000MFlops。

一个 MFLOPS (megaFLOPS) 等于每秒1百万 (=10^6) 次的浮点运算,

一个 GFLOPS (gigaFLOPS) 等于每秒10亿 (=10^9) 次的浮点运算,

一个 TFLOPS (teraFLOPS) 等于每秒1万亿 (=10^12) 次的浮点运算,

一个 PFLOPS (petaFLOPS) 等于每秒1千万亿 (=10^15) 次的浮点运算。

参考:https://zhuanlan.zhihu.com/p/137719986

参考:https://baike.baidu.com/item/Gflops/989595


【22】CUDA NMS、Fast NMS、Cluster NMS、Matrix NMS

NMS运算效率的瓶颈在哪?答案自然是IoU计算,及顺序迭代,IOU最大的框 抑制 其他IOU小的框。

参考:https://zhuanlan.zhihu.com/p/157900024

参考:https://blog.csdn.net/john_bh/article/details/107364782

参考:https://githubmemory.com/repo/APeiZou/yolov5


【23】smooth_BCE 损失函数

这个函数是一个标签平滑的策略(trick),是一种在 分类/检测 问题中,防止过拟合的方法。

效果:这实际上是一种正则化策略,减少了真实样本标签的类别在计算损失函数时的权重,最终起到抑制过拟合的效果。

函数:

def smooth_BCE(eps=0.1):

   """用在ComputeLoss类中  标签平滑操作  [1, 0]  =>  [0.95, 0.05]

   :params eps: 平滑参数

   :return positive, negative label smoothing BCE targets  两个值分别代表正样本和负样本的标签取值

           原先的正样本=1 负样本=0 改为 正样本=1.0 - 0.5 * eps  负样本=0.5 * eps

   """

   return 1.0 - 0.5 * eps, 0.5 * eps

返回正、负样本的标签取值

参考:https://github.com/ultralytics/yolov3/issues/238#issuecomment-598028441

参考:https://blog.csdn.net/qq_38253797/article/details/119444854

参考:https://blog.csdn.net/qq_35447659/article/details/107818462?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1.essearch_pc_relevant&spm=1001.2101.3001.4242.2


【24】Hardswish 激活函数

hardswish激活函数。在MobileNetV3架构中被提出,相较于swish函数,具有数值稳定性好,计算速度快等优点,

参考:https://pytorch.org/docs/stable/generated/torch.nn.Hardswish.html

参考:https://www.bookstack.cn/read/paddlepaddle-2.0-zh/9550b2db596b3c48.md

具体原理请参考: https://arxiv.org/pdf/1905.02244.pdf

class Hardswish(nn.Module):  # export-friendly version of nn.Hardswish()

   @staticmethod

   def forward(x):

       # return x * F.hardsigmoid(x)  # for torchscript and CoreML

       return x * F.hardtanh(x + 3, 0.0, 6.0) / 6.0  # for torchscript, CoreML and ONNX

hardsigmoid 激活函数

参考:https://pytorch.org/docs/stable/generated/torch.nn.Hardsigmoid.html

hardtanh 激活函数

参考:https://pytorch.org/docs/stable/generated/torch.nn.Hardtanh.html


【25】Mish 激活函数

Mish =  x * F.softplus(x).tanh() 或 = x * (torch.tanh(F.softplus(x))) 或 x * tanh(ln(1 + exp(x)))

Mish是一个光滑非单调的激活函数

参考:https://blog.csdn.net/moxibingdao/article/details/108289489

参考:https://zhuanlan.zhihu.com/p/84418420

F.softplus(x) 参考:https://pytorch.org/docs/stable/generated/torch.nn.Softplus.html

Softplus(x)= (1/β) ∗log(1+exp(β∗x))

【Swish Mish 激活函数 理解】https://blog.csdn.net/bu_fo/article/details/110224213


【26】FRelU 激活函数

FReLU的形式为y = max(x,T(x)),其中T(·)是二维空间条件(2D spatial condition)

此外,空间条件spatial condition以简单的方式实现了像素级建模能力,并通过常规卷积捕获了复杂的视觉layouts。

ReLU和PReLU分别表示为y = max(x,0)和y = max(x,px)

y=max(x,T(x)),其中T(x)代表简单高效的空间上下文特征提取器。

class FReLU(nn.Module):

   def __init__(self, c1, k=3):  # ch_in, kernel

       super().__init__()

       self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False)

       self.bn = nn.BatchNorm2d(c1)

   def forward(self, x):

       return torch.max(x, self.bn(self.conv(x)))

参考:https://blog.csdn.net/sinat_17456165/article/details/107603052


【27】AconC 激活函数

作者提出了一系列的ACON函数,其中 ReLU 是 Maxout 的一种特殊形式,Swish 是 ACON 的一种特殊形式

ACON 函数本质就是一个具有学习能力的Layer;

   r""" ACON activation (activate or not).

   AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter

   according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.

   """

参考:https://zhuanlan.zhihu.com/p/359633625

参考:https://zhuanlan.zhihu.com/p/363274457


【28】MetaAconC 激活函数

r""" ACON activation (activate or not).

   MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network

   according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.

   """

参考:https://zhuanlan.zhihu.com/p/359633625

参考:https://aistudio.baidu.com/aistudio/projectdetail/1871546?channelType=0&channel=0

本文只供大家参考与学习,谢谢。

相关文章
|
13天前
|
机器学习/深度学习 测试技术 Ruby
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
24 2
|
13天前
|
计算机视觉
YOLOv5改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)
YOLOv5改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)
13 3
|
13天前
|
机器学习/深度学习 测试技术 Ruby
YOLOv8改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
YOLOv8改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
18 0
|
13天前
|
机器学习/深度学习 测试技术 计算机视觉
YOLOv5改进 | 主干篇 | 低照度增强网络Retinexformer改进黑夜目标检测 (2023.11最新成果,全网独家首发)
YOLOv5改进 | 主干篇 | 低照度增强网络Retinexformer改进黑夜目标检测 (2023.11最新成果,全网独家首发)
14 0
|
13天前
|
机器学习/深度学习 编解码 算法
YOLOv5改进 | 主干篇 | 低照度增强网络PE-YOLO改进主干(改进暗光条件下的物体检测)
YOLOv5改进 | 主干篇 | 低照度增强网络PE-YOLO改进主干(改进暗光条件下的物体检测)
17 0
|
13天前
|
机器学习/深度学习 网络架构 计算机视觉
YOLOv5改进 | 主干篇 | 12月最新成果UniRepLknet特征提取网络(附对比试验效果图)
YOLOv5改进 | 主干篇 | 12月最新成果UniRepLknet特征提取网络(附对比试验效果图)
22 0
YOLOv5改进 | 主干篇 | 12月最新成果UniRepLknet特征提取网络(附对比试验效果图)
|
13天前
|
机器学习/深度学习 编解码 数据可视化
YOLOv5改进 | 主干篇 | 12月份最新成果TransNeXt特征提取网络(全网首发)
YOLOv5改进 | 主干篇 | 12月份最新成果TransNeXt特征提取网络(全网首发)
23 0
|
13天前
|
机器学习/深度学习 编解码 自然语言处理
YOLOv5改进 | 主干篇 | RevColV1可逆列网络(特征解耦助力小目标检测)
YOLOv5改进 | 主干篇 | RevColV1可逆列网络(特征解耦助力小目标检测)
15 2
|
13天前
|
机器学习/深度学习
YOLOv5改进 | 主干篇 | 轻量级网络ShuffleNetV1(附代码+修改教程)
YOLOv5改进 | 主干篇 | 轻量级网络ShuffleNetV1(附代码+修改教程)
16 1
|
20小时前
|
机器学习/深度学习 数据采集 算法
基于yolov2深度学习网络的血细胞检测算法matlab仿真
基于yolov2深度学习网络的血细胞检测算法matlab仿真

相关产品

  • 大数据开发治理平台 DataWorks
  • 检索分析服务 Elasticsearch版
  • 日志服务