Attention Is All You Need

本文深入解析Transformer模型,探讨其核心机制——自注意力(Self-Attention),如何通过并行计算提高效率,解决序列模型的长距离依赖问题。文章详细介绍了Scaled Dot-Product Attention的计算流程,包括Query、Key和Value的生成,以及Mask的应用,确保模型不会看到未来的信息。同时,讲解了Multi-Head Attention和Position-wise Feed-Forward Networks的作用,以及Positional Encoding如何帮助模型理解序列的顺序。

Motivation:

  • 靠attention机制,不使用rnn和cnn,并行度高
  • 通过attention,抓长距离依赖关系比rnn强

 

 

Scaled Dot-Product Attention

d_{k}=d_{model}/h


其中, 

其中因子起到调节作用,使得内积不至于太大(太大的话softmax后就非0即1了,不够“soft”了)。

 

1.给定输入数据,转换成对应的内容 embedding。

2.得到Q,K,V

3.计算Query和Key的相似度

4.增加mask

  • query和key有些部分是填充的,这些需要用mask屏蔽,一个简单的方法就是赋予一个很小很小的值或者直接变为0值。
  • 对于decoder的来说,我们是不能看到未来的信息的,所以对于decoder的输入,我们只能计算它和它之前输入的信息的相似度。

对encoder的 Key 进行mask,mask成负无穷(mask成负无穷的位置经过softmax后数值为0)

对decoder的Key进行mask, mask成0,

5.对Query进行mask

6.和Value进行相乘

完整的Scaled Dot-Product Attention的代码如下:

def scaled_dotproduct_attention(queries,keys,num_units=None,
                        num_heads = 0,
                        dropout_rate = 0,
                        is_training = True,
                        causality = False,
                        scope = "mulithead_attention",
                        reuse = None):
    with tf.variable_scope(scope,reuse=reuse):
        if num_units is None:
            num_units = queries.get_shape().as_list[-1]

        # Linear projection
        Q = tf.layers.dense(queries,num_units,activation=tf.nn.relu) #
        K = tf.layers.dense(keys,num_units,activation=tf.nn.relu) #
        V = tf.layers.dense(keys,num_units,activation=tf.nn.relu) #

        outputs = tf.matmul(Q,tf.transpose(K,[0,2,1]))
        outputs = outputs / (K.get_shape().as_list()[-1] ** 0.5)

        # 这里是对填充的部分进行一个mask,这些位置的attention score变为极小,我们的embedding操作中是有一个padding操作的,
        # 填充的部分其embedding都是0,加起来也是0,我们就会填充一个很小的数。
        key_masks = tf.sign(tf.abs(tf.reduce_sum(keys,axis=-1)))
        key_masks = tf.tile(tf.expand_dims(key_masks,1),[1,tf.shape(queries)[1],1])

        paddings = tf.ones_like(outputs) * (-2 ** 32 + 1)
        outputs = tf.where(tf.equal(key_masks,0),paddings,outputs)

        # 这里其实就是进行一个mask操作,不给模型看到未来的信息。
        if causality:
            diag_vals = tf.ones_like(outputs[0,:,:])
            tril = tf.contrib.linalg.LinearOperatorTriL(diag_vals).to_dense()
            masks = tf.tile(tf.expand_dims(tril,0),[tf.shape(outputs)[0],1,1])

            paddings = tf.ones_like(masks) * (-2 ** 32 + 1)
            outputs = tf.where(tf.equal(masks,0),paddings,outputs)

        outputs = tf.nn.softmax(outputs)
        # Query Mask
        query_masks = tf.sign(tf.abs(tf.reduce_sum(queries,axis=-1)))
        query_masks = tf.tile(tf.expand_dims(query_masks,-1),[1,1,tf.shape(keys)[1]])
        outputs *= query_masks
        # Dropout
        outputs = tf.layers.dropout(outputs,rate = dropout_rate,training = tf.convert_to_tensor(is_training))
        # Weighted sum
        outputs = tf.matmul(outputs,V)
        # Residual connection
        outputs += queries
        # Normalize
        outputs = normalize(outputs)

    return outputs

 

Multi-Head Attention
 

其中,

把Q,K,V通过参数矩阵映射一下,然后再做Attention,把这个过程重复做h次(参数不共享),结果拼接起来。

 

Position-wise Feed-Forward Networks

两层全连接前向网络,第一层的输出后接Relu激活函数,第二层不接激活函数。

 

Positional Encoding

在加入Positional Encoding之前,如果将K,V按行打乱顺序(相当于句子中的词序打乱),Attention的结果还是一样的,这样的模型并不能捕捉序列的顺序!此时,Attention模型顶多是一个非常精妙的“词袋模型”而已

2i2i+1为位置序号,d_{model}为Positional Encoding向量的长度.

假如Position_Embedding是拼接到原来的词向量中,那么将cos和sin前后连接还是交叉连接,都是没区别的,因为下一步都是接一个变换矩阵而已.

 

Encoder和Decoder的区别

编码可以并行计算,一次性全部encoding出来,但解码不是一次把所有序列解出来的,而是像rnn一样一个一个解出来的,因为要用上一个位置的输入当作attention的query

Decoder多了一个Multi-head attention,该Attention的输入是decoder的self attention作为query, encoder的self attention作为key和value,计算注意力权重矩阵。

Attention Is All You Need》由 Google 机器翻译团队于 2017 年发表在 NIPS 2017 上,该论文完全抛弃了 RNN 和 CNN 等网络结构,仅采用 Attention 机制进行机器翻译任务并取得良好效果,使注意力机制成为研究热点[^1]。 从论文解读来看,论文标题表明在变形金刚的原型案例中,注意力机制被用作核心想法。Transformer 是充分利用注意力机制的架构,截至 2021 年,最新的自然语言处理端高性能模型基于此架构。它利用了 Quest 的父类的 encoder 架构,在机器翻译等任务中表现出色[^2]。 在应用方面,机器翻译是其最具代表性和重要的任务之一。截至 2021 年,热门的自然语言处理模型如 gpg 和 penalty 都使用了 Transformer 架构以产生良好性能。机器翻译技术 1986 年被提出,10 年后 lstm 出现用于序列信息建模,2014 年 Squat sequence 使机器翻译技术再次兴起,之后 Attention 机制的出现进一步提升了机器翻译性能[^2]。 相关技术信息上,Attention 层的好处是能够一步到位捕捉到全局的联系,它直接把序列两两比较,虽然计算量变为 $O(n^2)$,但由于是纯矩阵运算,计算量问题并不严重。相比之下,RNN 需要一步步递推才能捕捉联系,而 CNN 则需要通过层叠来扩大感受野,这体现了 Attention 层的明显优势[^4]。 此外,Self - attention 还能产生更具可解释性的模型,模型中的各个注意力头能学习执行不同任务,且许多表现出与句子的句法和语义结构相关的行为[^5]。 ```python # 这里简单示意一个基于transformer架构的机器翻译模型构建的伪代码 import torch import torch.nn as nn # 定义一个简单的Transformer模型 class SimpleTransformer(nn.Module): def __init__(self, input_dim, d_model, nhead, num_layers): super(SimpleTransformer, self).__init__() self.embedding = nn.Embedding(input_dim, d_model) self.transformer_encoder = nn.TransformerEncoder( nn.TransformerEncoderLayer(d_model=d_model, nhead=nhead), num_layers=num_layers ) self.fc = nn.Linear(d_model, input_dim) def forward(self, src): src = self.embedding(src) output = self.transformer_encoder(src) output = self.fc(output) return output # 示例参数 input_dim = 1000 d_model = 512 nhead = 8 num_layers = 6 # 创建模型实例 model = SimpleTransformer(input_dim, d_model, nhead, num_layers) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值