赞
踩
知乎学习链接:1、目前主流的attention方法都有哪些?
我们认为,对于较大的dk值,点积的大小会变大,从而将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
自注意力机制的QKV全部在一边,要么在Source,要么在Target
作用:查找一句话的内部关系,比如下图中its与Law和application的关系
学习视频:多头注意力机制
多头注意力机制就是对注意力机制的简单堆叠
将单组的QKV拆成多组的QKV
联想:卷积提取图片特征时一般使用多个卷积核来提取图片的不同特征
在不同的参数空间去找最优参数
Transfomer学习链接1
Transfomer学习链接2
手把手教你用Pytorch代码实现Transformer模型(超详细的代码解读)
上图中,超过5的部分被截取掉,不足5的部分使用P进行填充,填充的P在注意力机制当中是没有意义的。
上图中,1表示batchsize为1,5表示输入的5个单词,4表示每个单词用1*4的向量表示。
将4拆成2*2,再将n_heads=2放到前面位置去。同理KV的操作。
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
上述场景等同于Transformer右边部分。其左边部分等同的生活场景如下:
transformer中的加位置编码
多头注意力层即找到句子间的相关性
前馈层,即将这些信息加工成我们最后要的那个语义空间。
mask矩阵中为1的位置在计算注意力时被设置成负无穷大。
将相似性得分中对应的位置设置成负无穷大。使得最后的相似性权重部分最后全部为0.
为实现并行:
传入真实标签,
该处的mask用于比较“我喜欢你 P”和“S I Iove you . P”之间的关系,被翻译的句子和翻译的结果他们之间的关系。6行5列
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。