来源: 我们在看一个句子的时候,会着重看句子的主语(或者其他成分),这个时候注意力是有重点的,如何让计算机处理的时候也有这个“注意力”呢?
注意力分配:在信息处理过程中,对不同的内容分配不同的注意力权重。
1 Attention在哪里
想知道Attention具体的机制,首先得对seq2seq有一些了解。
seq2seq其实就是 编码 + 解码。
编码做的事情: 对输入序列进行编码, 生成 一个中间的语义编码向量 C (也可以叫做背景向量)
解码做的事情: 对前面的这个C进行解码,得到想要的输出。
没引入 attention的 seq2seq 有什么问题呢?
以机器翻译为例, I like apple 翻译成 我喜欢吃苹果。 seq2seq 的输入就是 前面这个 I like apple, 我们想要的输出就是 我喜欢苹果。 当模型在输出 我 、 喜欢、 苹果 这个的时候 用的语义编码向量是相同的。 这样是不太符合 人类翻译逻辑的, 如果 在输出我的 时候, 模型多把注意力 放在 I 上 就更好了。 所以seq2seq 就引入了 attention。
并且attention放在了 解码当中,将语义编码向量C 更改为 随着输入动态的变化的过程。
2 Attention具体怎么衡量和计算的呢?
不可避免的,为了表述清楚这一点,我在这里插了一张图:
先介绍一下这张图,
(1)编码部分:
最下面的X_1,X_2,X_3,… 为每个时间步自然语言的输入(比如 i like)
往上的两层 h1, h2, …, 是指每个时间步输入编码的特征向量
(2)解码部分:
S_t-1, S_t 表示每个时间步生成翻译的隐藏状态
y_t-1, y_t 为每个时间步翻译的最终输出(比如 我 喜欢)
为了方便说明, 输入序列的时间步我用 t’ 表示, 输出序列的时间步 我用t表示。
(3) C = F (a , h) 这里的 C 表示 上下文向量,也可以说是背景向量,或叫 中间的语义编码向量 。这里的F可以指任何一个函数,在训练时确定。
这里a ,具体是 a_(t, t’) t是指输出的第t个时间步y_t 在输入的第t’个时间步的特征h_t’上花的注意力,换句话说 在 t处生成输出词 y_t,应该花多少注意力在第t’个输入值( 特征向量h_t’)上面。
而整个a矩阵,为注意力(权重)参数, 告诉我们应该花多少注意力,上下文取决于我们得到的特征(h),或者我们从不同时间步得到的激活值。
所以 我们定义上下文(背景向量、或者称 中间的语义编码向量)C 的方式实际上来源于 被注意力权重除权的 不同时间步的 特征值。
(4)接下来就是如何计算 a_(t,t’)的问题
a_(t, t’) = exp( e(t, t’) ) / ( exp(e(t, t’)) 对 t’从1到T_x 求和) 这个公式其实就是 e(t, t’) 的softmax值, 确保对每个输出 y_t时的注意力权重a_(t,:)和为1.
那如何计算 e(t, t’) 呢
图上的两个输入为:
a_<t’> 就是前文所说的 h_t’, 即这个时间步的特征向量,
S_t-1 就是 神经网络在上一个时间步的隐藏状态.
所以: e(t,t’) 由 h_t’ 和 S_t-1 决定。 直观来讲,是想要花多少注意力在 t’的激活值(即 h_t’)上, 似乎很大程度上也会取决于 上一个时间步的输出序列隐藏状态的激活值(即S_t-1)
以上 说明了 a(t,t’)的计算过程。
(5)这个算法的缺点是什么?
算法的复杂度是O(n^3),相当于要花三次方的时间。假设有T_x个输入单词,T_y个输出单词,则注意力参数的总数 T_x* T_y。
这个缺点在机器翻译上可能可以接受,因为翻译的输入输出都不会太长,但在其他应用上会尽量的优化。这个可以通过别的方式进行。
attention机制还可以应用到很多领域,比如图片加标题等等
(6) 总结下来
S_t 由 S_t-1 和 C_t 决定;
C_t 由 a(t)和h 决定,更准确的是 a_(t,t’)和h_t’相乘 ,然后在t’上的求和的结果 决定;
a(t,t’) 由h_t’ 和 S_t-1 决定。(h_t’在不同时刻的解码时是相同的,而c_t在不同时刻的解码是不同的)
本质: 为了实现编解码之间的信息更加有效的传递,在解码的时候根据前一时刻的解码状态,获取不同时刻编码状态的权重值并加权求和, 进而获得该时刻语义编码向量(C_t)。
3 学习资料
公众号《有三AI》
网易云课堂 Andrew Ng https://mooc.study.163.com/learn/2001280005?tid=2001391038#/learn/content?type=detail&id=2001770045