前言
本篇文章讲解一下注意力机制相关的内容,这几年大火的Transformer都离不开注意力机制这个内容。那么什么是注意力机制,理解起来很容易,比如有很多个物品,我们最选择性的关心重要的特征来发现我们需要的东西。我们之前使用的CNN之类的卷积,并没有这种抓重点特征的功能。
一、self-Attention
自注意力机制的基本思想是,在处理序列数据时,每个元素都可以与序列中的其他元素建立关联,而不仅仅是依赖于相邻位置的元素。它通过计算元素之间的相对重要性来自适应地捕捉元素之间的长程依赖关系。这里就像循环神经网络RNN产生的可以获取之前和之后的信息。
1.self-attention
自注意力是自己注意自己的数据,并没有前验数据。比如这里是个seq2seq的问答问题,这里面的a都是编码后的单词或者汉字。通过不同的矩阵Wq,Wk,Wv的到q(query),k(key),v(value)。每个汉字或单词都对应一个q,k,v。可以理解成q可以用来帮助寻找与自己有关系和有依赖的其他单词汉字,而k代表其他汉字单词的特征,通过q和k确定该汉字和其他汉字的依赖关系的权重,是否有密切的关系,得出注意力权重。通过注意力权重乘value值,就得到了新的特征。
self-attention 在Attention Is All You need里提出,其中多头注意力机制是Transformer的一部分。实现self-attention的方法有很多,我们先说论文里的
Scaled Dot-product Attention。
每个ai对应一个编码后的字,通过矩阵生成q,k,v。因为q和v后面需要进行点积操作,所以要控制大小长度一样,v的大小可以和q,k不同。
每个qi和句子中所有的kj进下面公司的运算得到注意分数,也就是给vj和ai的相关性打分。
注意力分数还要经过softmax函数生成注意力权重,其总和为1,控制范围。得出注意力权重之后,对应权重与对应value相乘然后求和,就得到了在原本向量的基础上并包括其他向量关系的新特征。这样的特征训练会有更好的效果。
2.自注意力机制优点
1.提高模型对输入序列中不同位置的关注程度。自注意力机制允许模型在处理序列数据时,根据输入序列中不同位置的信息来调整注意力的权重,从而更好地捕捉序列中不同位置的重要信息。
2.实现长距离依赖建模。传统的注意力机制通常只关注输入序列中相邻的位置,而自注意力机制可以通过学习位置之间的关联性,实现对任意两个位置之间的依赖关系建模,从而更好地处理长距离依赖问题。
3.提高模型的泛化能力。自注意力机制能够自动学习输入序列中不同位置的相关性,从而减少了人工设计特征的需要,提高了模型的泛化能力。
4.支持并行计算。自注意力机制可以对输入序列中的不同位置进行并行计算,从而加速模型的训练和推理过程。
3.自注意力机制实现(pytorch)
#slef-attention可以理解成提取上下文关系进行编码,得出了新的特征表示
class SelfAttention(nn.Module):
def __init__(self,dim,dqk,dv):
super(SelfAttention,self).__init__()
self.query = nn.Linear(dim, dqk)
self.key = nn.Linear(dim, dqk)
self.value = nn.Linear(dim, dv)
def forward(self,x):
q = self.query(x)
k = self.key(x)
v = self.value(x)
# q,k,v 的shape都是(batch_size, nums_steps, dqk或dv)
attn_weights = torch.matmul(q, k.transpose(1, 2)) #计算注意力分数
attn_weights = nn.functional.softmax(attn_weights, dim=-1) # 利用softmax函数得出归一化权重
attended_values = torch.matmul(attn_weights, v) #求解出最后的特征
return attended_values #这里的特征维度是(batch_size,num_steps ,dv)
#得出自注意力特征后就可以进行分类了
class Selfattention_Classfier(nn.Module):
def __init__<