在学习注意力机制的进程中,我发现像我这样的麻瓜就不配看论文去了解这个东西。
后边找到了源码,企图从完成看出一些逻辑,发现也不是那么友好。究竟,麻瓜精通算法也就不是麻瓜了。
万幸,我后来磕磕绊绊的从论文,搜索引擎和源码逐步的了解他。
论文链接:Attention Is All You Need.pdf (arxiv.org)
1. 开始了解注意力机制
注意力机制(Attention Mechanism)是近年来在深度学习范畴取得明显成果的重要技能之一。
其中心思想是在模型的处理进程中,对输入的不同部分分配不同的权重,从而使模型可以更加重视与当前使命相关的信息。这一机制的引入在自然言语处理、核算机视觉等范畴都取得了明显的性能提升,为模型的开展提供了强大的支持。
2. 注意力机制开展的背景
传统的循环神经网络模型在处理序列数据时往往面临着信息丢失和模糊的问题。随着输入序列的添加,模型越来越难有效地捕捉到要害信息,导致性能下降。
为了处理这一问题,注意力机制应运而生。注意力机制可以经过对输入序列中的不同部分分配不同的注意力权重,从而有效地处理这个问题。
最早的注意力机制出现在自然言语处理的机器翻译使命中,经过对齐源言语和目标言语的词语,模型可以更灵敏地学习言语间的对应关系,从而提高翻译质量。
3. 注意力机制的架构
注意力机制的基本架构包括查询(Query)、键(Key)和值(Value)的组合。也便是常说的Q、K、V。
在处理输入序列时,模型经过核算查询与键之间的关联度,然后运用这些关联度为每个值分配权重。这些权重决定了模型在核算输出时对输入的重视程度,使得模型可以更有针对性地选择信息。
最中心的便是这个公式,可是这个公式确实不太简略了解。下面结合图像来走一遍注意力机制的核算流程。
其实这个公式,便是三个变量,Q、K、V。所以接下来我们会从Q、K、V的角度逐步了解这个公式。
1. 求出Q、K、V
看论文的时分,我很难了解这一点。
Q、K、V究竟都是个啥?他们怎样出来的?怎样定义的他们的意义是啥子?作用是啥?
一波热情五连问,把搜索引擎都给干冒烟了。
最终功夫不负有心人,总算在完成代码中看到了Q、K、V的完成,才逐步了解了。
模型中我们会输入数据X,不论是原始数据,时序数据,仍是CV的像素矩阵,仍是NLP的语义向量,他们都会变成一个数据矩阵的形式。如上图,左半边。
Q、K、V便是经过X过一遍线性层liner核算出来的。
进程十分简略,可是这个意义不简略。
Q、K、V经过的liner层的权重是可学习的,随着练习不断优化调整的,所以Q、K、V也会逐步趋向我们需求的姿态。
2. Q、K、V的用途
为什么要给这个三个变量起这样的名字,查询(Query)、键(Key)和值(Value)。
论文中大致意义是这样的,经过将Q,k相乘,得到注意力得分。
相乘便是十分简略的相乘,然后按列求和,如下代码。
正常来说,是三维矩阵,也不会是torch.mm而是torch.bmm,并且一般矩阵维度相同。可是为了方便了解,就这样来做了。
q=torch.Tensor([[[3,4],[1,2]],[[3,4],[1,2]],[[3,4],[1,2]]]) # 3*2*2
k=torch.Tensor([[[1,2],[3,4]],[[1,2],[3,4]],[[3,4],[1,2]]]) # 3*2*2
torch.bmm(a,b) # 3*2*2
这个函数所做的一个事情便是后边剩下的两维对应相乘,因为榜首维是3所以要做三次矩阵相乘运算得到3个矩阵,然后再拼接起来,又是322。
这一步操作把我整的很迷惑,为什么相乘,目的是什么,成果为什么能作为权重?
在这里我的了解是,如果没有Q和K,X只是一个简略的iner线性层得到V,这样的权重设置的信息含量太低了,完全便是随机生成,不断拟合罢了。
而Q和K都是可以经过学习不断调整的,并且Q和K他们内部都包含了X自身的信息,经过一个比较复杂的运算得到权重,其信息含量会更高。并且Q和K也是经过参阅自己不断练习调整得到的,可以学习到的信息更多。权重设置会更合理。
我已经提早声明了,我是个麻瓜,究竟我连矩阵运算都不太会了。所以这样的了解,简略粗暴,不需求深究公式意义就比较简略了解了。
注意:这里是二维矩阵运用mm办法,三维矩阵才会运用bmm办法。
3. W*V 最终加权和
为了梯度的安稳,注意力机制后续运用了score归一化。
并且也对对score运用softmax激活函数,使其拟合才能更强。
- W点乘Value值,得到加权的每个输入向量的评分
- 然后相加之后得到最终的输出成果
这里的了解就比较简略了,加权和嘛。
4. 注意力机制的中心完成
# Self-Attention 机制的完成
class Attention(nn.Module):
# input x : batch_size * seq_len * input_dim
# q : batch_size * input_dim * dim_k
# k : batch_size * input_dim * dim_k
# v : batch_size * input_dim * dim_v
def __init__(self, input_dim, dim_k, dim_v):
super(Discriminator, self).__init__()
self.q = nn.Linear(input_dim, dim_k)
self.k = nn.Linear(input_dim, dim_k)
self.v = nn.Linear(input_dim, dim_v)
self._norm_fact = 1 / sqrt(dim_k)
def forward(self, x, h):
Q = self.q(x) # Q: batch_size * seq_len * dim_k
K = self.k(x) # K: batch_size * seq_len * dim_k
V = self.v(x) # V: batch_size * seq_len * dim_v
attention = nn.Softmax(dim=-1)(torch.bmm(Q, K.permute(0, 2, 1))) * self._norm_fact # Q * K.T() # batch_size * seq_len * seq_len
output_temp = torch.bmm(attention, V) # Q * K.T() * V # batch_size * seq_len * dim_v
output=nn.Sigmoid()(output_temp)
# print("output",output.shape)
return output
在深度学习中,注意力机制的应用有多种形式,例如自注意力机制(Self-Attention)和多头注意力机制(Multi-Head Attention)。
以上的完成便是自注意力机制,多头注意力机制便是组合多个自注意力头来更全面地捕捉输入序列的信息。