超细节!从源代码剖析Self-Attention知识点

©PaperWeekly 原创 · 作者|海晨威

学校|同济大学硕士生

研究方向|自然语言处理

在当前的 NLP 领域,Transformer / BERT 已然成为基础应用,而 Self-Attention  则是两者的核心部分,下面尝试用 Q&A 和源码的形式深入 Self-Attention 的细节

Q&A

1. Self-Attention 的核心是什么?

Self-Attention 的核心是用文本中的其它词来增强目标词的语义表示,从而更好的利用上下文的信息。

2. Self-Attention 的时间复杂度是怎么计算的?

Self-Attention 时间复杂度: ,这里,n 是序列的长度,d 是 embedding 的维度,不考虑 batch 维。

Self-Attention 包括三个步骤:相似度计算,softmax 和加权平均

它们分别的时间复杂度是:

相似度计算 可以看作大小为 的两个矩阵相乘:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是 multi-head-self-attention 的代码示例: ``` class MultiHeadSelfAttention(nn.Module): def __init__(self, d_model, num_heads): super(MultiHeadSelfAttention, self).__init__() self.num_heads = num_heads self.d_model = d_model assert d_model % self.num_heads == self.depth = d_model // self.num_heads self.Wq = nn.Linear(d_model, d_model) self.Wk = nn.Linear(d_model, d_model) self.Wv = nn.Linear(d_model, d_model) self.fc = nn.Linear(d_model, d_model) def forward(self, x, mask=None): batch_size = x.size() Q = self.Wq(x).view(batch_size, -1, self.num_heads, self.depth).transpose(1,2) K = self.Wk(x).view(batch_size, -1, self.num_heads, self.depth).transpose(1,2) V = self.Wv(x).view(batch_size, -1, self.num_heads, self.depth).transpose(1,2) scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.depth) if mask is not None: scores = scores.masked_fill(mask == , -1e9) attention = F.softmax(scores, dim=-1) context = torch.matmul(attention, V) context = context.transpose(1,2).contiguous().view(batch_size, -1, self.num_heads*self.depth) output = self.fc(context) return output ``` 这是一个用于实现多头自注意力机制的 PyTorch 模块。它接受一个大小为 (batch_size, seq_len, d_model) 的输入张量 x,并返回一个大小相同的输出张量。num_heads 参数指定了要使用的头数,d_model 参数指定了输入和输出张量的特征维度。 在 forward 方法中,首先使用三个线性 Wq、Wk 和 Wv 将输入张量 x 映射到查询、键和值张量 Q、K 和 V。然后将它们分别重塑为大小为 (batch_size, num_heads, seq_len, depth) 的张量,并通过 transpose 方法将头和序列维度交换,以便在计算注意力得分时进行矩阵乘法。 得分张量 scores 通过除以 math.sqrt(self.depth) 进行缩放,并在需要时使用 mask 张量进行掩码。然后使用 softmax 函数计算注意力张量 attention,并将其与值张量 V 相乘以获得上下文张量 context。 最后,将 context 张量重塑为大小为 (batch_size, seq_len, d_model) 的张量,并通过一个额外的线性 fc 进行变换,以获得最终的输出张量。 ### 回答2: multi-head-self-attention是一种用于自然语言处理任务的机制,其通过多个头(head)并行计算来加强注意力机制。下面我们对multi-head-self-attention的代码进行分析: 首先,代码会接收一个输入tensor,该tensor的维度为(batch_size, seq_len, dim),其中batch_size表示批次中的样本数量,seq_len表示序列长度,dim表示每个词向量的维度。 接着,代码会进行一系列线性变换,包括将输入tensor乘上权重矩阵进行维度变换,使得输入tensor的维度变为(batch_size, seq_len, num_heads, head_dim)。其中,num_heads表示头的数量,head_dim表示每个头的维度。 然后,代码会对维度变换后的tensor进行reshape操作,使每个头的维度与原始输入tensor一致,这样可以方便计算每个头的注意力权重。 接下来,代码会计算每个头的注意力权重。注意力权重的计算包括三个步骤:首先,通过对每个头的词向量进行线性变换生成查询(query)、键(key)和值(value)向量;其次,计算每个头的注意力分数,即query与key的点积再经过softmax函数进行归一化;最后,将注意力分数与value相乘,并将结果相加,得到每个头的输出向量。 随后,代码会将每个头的输出向量拼接起来,并通过一个线性变换将维度转换为原始输入tensor的维度,即(batch_size, seq_len, dim)。 最后,代码会对输出tensor进行一些后续的处理,如添加残差连接和归一化等,以增强模型的表达能力和稳定性。 总的来说,multi-head-self-attention通过引入多个头并行计算,能够捕捉到不同次的语义信息,增强了模型对序列中各个位置的关注程度,提升了自然语言处理任务的性能。该代码实现了multi-head-self-attention的关键步骤,即将输入tensor进行维度变换、计算注意力权重并加权求和,最后通过线性变换重建输出tensor。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值