YOLOv5源码(使用的是YOLOv5 6.1版本)地址:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
参考笔记:
YOLOv5改进系列(六) 更换空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC_rfb结构替换sppf-CSDN博客
目录
1.SPP(Spatial Pyramid Pooling)
1.SPP(Spatial Pyramid Pooling)
SPP是何凯明在2015年的论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》中提出的
SPP全称为空间金字塔池化结构,主要是为了解决两个问题:
(1)有效避免了对图像区域裁剪、缩放操作导致的图像失真等问题
(2)解决了卷积神经网络对图相关重复特征提取的问题,大大提高了产生候选框的速度,且节省了计算成本
SPP
YOLOv4中将SPP用于Neck部分,SPP对后面的SPPF等各种变形的空间金字塔池化结构的提出有很大的影响
SPP的代码实现:
class SPP(nn.Module):
# 空间金字塔池化 (SPP) 层,用于捕获不同尺度的上下文信息
# 参考论文: https://arxiv.org/abs/1406.4729
def __init__(self, c1, c2, k=(5, 9, 13)):
super().__init__()
'''
c1: in_channel
c2: out_channel
k: 最大池化层卷积核大小设置
'''
#中间通道数
c_ = c1 // 2
#最大池化之前的1x1卷积,用于降维
self.cv1 = Conv(c1, c_, 1, 1)
#3个最大池化层
self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])
#concat之后的1x1卷积,将通道维数输出为指定的'c2'通道数
self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)
def forward(self, x):
#第一个1x1卷积层
y1 = self.cv1(x)
#将降维后的输入和不同池化层结果在通道维度上拼接
y2 = torch.cat([y1] + [m(y1) for m in self.m], 1)
#concat之后的1x1卷积层
return self.cv2(y2)
2.SPPF
SPPF是由YOLOv5作者Glenn Jocher基于SPP提出,速度较SPP快很多,因此命名为SPP-Fast,官方提供的YOLOv5源码默认使用的就是SPPF