YOLOv8目标检测创新改进与实战案例专栏
专栏目录: YOLOv8有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLOv8基础解析+创新改进+实战案例
介绍
摘要
Mamba是一种具有线性计算复杂度的有效状态空间模型。它最近在处理各种视觉任务的高分辨率输入方面表现出了令人印象深刻的效率。在本文中,我们揭示了强大的Mamba模型与线性注意力Transformer共享令人惊讶的相似性,而线性注意力Transformer在实践中通常不如传统Transformer。通过探索高效的Mamba和表现欠佳的线性注意力Transformer之间的相似性和差异,我们提供了全面的分析,揭示了Mamba成功背后的关键因素。具体来说,我们在统一的公式下重新定义了选择性状态空间模型和线性注意力,将Mamba重新表述为具有六个主要区别的线性注意力Transformer的变体:输入门、遗忘门、快捷连接、无注意力归一化、单头和修改的块设计。对于每个设计,我们仔细分析了其优缺点,并实验证明其对视觉任务中模型性能的影响。有趣的是,结果突出表明遗忘门和块设计是Mamba成功的核心贡献者,而其他四个设计则不太关键。基于这些发现,我们通过将这两个关键设计的优点引入线性注意力,提出了一种类Mamba的线性注意力(MLLA)模型。该模型在图像分类和高分辨率密集预测任务中均优于各种视觉Mamba模型,同时享有可并行计算和快速推理速度。代码可在https://github.com/LeapLabTHU/MLLA获取。
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
Mamba-Like Linear Attention (MLLA)是一种模型,结合了Mamba和线性注意力Transformer的优点,旨在提高模型在视觉任务中的性能。
线性注意力:
- 线性注意力是一种注意力机制,用于计算输入序列中各个位置之间的关联性。与传统的Softmax注意力不同,线性注意力使用线性归一化代替非线性Softmax函数,从而降低计算复杂度。这使得线性注意力的计算复杂度从O(N^2)降低到O(N),提高了效率。
Mamba模型:
- Mamba是一种基于状态空间的模型,具有线性计算复杂度。它通过有效地建模序列来处理长序列,适用于自然语言处理和视觉识别任务。
MLLA的数学原理:
- MLLA模型将Mamba的关键设计元素(如遗忘门和块设计)与线性注意力Transformer相结合。在数学上,这意味着将Mamba的状态空间建模方法与线性注意力的位置关联性计算相结合,以提高模型的表现。
遗忘门的替代:
- 在MLLA中,遗忘门通常被替代为适当的位置编码。这些位置编码可以在视觉任务中代替遗忘门的功能,同时保持模型的并行计算和快速推理速度。
核心设计元素的整合:
- MLLA模型的关键设计元素包括遗忘门和块设计。通过将这些设计元素整合到线性注意力中,MLLA模型能够在图像分类和密集预测任务中取得优越性能。
核心代码
class MLLABlock(nn.Module):
r""" MLLA Block.
Args:
dim (int): Number of input channels.
input_resolution (tuple[int]): Input resulotion.
num_heads (int): Number of attention heads.
mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
drop (float, optional): Dropout rate. Default: 0.0
drop_path (float, optional): Stochastic depth rate. Default: 0.0
act_layer (nn.Module, optional): Activation layer. Default: nn.GELU
norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
"""
def __init__(self, dim, input_resolution, num_heads, mlp_ratio=4., qkv_bias=True, drop=0., drop_path=0.,
act_layer=nn.GELU, norm_layer=nn.LayerNorm, **kwargs):
super().__init__()
self.dim = dim
self.input_resolution = input_resolution
self.num_heads = num_heads
self.mlp_ratio = mlp_ratio
self.cpe1 = nn.Conv2d(dim, dim, 3, padding=1, groups=dim)
self.norm1 = norm_layer(dim)
self.in_proj = nn.Linear(dim, dim)
self.act_proj = nn.Linear(dim, dim)
self.dwc = nn.Conv2d(dim, dim, 3, padding=1, groups=dim)
self.act = nn.SiLU()
self.attn = LinearAttention(dim=dim, input_resolution=input_resolution, num_heads=num_heads, qkv_bias=qkv_bias)
self.out_proj = nn.Linear(dim, dim)
self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
self.cpe2 = nn.Conv2d(dim, dim, 3, padding=1, groups=dim)
self.norm2 = norm_layer(dim)
self.mlp = Mlp(in_features=dim, hidden_features=int(dim * mlp_ratio), act_layer=act_layer, drop=drop)
def forward(self, x):
H, W = self.input_resolution
B, L, C = x.shape
assert L == H * W, "input feature has wrong size"
x = x + self.cpe1(x.reshape(B, H, W, C).permute(0, 3, 1, 2)).flatten(2).permute(0, 2, 1)
shortcut = x
x = self.norm1(x)
act_res = self.act(self.act_proj(x))
x = self.in_proj(x).view(B, H, W, C)
x = self.act(self.dwc(x.permute(0, 3, 1, 2))).permute(0, 2, 3, 1).view(B, L, C)
# Linear Attention
x = self.attn(x)
x = self.out_proj(x * act_res)
x = shortcut + self.drop_path(x)
x = x + self.cpe2(x.reshape(B, H, W, C).permute(0, 3, 1, 2)).flatten(2).permute(0, 2, 1)
# FFN
x = x + self.drop_path(self.mlp(self.norm2(x)))
return x
def extra_repr(self) -> str:
return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \
f"mlp_ratio={self.mlp_ratio}"
task与yaml配置
详见:https://blog.csdn.net/shangyanaf/article/details/140406244