(multi-head attention 用于CNN相关理解)
饭前小菜
在早期的Machine Translation(机器翻译)中,Attention机制与RNN的结合。机器翻译解决的是输入是一串在某种语言中的一句话,输出是目标语言相对应的话的问题,如将中文翻译成英文。通常的配置是encoder-decoder结构,即encoder读入输入的句子并将其转换为一个固定长度的向量,然后decoder再将这个向量翻译成对应的目标语言的文字。
存在的问题:RNN机制实际上存在长梯度消失的问题,对于较长的句子,我们很难寄希望于将输入的序列转化为定长的向量而保存所有的有效信息,所有随着翻译句子的长度的增加,这种结构的效果会显著下降。
解决办法:那当然就是我们的attention啦!
multi-head attention 是继self-attention之后又一重大研究成果,其出发点是在transformer模型上,改进之前使用的传统attention。本人是将multi-head attention 用于CNN模型当中,踩了不少坑,但是复现代码的人确实是大牛。相关参考参考代码
传统attention
举个例子:
翻译’knowledge’时,只需要将注意力放在源句子中“知识”的部分,当翻译“power”时,只需要将注意力集中在“力量”。这样,当我们的decoder预测目标翻译的时候就可以看到encoder的所有信息,而不仅局限于原来模型中定长的隐向量,并且不会丧失较长的信息
transformer中的attention
问题来了
当然,既然attention机制如此的有效,那可不可以去掉模型中的RNN的部分,仅仅利用attention呢?答案是当然可以啦!
// attention
def _attention(self,inputs, attention_size, time_major=False, return_alphas=False):
if isinstance(inputs, tuple):
# In case of Bi-RNN, concatenate the forward and the backward RNN outputs.
inputs = tf.concat(inputs, 2)
if time_major:
# (T,B,D) => (B,T,D)
inputs = tf.array_ops.transpose(inputs, [1, 0, 2])
hidden_size = inputs.shape[2].value # D value - hidden size of the RNN layer
# Trainable parameters
W_omega = tf.Variable(tf.random_normal([hidden_size, attention_size], stddev=0.1