RT-DETR改进策略【损失函数篇】| 将激活函数替换为带有注意力机制的激活函数 ARelu
一、本文介绍
本文记录的是
利用带有注意力机制的激活函数ARelu改进RT-DETR的方法研究
。
RT-DETR
默认的激活函数是
Silu
,通过引入了非线性因素,使网络能够学习和拟合更复杂的函数关系,
但在处理梯度消失问题上能力相对较弱,且稳定性会受到输入值和网络参数的较大影响
。而
ARelu
激活函数,通过
注意力模块
学习元素级别的残差,对于激活的输入能够有效放大从下游传播的梯度,
从而缓解梯度消失问题。在面对复杂多样的数据时,能够灵活地调整激活效果。
二、AReLU设计原理
2.1 AReLU模块设计的出发点
- 对激活函数学习方式的新探索 :现有的可学习激活函数主要通过对不可学习的激活函数进行参数化或松弛,或者寻求预定义激活函数池的数据驱动组合来实现数据自适应。作者希望从新的角度,即利用逐元素注意力机制来构建可学习的激活函数。
- 结合激活函数与注意力机制的直观联系 :激活函数和逐元素注意力函数都以逐元素乘法的网络模块形式应用,在神经网络中学习逐元素激活函数可被视为面向任务的注意力机制,即根据要完成的最终任务学习关注(激活)输入特征图中的哪些元素,从而促使一种更具可解释性的注意力激活函数公式的产生。
2.2 AReLU模块的原理
2.2.1 基于注意力机制的通用公式
设 V = { v i } ∈ R D v 1 × D v 2 × ⋯ V = \{v_{i}\} \in \mathbb{R}^{D_{v}^{1}×D_{v}^{2}×\cdots} V = { v i } ∈ R D v 1 × D v 2 × ⋯ 为表示输入数据或特征量的张量,函数 Φ \Phi Φ 由参数 Θ = { θ i } \Theta = \{\theta_{i}\} Θ = { θ i } 参数化,用于计算注意力图 S = { s i } ∈ R D v θ ( 1 ) × D v θ ( 2 ) × ⋯ S = \{s_{i}\} \in \mathbb{R}^{D_{v}^{\theta(1)}×D_{v}^{\theta(2)}×\cdots} S = { s i } ∈ R D v θ ( 1 ) × D v θ ( 2 ) × ⋯ ,即 s i = Φ ( v i , Θ ) s_{i}=\Phi(v_{i}, \Theta) s i = Φ ( v i , Θ ) 。 Φ \Phi Φ 可由神经网络实现,其参数 Θ \Theta Θ 是可学习的。通过函数 Ψ \Psi Ψ 用注意力图 S S S 调制输入 V V V 得到输出 U = { u i } ∈ R D v 1 × D v 2 × ⋯ U = \{u_{i}\} \in \mathbb{R}^{D_{v}^{1}×D_{v}^{2}×\cdots} U = { u i } ∈ R D v 1 × D v 2 × ⋯ ,其中 Ψ \Psi Ψ 是逐元素乘法,即 u i = Ψ ( v i , s i ) u_{i}=\Psi(v_{i}, s_{i}) u i = Ψ ( v i , s i ) 。
2.2.2 ARelu的具体构建
- 逐元素基于符号的注意力机制(ELSA) :对于特征量 V = { v i } ∈ R W × H × C V = \{v_{i}\} \in \mathbb{R}^{W×H×C} V = { v i } ∈ R W × H × C ,计算逐元素注意力图 S = { s i } ∈ R W × H × C S = \{s_{i}\} \in \mathbb{R}^{W×H×C} S = { s i } ∈ R W × H × C ,其中 s i = Φ ( v i , Θ ) = { C ( α ) , v i < 0 σ ( β ) , v i ≥ 0 s_{i}=\Phi(v_{i}, \Theta)= \begin{cases}C(\alpha), & v_{i}<0 \\ \sigma(\beta), & v_{i} \geq 0\end{cases} s i = Φ ( v i , Θ ) = { C ( α ) , σ ( β ) , v i < 0 v i ≥ 0 , Θ = { α , β } ∈ R 2 \Theta = \{\alpha, \beta\} \in \mathbb{R}^{2} Θ = { α , β } ∈ R 2 是可学习参数, C ( ⋅ ) C(\cdot) C ( ⋅ ) 将输入变量限制在 [ 0.01 , 0.99 ] [0.01, 0.99] [ 0.01 , 0.99 ] , σ \sigma σ 是sigmoid函数,调制函数 Ψ \Psi Ψ 定义为 u i = Ψ ( v i , s i ) = s i v i u_{i}=\Psi(v_{i}, s_{i})=s_{i}v_{i} u i = Ψ ( v i , s i ) = s i v i 。
2.2.3 ARelu的定义
将ELSA中的函数 Φ \Phi Φ 用具有可学习参数 α \alpha α 和 β \beta β 的网络层表示为 L ( x i , α , β ) = { C ( α ) x i , x i < 0 σ ( β ) x i , x i ≥ 0 \mathcal{L}(x_{i}, \alpha, \beta)= \begin{cases}C(\alpha)x_{i}, & x_{i}<0 \\ \sigma(\beta)x_{i}, & x_{i} \geq 0\end{cases} L ( x i , α , β ) = { C ( α ) x i , σ ( β ) x i , x i < 0 x i ≥ 0 ,结合标准的Rectified Linear Units R ( x i ) = { 0 , x i < 0 x i , x i ≥ 0 \mathcal{R}(x_{i})=\begin{cases}0, & x_{i}<0 \\ x_{i}, & x_{i} \geq 0\end{cases} R ( x i ) = { 0 , x i , x i < 0 x i ≥ 0 ,得到可学习激活函数 F ( x i , α , β ) = R ( x i ) + L ( x i , α , β ) = { C ( α ) x i , x i < 0 ( 1 + σ ( β ) ) x i , x i ≥ 0 \mathcal{F}(x_{i}, \alpha, \beta)=\mathcal{R}(x_{i})+\mathcal{L}(x_{i}, \alpha, \beta)=\begin{cases}C(\alpha)x_{i}, & x_{i}<0 \\ (1+\sigma(\beta))x_{i}, & x_{i} \geq 0\end{cases} F ( x i , α , β ) = R ( x i ) + L ( x i , α , β ) = { C ( α ) x i , ( 1 + σ ( β )) x i , x i < 0 x i ≥ 0 。
2.3 AReLU模块的结构
- 注意力模块 :在每一层网络中,有一个注意力模块,它为预激活特征图学习一个逐元素、基于符号的注意力图。该注意力图根据元素的符号对元素进行缩放。
- 与ReLU的结合 :注意力模块与ReLU模块相结合,共同构成ARelu。对于输入的每个元素,当元素小于0时,通过 C ( α ) C(\alpha) C ( α ) 进行缩放;当元素大于等于0时,通过 ( 1 + σ ( β ) ) (1 + \sigma(\beta)) ( 1 + σ ( β )) 进行缩放。
2.4 AReLU模块的优势
- 缓解梯度消失问题 :注意力模块本质上学习了相对于ReLU激活部分的逐元素残差(因为ReLU可视为恒等变换),这有助于有效缓解梯度消失问题。具体来说,当输入被激活时,ARelu会放大从下游传播的梯度(因为 1 + σ ( β ) > 1 1+\sigma(\beta)>1 1 + σ ( β ) > 1 ),而在其他情况下则抑制梯度,而标准的ReLU及其变体(如PReLU)只有抑制作用。
- 数据自适应和稳定性 :ARelu的放大因子是通过学习动态适应输入的,并由sigmoid函数限制,这使得激活更具数据自适应性和稳定性。例如,通过对后激活特征图的可视化比较,可以看出ARelu在这方面的优势。
- 轻量级且易于学习 :只有两个可学习参数 α \alpha α 和 β \beta β ,因此ARelu是轻量级的且易于学习。
- 计算复杂度低 :对于一个 L L L 层网络,ARelu引入的额外参数非常少,只有 2 L 2L 2 L 个,并且在正向和反向传播中,由于ARelu导致的计算复杂度可以忽略不计。
论文: https://arxiv.org/pdf/2006.13858
源码: https://link.zhihu.com/?target=https%3A//github.com/densechen/AReLU
三、AReLU的实现代码
AReLU
的实现代码如下:
import torch
import torch.nn as nn
import torch.nn.functional as F
class AReLU(nn.Module):
def __init__(self, alpha=0.90, beta=2.0):
super().__init__()
self.alpha = nn.Parameter(torch.tensor([alpha]))
self.beta = nn.Parameter(torch.tensor([beta]))
def forward(self, input):
alpha = torch.clamp(self.alpha, min=0.01, max=0.99)
beta = 1 + torch.sigmoid(self.beta)
return F.relu(input) * beta - F.relu(-input) * alpha
四、添加步骤
4.1 修改ultralytics/nn/modules/conv.py
此处需要查看的文件是
ultralytics/nn/modules/conv.py
①
在此文件中加入
ARelu
激活函数的实现代码:
②
在
Conv
模块中调用
AReLU
激活函数:
default_act = AReLU()
再次运行即可调用
AReLU
激活函数。
五、成功运行截图
六、总结
AReLU模块的作用
-
提升网络性能
:
ARelu仅在每层引入两个额外的可学习参数,就能显著提高大多数主流网络架构的性能。 -
加速网络训练
:
ARelu在小学习率下能够实现快速网络训练,这使得它在迁移学习和元学习等场景中特别有用。例如,在迁移学习中,预训练模型通常需要在新的领域/数据集上以小学习率进行微调,而ARelu能够很好地适应这种情况。 - 实现聚焦激活 :通过特征图可视化证明,学习到的注意力激活能够实现对特征图相关区域的良好聚焦激活,即根据任务导向,对与目标类相关的区域进行更有意义的激活。