YOLO目标检测创新改进与实战案例专栏
专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLO基础解析+创新改进+实战案例
摘要
像素级回归可能是细粒度计算机视觉任务中最常见的问题,例如估计关键点热图和分割掩模。这些回归问题非常具有挑战性,特别是因为它们需要在低计算开销下对高分辨率输入/输出建模长距离依赖关系,以估计高度非线性的像素级语义。
尽管深度卷积神经网络(DCNNs)中的注意机制已经流行起来,用于增强长距离依赖关系,但是元素特定的注意力,例如非局部块,学习起来非常复杂且对噪声敏感,而大多数简化的注意力混合体试图在多种任务类型之间达到最佳折衷。
在本文中,我们提出了极化自注意(PSA)块,它融合了两个关键设计,以实现高质量的像素级回归:(1)极化过滤:在保持通道和空间注意力计算中的高内部分辨率的同时,完全折叠输入张量沿其相对应维度。(2)增强:构成非线性,直接适应典型细粒度回归的输出分布,例如2D高斯分布(关键点热图)或2D二项分布(二进制分割掩模)。PSA似乎已经充分利用了其仅通道和仅空间分支的表示能力,因此其顺序和并行布局之间只有边际度量差异。实验结果表明,PSA将标准基线提高了2至4个点,并将2D姿势估计和语义分割基准上的最新技术提高了1至2个点。
创新点
极化滤波(Polarized filteringPolarized):在通道和空间维度保持比较高的分辨率(在通道上保持C/2的维度,在空间上保持[H,W]的维度 ),进一步减少低分辨率、低通道数和上采样造成的信息损失。
增强(Enhancement):采用细粒度回归输出分布的非线性函数。
yolov8 引入
class PolarizedSelfAttention(nn.Module):
def __init__(self, channel=512):
super().__init__()
# 通道注意力权重计算层
self.ch_wv = nn.Conv2d(channel, channel // 2, kernel_size=(1, 1))
self.ch_wq = nn.Conv2d(channel, 1, kernel_size=(1, 1))
# 通道和空间注意力的softmax
self.softmax_channel = nn.Softmax(1)
self.softmax_spatial = nn.Softmax(-1)
# 通道注意力输出层
self.ch_wz = nn.Conv2d(channel // 2, channel, kernel_size=(1, 1))
# 用于通道注意力权重的层归一化和Sigmoid函数
self.ln = nn.LayerNorm(channel)
self.sigmoid = nn.Sigmoid()
# 空间注意力权重计算层
self.sp_wv = nn.Conv2d(channel, channel // 2, kernel_size=(1, 1))
self.sp_wq = nn.Conv2d(channel, channel // 2, kernel_size=(1, 1))
# 平均池化层,用于空间注意力计算
self.agp = nn.AdaptiveAvgPool2d((1, 1))
def forward(self, x):
b, c, h, w = x.size() # 输入x的尺寸
# 通道注意力计算过程
channel_wv = self.ch_wv(x) # 对输入x进行卷积,得到中间特征
channel_wq = self.ch_wq(x) # 对输入x进行卷积,得到查询特征
# 重塑特征,以便进行矩阵乘法
channel_wv = channel_wv.reshape(b, c // 2, -1) # 将特征图重塑为矩阵形式
channel_wq = channel_wq.reshape(b, -1, 1) # 将查询特征重塑为矩阵形式
channel_wq = self.softmax_channel(channel_wq) # 对查询特征应用softmax
channel_wz = torch.matmul(channel_wv, channel_wq).unsqueeze(-1) # 计算权重并增加一个维度
# 应用层归一化、卷积和Sigmoid函数得到通道注意力权重
channel_weight = (
self.sigmoid(
self.ln(self.ch_wz(channel_wz).reshape(b, c, 1).permute(0, 2, 1))
)
.permute(0, 2, 1)
.reshape(b, c, 1, 1)
)
channel_out = channel_weight * x # 将权重应用到输入x上
# 空间注意力计算过程
spatial_wv = self.sp_wv(x) # 对输入x进行卷积,得到中间特征
spatial_wq = self.sp_wq(x) # 对输入x进行卷积,得到查询特征
spatial_wq = self.agp(spatial_wq) # 对查询特征进行平均池化
spatial_wv = spatial_wv.reshape(b, c // 2, -1) # 重塑特征
spatial_wq = spatial_wq.permute(0, 2, 3, 1).reshape(b, 1, c // 2) # 重塑查询特征并转置
spatial_wq = self.softmax_spatial(spatial_wq) # 对查询特征应用softmax
spatial_wz = torch.matmul(spatial_wq, spatial_wv) # 计算权重
spatial_weight = self.sigmoid(spatial_wz.reshape(b, 1, h, w)) # 应用Sigmoid函数得到空间注意力权重
spatial_out = spatial_weight * x # 将权重应用到输入x上
out = spatial_out + channel_out # 合并通道和空间注意力结果
# 返回最终的输出
return out
# 主函数,用于测试极化自注意力模块
if __name__ == "__main__":
x = torch.randn(1, 1024, 224, 224) # 创建一个随机的输入张量,模拟一个批量大小为1,通道数为1024,尺寸为224x224的图像
psa = PolarizedSelfAttention(channel=1024) # 实例化一个极化自注意力模块,输入通道数设为1024
x = psa(x) # 通过极化自注意力模块处理输入张量
print(x.shape) # 打印处理后的张量的形状,以验证输出的维度是否正确
task与yaml配置
详见:https://blog.csdn.net/shangyanaf/article/details/137295765