为什么自己写的注意力机制会比不过torch的注意力机制效果呢?

如题,是按照逻辑结构临摹的,没够魔改
关注者
204
被浏览
137,307

6 个回答

如果你用的是torch.nn.MultiheadAttention,并且设置了dropout,你有可能忽略的是: torch.nn.MultiheadAttention里的dropout不是对输出的dropout,而是对注意力权重的dropout。


见官方文档 torch.nn.MultiheadAttention - Parameters:

dropout – Dropout probability on attn_output_weights . Default: 0.0 (no dropout).


我之前也留意到自己写的注意力没有pytorch的好,后面发现了这点后加入注意力的dropout就能达到一样的效果。


但是,torch.nn.MultiheadAttention里对注意力权重的dropout在实现上有一些问题,CVPR2023中的DropKey提供了更好的实现方法。大家可以看我另一个回答

dropout 是一个原因,但是它在 attention 里也不常用 (我看到的 FAIR 的代码里基本都是 0.0)。跟 dropout 相比 drop_path 用的比较多,但它不是 attention 的一部分。

还有一个原因是 初始化 。盲猜题主是用 torch.nn.Linear 来实现 QKV mapping 的(因为最方便),但是 torch.nn.MultiheadAttention 里的这一步参数是用 torch.nn.Parameter 来实现的,然后进行了自定义的初始化:

# 以下代码来自 torch.nn.MultiheadAttention 源码 
# https://pytorch.org/docs/stable/_modules/torch/nn/modules/activation.html#MultiheadAttention
# 只显示重要部分
self.in_proj_weight = Parameter(torch.empty((3 * embed_dim, embed_dim), **factory_kwargs))
self.in_proj_bias = Parameter(torch.empty(3 * embed_dim, **factory_kwargs))
xavier_uniform_(self.in_proj_weight) # weight 使用 xavier_uniform 初始化
constant_(self.in_proj_bias, 0.) # bias 初始化为 0
...

对比一下 torch.nn.Linear 的初始化:

# 以下代码来自 torch.nn.Linear 源码 
# https://pytorch.org/docs/stable/_modules/torch/nn/modules/linear.html#Linear
# 只显示重要部分