YOLO目标检测创新改进与实战案例专栏
专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLO基础解析+创新改进+实战案例
介绍
摘要
我们介绍了BoTNet,这是一个概念简单但功能强大的骨干架构,将自注意力引入多个计算机视觉任务,包括图像分类、物体检测和实例分割。通过仅在ResNet的最后三个瓶颈块中用全局自注意力替换空间卷积,而不进行其他更改,我们的方法在实例分割和物体检测任务上显著提升了基线性能,同时减少了参数,延迟方面的开销也极小。通过设计BoTNet,我们还指出了带自注意力的ResNet瓶颈块可以视为Transformer块。在不增添任何复杂元素的情况下,BoTNet在COCO实例分割基准上使用Mask R-CNN框架实现了44.4%的Mask AP和49.7%的Box AP,超过了以前在COCO验证集上评估的ResNeSt [67]单模型和单尺度结果的最佳水平。最后,我们展示了将BoTNet设计简单地适应图像分类的方法,结果显示模型在ImageNet基准上达到了84.7%的top-1准确率,而在TPU-v3硬件上的“计算”时间比流行的EfficientNet模型快高达1.64倍。我们希望我们简单而有效的方法能成为未来视觉自注意力模型研究的强有力基准。
文章链接
论文地址:论文地址
代码地址: 代码地址
基本原理
多头自注意力(Multi-Head Self-Attention)是一种在神经网络,尤其是Transformer架构中常用的机制,它在自然语言处理、计算机视觉等领域取得了显著的效果。多头自注意力的核心思想是通过多个注意力头(attention heads)来捕捉输入数据中不同部分之间的关系,从而提升模型的表示能力。
自注意力机制(Self-Attention)
在解释多头自注意力之前,先了解自注意力机制。自注意力机制的主要步骤如下:
输入向量:假设输入是一组向量,表示为$\mathbf{X} = [x_1, x_2, ..., x_n]$,其中每个$x_i$是一个$d$维向量。
线性变换:对每个输入向量$x_i$进行三个线性变换,生成查询(query)、键(key)和值(value)向量:
$$ q_i = W_q x_i, \quad k_i = W_k x_i, \quad v_i = W_v x_i $$
其中,$W_q, W_k, W_v$是可训练的权重矩阵。计算注意力得分:通过点积来计算查询向量和键向量之间的相似性得分,然后通过softmax函数归一化:
$$ \text{score}_{ij} = \frac{q_i \cdot k_j}{\sqrt{d_k}} $$
其中,$d_k$是键向量的维度。加权求和:使用归一化后的得分对值向量进行加权求和,得到每个输入向量的输出表示:
$$ \text{Attention}(x_i) = \sum_{j=1}^n \text{softmax}(\text{score}_{ij}) v_j $$
多头自注意力(Multi-Head Self-Attention)
多头自注意力机制通过多个注意力头来增强模型的表现力。每个注意力头独立地执行上述的自注意力机制,并最终将这些头的输出进行拼接和线性变换。具体步骤如下:
多头计算:假设有$h$个注意力头,每个头都有独立的查询、键和值的线性变换:
$$ q_i^h = W_q^h x_i, \quad k_i^h = W_k^h x_i, \quad v_i^h = W_v^h x_i $$
每个头都执行自注意力机制,得到输出:
$$ \text{head}_h = \sum_{j=1}^n \text{softmax}\left(\frac{q_i^h \cdot k_j^h}{\sqrt{d_k}}\right) v_j^h $$拼接和线性变换:将所有头的输出拼接在一起,并进行线性变换,得到最终的输出:
$$ \text{MultiHead}(x_i) = W_o [\text{head}_1, \text{head}_2, ..., \text{head}_h] $$
其中,$W_o$是用于将拼接结果映射到输出维度的线性变换矩阵。
BoTNet使用的MHSA
BoTNet(Bottleneck Transformers)使用的MHSA(Multi-Head Self-Attention)层是该架构的关键组成部分,用于在视觉识别任务中实现全局自注意力机制。
整合位置:BoTNet将MHSA层集成到骨干网络的最低分辨率特征图中,通常是在ResNet的c5堆栈中的残差块中。这样的设计使得MHSA能够在较低分辨率的特征图上执行全局自注意力操作。
替代传统卷积:在BoTNet中,MHSA层取代了传统的卷积操作,特别是在ResNet的残差块中。这种替代使得网络能够更好地捕捉长距离依赖关系,从而提高视觉识别任务的性能。
多头机制:MHSA在BoTNet中采用多头自注意力机制,通过并行计算多个注意力头来学习不同的特征表示。这有助于网络更好地理解和处理输入特征之间的关系。
残差连接和归一化:为了促进网络的训练和收敛,BoTNet中的MHSA层通常与残差连接和归一化操作结合使用。这些操作有助于减轻梯度消失和加速网络的训练过程。
性能优势:通过在BoTNet中使用MHSA层,网络能够更好地处理大尺寸图像和复杂场景,提高实例分割、目标检测和图像分类等任务的性能和泛化能力。
yolov8 引入
class MHSA(nn.Module):
def __init__(self, n_dims, width=14, height=14, heads=4):
super(MHSA, self).__init__()
self.heads = heads
self.query = nn.Conv2d(n_dims, n_dims, kernel_size=1)
self.key = nn.Conv2d(n_dims, n_dims, kernel_size=1)
self.value = nn.Conv2d(n_dims, n_dims, kernel_size=1)
self.rel_h = nn.Parameter(torch.randn([1, heads, n_dims // heads, 1, height]), requires_grad=True)
self.rel_w = nn.Parameter(torch.randn([1, heads, n_dims // heads, width, 1]), requires_grad=True)
self.softmax = nn.Softmax(dim=-1)
def forward(self, x):
n_batch, C, width, height = x.size()
q = self.query(x).view(n_batch, self.heads, C // self.heads, -1)
k = self.key(x).view(n_batch, self.heads, C // self.heads, -1)
v = self.value(x).view(n_batch, self.heads, C // self.heads, -1)
content_content = torch.matmul(q.permute(0, 1, 3, 2), k)
content_position = (self.rel_h + self.rel_w).view(1, self.heads, C // self.heads, -1).permute(0, 1, 3, 2)
content_position = torch.matmul(content_position, q)
energy = content_content + content_position
attention = self.softmax(energy)
out = torch.matmul(v, attention.permute(0, 1, 3, 2))
out = out.view(n_batch, C, width, height)
return out
task与yaml配置
详见:https://blog.csdn.net/shangyanaf/article/details/140110995