Transformer中的多头注意力机制-为什么需要多头?

文章探讨了Transformer中多头注意力机制的作用,解释了为何它能学习不同维度的信息,以及QKV矩阵的生成和自注意力计算原理。还讨论了多头机制如何增强模型表达能力和计算效率,并简要介绍了Transformerencoder的结构。

Transformer为什么使用多头注意力机制呢?

多头可以学习到不同维度的特征和信息。为什么可以学习到不同维度的信息呢?

答案是:多头注意力机制的组成是有单个的self attention,由于self attention通过产生QKV矩阵来学习数据特征,那每一个self attention最终会产生一个维度上的输出特征,所以当使用多头注意力机制的时候,模型就可以学习到多维度的特征信息,这使得模型可以从多个维度更好的理解数据。同时多头注意力机制还是并行计算的,这也符合现在硬件架构,提升计算效率。详细说明请看下文。

首先,要明确的是multi head attention的组成是单个的self attention。我们先理解self attention的计算过程。

self attention的计算如左下图所示:其中QKV的来源是将输入X进行线性变换,产生三个不同的权重矩阵,如右下图所示,然后这三个矩阵依次和输入x做矩阵点乘运算得到了QKV,

最后通过下面这个式子的可以得到self attention的输出,我们可以将其理解为一个维度上的特征信息。

而多头注意力机制的如下图,允许模型从不同的子空间关注多个不同的位置(上图中的QKV的来源文件中矩阵是生成了,可学习的,)从而捕捉不同级别的特征和信息,使得每个头可以学习到不同的关系,这使得模型可以从不同的角度理解数据。

几个问题:

1、Q和K为什么使用不同的权重矩阵生成?为什么不能使用同一个值进行自身的点乘运算?

回答:1)使用不同的权重举证可以增加模型的表达能力,不同的权重矩阵允许模型在不同的空间中学习和匹配不同的特征。2)不同的权重矩阵可以使模型更好的参数化,学习到更多的信息而不是仅仅依赖一个权重矩阵。

2、self attention中为什么是点乘而不是add?二者复杂度上有什么区别?

回答:点乘注意力通常在实践中表现更好,可能是因为计算简单和高效。点乘复杂度为O(d*n^2)其中d是特征维度,n是序列长度。

3、transformer的encoder结构

回答:encoder由多个相同的block组成,如下图所示,每个block中包含由两个模块,multi head attention和feed forward模块。每个模块中都含有一个残差连接和归一化层。

### Transformer多头注意力机制的原理与实现 Transformer多头注意力机制是一种增强模型表示能力的关键技术,其核心思想是通过多个并行的注意力头(Attention Heads)捕捉输入序列的不同特征[^1]。以下是多头注意力机制的原理和实现细节: #### 1. 多头注意力机制的基本原理 多头注意力机制允许模型在不同的表示子空间中学习信息[^1]。具体来说,它将输入向量通过线性变换映射到三个不同的空间:查询(Query)、键(Key)和值(Value)。然后,通过计算查询和键之间的点积相似度,并对值进行加权求和,得到注意力输出。 公式如下: - $ Q = XW_Q $ - $ K = XW_K $ - $ V = XW_V $ - $ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $ 其中: - $ X $ 是输入矩阵。 - $ W_Q, W_K, W_V $ 是可训练的权重矩阵。 - $ d_k $ 是键向量的维度,用于缩放点积以避免梯度消失或爆炸[^1]。 #### 2. 多头注意力的具体实现 为了捕获更丰富的信息,多头注意力机制将上述过程重复多次,每个头都有独立的权重矩阵。最终,所有头的输出被拼接在一起并通过另一个线性变换整合。 代码实现如下: ```python import torch import torch.nn as nn class MultiHeadAttention(nn.Module): def __init__(self, embed_size, heads, dropout=0.1): super(MultiHeadAttention, self).__init__() self.embed_size = embed_size self.heads = heads self.head_dim = embed_size // heads assert (self.head_dim * heads == embed_size), "Embed size needs to be divisible by heads" self.values = nn.Linear(self.head_dim, self.head_dim, bias=False) self.keys = nn.Linear(self.head_dim, self.head_dim, bias=False) self.queries = nn.Linear(self.head_dim, self.head_dim, bias=False) self.fc_out = nn.Linear(heads * self.head_dim, embed_size) self.dropout = nn.Dropout(dropout) def forward(self, values, keys, query, mask): N = query.shape[0] value_len, key_len, query_len = values.shape[1], keys.shape[1], query.shape[1] # Split embedding into self.heads pieces values = values.reshape(N, value_len, self.heads, self.head_dim) keys = keys.reshape(N, key_len, self.heads, self.head_dim) queries = query.reshape(N, query_len, self.heads, self.head_dim) energy = torch.einsum("nqhd,nkhd->nhqk", [queries, keys]) / (self.head_dim ** 0.5) if mask is not None: energy = energy.masked_fill(mask == 0, float("-1e20")) attention = torch.softmax(energy, dim=3) attention = self.dropout(attention) out = torch.einsum("nhql,nlhd->nqhd", [attention, values]).reshape( N, query_len, self.heads * self.head_dim ) out = self.fc_out(out) return out ``` #### 3. 多头注意力的优点 多头注意力机制的主要优势在于其能够同时关注输入序列的不同部分,从而捕获更复杂的依赖关系。通过并行处理多个注意力头,模型能够在不同的子空间中提取特征。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值