1、注意力机制
知乎学习链接:1、目前主流的attention方法都有哪些?
- 注意力机制计算公式:
- 结合淘宝搜索实例,理解注意力机制的公式含义
我们认为,对于较大的dk值,点积的大小会变大,从而将softmax函数推入具有极小梯度的区域(训练就很慢了),为了抵消这个影响,我们将点乘积乘以
- 对应的矩阵运算
- 相似性得分如下:
- 经过softmax后,
- 代码部分
import torch
import torch.nn as nn
import torch.nn.functional as F
__author__ = "Yu-Hsiang Huang"
class ScaledDotProductAttention(nn.Module):
''' Scaled Dot-Product Attention '''
def __init__(self, temperature, attn_dropout=0.1):
super().__init__()
self.temperature = temperature
self.dropout = nn.Dropout(attn_dropout)
def forward(self, q, k, v, mask=None):
attn = torch.matmul(q / self.temperature, k.transpose(2, 3))
if mask is not None:
attn = attn.masked_fill(mask == 0, -1e9)
attn = self.dropout(F.softmax(attn, dim=-1))
output = torch.matmul(attn, v)
return output, attn
2、自注意力机制
- 抽象的文本处理领域的Encoder-Decoder
- 没有用注意力情况
- 用注意力的情况
- 注意力机制的QKV情况
- 自注意力机制的QKV情况
自注意力机制的QKV全部在一边,要么在Source,要么在Target
作用:查找一句话的内部关系,比如下图中its与Law和application的关系
3、多头注意力机制
学习视频:多头注意力机制
(1)、多头注意力机制是什么,有什么用,具体运算过程
- 多头注意力机制是什么
多头注意力机制就是对注意力机制的简单堆叠
将单组的QKV拆成多组的QKV
- 多头注意力机制的作用
联想:卷积提取图片特征时一般使用多个卷积核来提取图片的不同特征
在不同的参数空间去找最优参数
- 多头注意力机制具体实现
Transfomer学习链接1
Transfomer学习链接2
(2)、多头注意力机制的代码实现,结合实例的数据变化
手把手教你用Pytorch代码实现Transformer模型(超详细的代码解读)
上图中,超过5的部分被截取掉,不足5的部分使用P进行填充,填充的P在注意力机制当中是没有意义的。
- MultiHeadAttention
上图中,1表示batchsize为1,5表示输入的5个单词,4表示每个单词用1*4的向量表示。
- QKV拆成多头的操作:
将4拆成2*2,再将n_heads=2放到前面位置去。同理KV的操作。
- ScaledDotProductAttention
- 多头注意力机制的代码部分
class MultiHeadAttention(nn.Module):
''' Multi-Head Attention module '''
def __init__(self, n_head, d_model, d_k, d_v, dropout=0.1):
super().__init__()
self.n_head = n_head
self.d_k = d_k
self.d_v = d_v
self.w_qs = nn.Linear(d_model, n_head * d_k, bias=False)
self.w_ks = nn.Linear(d_model, n_head * d_k, bias=False)
self.w_vs = nn.Linear(d_model, n_head * d_v, bias=False)
self.fc = nn.Linear(n_head * d_v, d_model, bias=False)
self.attention = ScaledDotProductAttention(temperature=d_k ** 0.5)
self.dropout = nn.Dropout(dropout)
self.layer_norm = nn.LayerNorm(d_model, eps=1e-6)
def forward(self, q, k, v, mask=None):
d_k, d_v, n_head = self.d_k, self.d_v, self.n_head
sz_b, len_q, len_k, len_v = q.size(0), q.size(1), k.size(1), v.size(1)
residual = q
# Pass through the pre-attention projection: b x lq x (n*dv)
# Separate different heads: b x lq x n x dv
q = self.w_qs(q).view(sz_b, len_q, n_head, d_k)
k = self.w_ks(k).view(sz_b, len_k, n_head, d_k)
v = self.w_vs(v).view(sz_b, len_v, n_head, d_v)
# Transpose for attention dot product: b x n x lq x dv
q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
if mask is not None:
mask = mask.unsqueeze(1) # For head axis broadcasting.
q, attn = self.attention(q, k, v, mask=mask)
# Transpose to move the head dimension back: b x lq x n x dv
# Combine the last two dimensions to concatenate all the heads together: b x lq x (n*dv)
q = q.transpose(1, 2).contiguous().view(sz_b, len_q, -1)
q = self.dropout(self.fc(q))
q += residual
q = self.layer_norm(q)
return q, attn
4、Transfomer
(1)transformer框架流程完全等于年会发奖品流程
上述场景等同于Transformer右边部分。其左边部分等同的生活场景如下:
transformer中的加位置编码
多头注意力层即找到句子间的相关性
前馈层,即将这些信息加工成我们最后要的那个语义空间。
(2)mask操作及代码详解
mask矩阵中为1的位置在计算注意力时被设置成负无穷大。
将相似性得分中对应的位置设置成负无穷大。使得最后的相似性权重部分最后全部为0.
为实现并行:
传入真实标签,
该处的mask用于比较“我喜欢你 P”和“S I Iove you . P”之间的关系,被翻译的句子和翻译的结果他们之间的关系。6行5列