Attention机制全流程详解与细节学习笔记

回顾

上一篇笔记里,我们的初学笔记里,我们已经对Attention机制的主要内容作了全面的介绍,这篇笔记,主要是补充我在第二次学习Attention机制时对一些细节的理解与记录。下面我会把整个Attention机制的主要流程通过另外一种方式再过一遍,对其中的一些关键参数的维度,这里也会有所标注。温故而知新,挺好。

Attention的全流程

image-20201202015719320

我们用上面的图来说明Attention机制的整个工作流程。

首先,是Decoder部分:

原始输入是语料分词后的token_id,分批次传入Embedding层得到词向量,再将词向量传入Encoder中的特征提取器进行特征提取,这里使用的是RNN系列的模型(RNN、LSTM、GRU),用RNNs代称,为了更好的捕捉一个句子前后的语义特征,我们这里使用双向的RNNs。两个方向的RNNs所产生的两部分隐藏层状态拼接成一个状态hs进行输出。这是后面Attention所需要用到的重要状态值,它包含了各个输入词的语义,在普通的Seq2Seq模型中,它就是生成的语义编码c。

再看Decoder部分:

image-20201202015849920

解码部分与编码部分类似,t-1时刻RNNs输出一个隐藏状态h_(t-1),该隐藏状态在图中要传下去,与编码产生的h_s进行计算,得到一个Score:

image-20201202015804994

注意,当前时刻用到的Decoder的隐藏态h_t-1代表是上一时刻Decoder单元输出的,因为在RNN中,当前时刻的输入来自于上一时刻的输出。

这个Score怎么计算的呢,一般我们常用的两个方法如下:

方法一:

两个向量h_t与h_s直接进行点乘得到Score。中间也可以加一个神经网络参数去学习。点乘其实是求了两个向量的相似度,这看起来也很合理,越相似的权重越大。

方法二:

感知机的方式。可以写作:v^T tanh(W_h h_i + W_s s_t + b_attn)

下一步,将Score进行softmax归一化,得到权重Attention Weight。

再将Attention Weight与h_s作reduce_sum,其实也就是加权求和得到context vector。形如图中的0.1h_s1+0.2h_s2+0.5h_s3+0.2h_s4。如下图:

image-20201202014847762

接下来,再将context vector与Decoder中上一时刻的输出进行concat,拼接成新的向量作为这一时刻Decoder的输入:

image-20201202015307812

至此Attention的主要流程就描述完了,Decoder的输出就可以去接一个全连接层再过一个softmax就可以拿到词表大小的概率分布了,这也就得到了我们的预测值,再将预测值跟标签值算损失函数作反向梯度更新,再更新网络参数,如此往复,也就是神经网络的常规操作了。

代码实现中的各个关键tensor的维度

这里记录一下一般在代码实现整个Seq2Seq Attention时,各个环节各个关键tensor的维度,先对各个变量做一下定义说明:

batch_size:数据分批时一批数据的大小;

embedding_dim:输入对应的embedding的维度,默认Encoder与Decoder一致;

enc_max_len:encoder时输入的最大长度,一般是数据预处理是,阶段或padding之后规范化的长度;

dec_max_len:decoder时输入的最大长度;

enc_hidden_size:encoder中隐藏层的维度;

dec_hidden_size:decoder中隐藏层的维度;

vocab_size:词表大小。

各个关键tensor维度:

Encoder部分:

Encoder的输入:enc_input.shape=(batch_size,enc_max_len)

输入因为是token_id,所以得过一个Embedding层,过完Embedding的输入:enc_input_embedding.shape=(batch_size,enc_max_len,embedding_dim)【每一个词都变成了对应的词向量】

过完Encoder的输出:enc_output.shape=(batch_size,enc_max_len,enc_hidden_size);对应隐藏层的维度:enc_hidden.shape=(batch_size,enc_hidden_size)

Decoder部分:

原始Decoder的输入:dec_input.shape=(batch_size,dec_max_len)

第一个Encoder的输入过Embedding层:dec_input_embedding.shape=(batch_size,1,embedding_dim)

隐藏层:dec_hidden.shape=(batch_size,dec_hidden_size)

Attention中间过程及输出:

score.shape=(batch_size,enc_max_len,1) = Attention_Weight.shape

Attention_Weight与enc_output作reduce_sum,其实是在中间维度上进行的加权求和,得到的context_vextor维度:context_vextor.shape=(batch_size,enc_hidden_size)

将context_vextor升维后与dec_input_embedding进行concat,得到最终每个RNNs的输入:RNNs_input.shape=(batch_size,1,embedding_dim+enc_hidden_size)

输出:dec_output.shape=(batch_size,dec_hidden_size)

如果输出再过一个FC层,则输出维度(batch_size,vocab_size)

小结

没什么特殊小结,纸上得来终觉浅,绝知此事要躬行。代码撸一遍就知道了。改天放上代码链接。晚安嘞您。

参考文章:
没有参考文章,感谢HCT张楠老师的讲解。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值