attention方法是一种注意力机制,很明显,是为了模仿人的观察和思维方式,将注意力集中到关键信息上,虽然还没有像人一样,完全忽略到不重要的信息,但是其效果毋庸置疑,本篇我们来总结注意力机制的不同方法。
循环神经网络RNN 1—— 基本模型及其变体
循环神经网络RNN 2—— attention注意力机制(附代码)
循环神经网络RNN 3——LSTM及其变体


目录

  • 1,attention的定义
  • 2,基础的attention
  • 3, attention变体
    • 3.1,针对attention向量计算方式的变体
      • 3.1.1 Soft-attention
      • 3.1.2 Hard attention
      • 3.1.3 Local attention
    • 3.2, 针对attention score计算方式的变体
    • 3.3 self-attention
    • 3.3 multi-head attention

1,attention的定义

我们先给出定义,后面给出attention的多种实现方法,带着问题来学习和实践。

1)给定一组向量集合values,以及一个向量query,那么attention机制就是一种根据该query计算values的加权求和的机制。这里query看做是decode的h,values看做是encode的h。
2)attention的重点就是这个集合values中的每个value的“权值”的计算方法。
3)有时候也把这种attention的机制叫做query的输出关注了(或者说叫考虑到了)原文的不同部分(Query attends to the values),因为这其中有对encode加权部分。

2,基础的attention

在Encoder-Decoder结构中,Encoder把所有的输入序列都编码成一个统一的语义特征c再解码,因此, c中必须包含原始序列中的所有信息,它的长度就成了限制模型性能的瓶颈。如机器翻译问题,当要翻译的句子较长时,一个c可能存不下那么多信息,就会造成翻译精度的下降。

Attention机制通过在每个时间输入不同的c来解决这个问题,下图是带有Attention机制的Decoder(注意,是解码部分):

每一个c会自动去选取与当前所要输出的y最合适的上下文信息。具体来说,我们用 a i j a_{ij} aij 衡量Encoder中第j阶段的 h j h_j hj和解码时第i阶段的相关性,最终Decoder中第i阶段的输入的上下文信息 c i c_i ci 就来自于所有hi对 a i j a_{ij} aij的加权和。
以机器翻译为例(将中文翻译成英文):

输入的序列是“我爱中国”,因此,Encoder中的h1、h2、h3、h4就可以分别看做是“我”、“爱”、“中”、“国”所代表的信息。在翻译成英语时,第一个上下文c1应该和“我”这个字最相关,因此对应的 a11 就比较大,而相应的 a12、a13、a14 就比较小。c2应该和“爱”最相关,因此对应的 a22 就比较大。最后的c3和h3、h4最相关,因此 a33 、 a34的值就比较大。

至此,关于Attention模型,我们就只剩最后一个问题了,那就是:这些权重 a i j a_{ij} aij 是怎么来的

事实上, a i j a_{ij} aij同样是从模型中学出的,它实际和Decoder的第i-1阶段的隐状态、Encoder第j个阶段的隐状态有关。

同样还是拿上面的机器翻译举例, a 1 j a_{1j} a1ja 1 j a_{1j} a1j 的计算(此时箭头就表示对h’和 hj 同时做变换):

这个过程如何计算呢? 其实思路很简单:

我们在encoder的过程中保留每个RNN单元的隐藏状态(hidden state)得到 ( h 1 … … h N ) (h_1……h_N) h1hN
此时假设decode的time-step为t,那么将decode前一个隐藏状态 h t − 1 ′ h_{t-1}' ht1,与 h 1 … … h N h_1……h_N h1hN相乘,得到attention score,成为相似度或者“影响度”,或者“匹配得分”.

然后利用softmax,将attention scores转化为概率分布,按照刚才的概率分布,计算encoder的hidden states的加权求和。
a t = ∑ i N α i h i a_t = \sum_i^N\alpha_ih_i at=iNαihi
attention计算完成, a t a_t at就是decoder的第t时刻的注意力向量。然后将 a t a_t at与decode时刻的hidden state并联起来,做后续处理,比如分类等。

3, attention变体

根据以上分析,attention主要分为两部分,score值的计算,权值的计算,剩下的就是加权,所以attention的变体也是围绕着这两个方面来的。一种是在attention 向量的加权求和计算方式上进行创新;一种是在attention score(匹配度或者叫权值)的计算方式上进行创新。

3.1,针对attention向量计算方式的变体

3.1.1 Soft-attention


这是一种基本的attention结构,先通过点乘获得attention score,经过softmax得到alpha权值,然后加权求和得到attention变量(context vecor)
论文:Neural machine translation by jointly learning to align and translate

3.1.2 Hard attention


区别于soft attention,hard-attention寻找特定的h与之相应的timestep对齐。

3.1.3 Local attention

Local-attention介于soft-attention与hard-attention之间,取一个窗口,对窗口内的数据进行加权。

方式有两种:
一种是线性对齐,假设对齐位置pt=t,然后计算窗口内的softmax。
α i = e x p ( s c o r e ( h i ′ , s i ) ) ∑ i e x p ( s c o r e ( h i ′ , s i ) ) \alpha_i=\frac{exp(score(h'_i,s_i))}{\sum_i exp(score(h'_i,s_i))} αi=iexp(score(hi,si))exp(score(hi,si))
另一种是通过一个函数预测pt的位置.
p t = S ∗ s i g m o i d ( V p t ∗ t a n h ( W p ∗ s t ) ) α t = e x p ( s c o r e ( h i ′ , s i ) ) ∑ i e x p ( s c o r e ( h i ′ , s i ) ) ∗ e x p ( − f r a c ( s − p t ) 2 σ 2 ) \begin{aligned} & p_t=S*sigmoid(V_p^t*tanh(W_p*s_t)) \\ & \alpha_t = \frac{exp(score(h'_i,s_i))}{\sum_i exp(score(h'_i,s_i))}*exp(-frac{(s-p_t)}{2\sigma^2}) \end{aligned} pt=Ssigmoid(Vpttanh(Wpst))αt=iexp(score(hi,si))exp(score(hi,si))exp(frac(spt)2σ2)
S表示源句子长度大小, W p W_p WpV p V_p Vp表示模型参数通过训练得到,为了得到 p t p_t pt附近的对齐点,设置一个围绕 p t p_t pt的高斯分布,s是在以 p t p_t pt为中心的窗口中的整数。 p t p_t pt是一个在[0,S]之间的实数. σ 一般取窗口大小的一半.

3.2, 针对attention score计算方式的变体

在计算权值向量之前,我们要计算出attention score.
α = s o f t m a x ( e ) a = ∑ i = 1 N α i h i \begin{aligned} & \alpha = softmax(e)\\ & a = \sum_{i=1}^{N}\alpha_ih_i \end{aligned} α=softmax(e)a=i=1Nαihi
attention score的计算方式有多种:
点积:
e i = s T ∗ h i e_i = s^T*h_i ei=sThi
这里有个假设,就是s和h的维数要一样才能进行点积
乘法
e i = s T ∗ W ∗ h i e_i = s^T*W*h_i ei=sTWhi
W矩阵是训练得到的参数,维度是d2 x d1,d2是s的hidden state输出维数,d1是hi的hidden state维数。
加法
e i = v T ∗ t a n h ( W 1 h i + W 2 s ) e_i = v^T*tanh(W_1h_i+W_2s) ei=vTtanh(W1hi+W2s)
additive attention,是对两种hidden state 分别再训练矩阵然后激活过后再乘以一个参数向量变成一个得分。其中,W1 = d3xd1,W2 = d3*d2,v = d3x1 ,d1,d2,d3分别为h和s还有v的维数,属于超参数。

3.3 self-attention

Self attention也叫做intra-attention在没有任何额外信息的情况下,我们仍然可以通过允许句子使用–self attention机制来处理自己,从句子中提取关注信息。

方法一:以当前的隐藏状态去计算和前面的隐藏状态的得分,作为当前隐藏单元的attention score:
e h i = h t T ∗ W ∗ h i e_{h_i}=h_t^T*W*h_i ehi=htTWhi

方法二:以当前状态本身去计算得分作为当前单元attention score,这种方式更常见,也更简单,例如:

e h i = v α T t a n h ( w α h i ) e h i = t a n h ( w T h i + b ) \begin{aligned} & e_{h_i}=v_{\alpha}^{T}tanh(w_{\alpha}h_i)\\ & e_{h_i} = tanh(w^Th_i+b) \end{aligned} ehi=vαTtanh(wαhi)ehi=tanh(wThi+b)

#coding=utf-8
'''
Single model may achieve LB scores at around 0.043
Don't need to be an expert of feature engineering
All you need is a GPU!!!!!!!The code is tested on Keras 2.0.0 using Theano backend, and Python 3.5referrence Code:https://www.kaggle.com/lystdo/lstm-with-word2vec-embeddings
'''########################################
## import packages
########################################
import os
import re
import csv
import codecs
import numpy as np
import pandas as pd########################################
## set directories and parameters
########################################from keras import backend as K
from keras.engine.topology import Layer
# from keras import initializations
from keras import initializers, regularizers, constraintsnp.random.seed(2018)class Attention(Layer):def __init__(self,W_regularizer=None, b_regularizer=None,W_constraint=None, b_constraint=None,bias=True, **kwargs):"""Keras Layer that implements an Attention mechanism for temporal data.Supports Masking.Follows the work of Raffel et al. [https://arxiv.org/abs/1512.08756]# Input shape3D tensor with shape: `(samples, steps, features)`.# Output shape2D tensor with shape: `(samples, features)`.:param kwargs:"""self.supports_masking = True# self.init = initializations.get('glorot_uniform')self.init = initializers.get('glorot_uniform')self.W_regularizer = regularizers.get(W_regularizer)self.b_regularizer = regularizers.get(b_regularizer)self.W_constraint = constraints.get(W_constraint)self.b_constraint = constraints.get(b_constraint)self.bias = biasself.features_dim = 0super(Attention, self).__init__(**kwargs)def build(self, input_shape):self.step_dim = input_shape[1]assert len(input_shape) == 3 # batch ,timestep , num_featuresprint(input_shape)self.W = self.add_weight((input_shape[-1],), #num_featuresinitializer=self.init,name='{}_W'.format(self.name),regularizer=self.W_regularizer,constraint=self.W_constraint)self.features_dim = input_shape[-1]if self.bias:self.b = self.add_weight((input_shape[1],),#timestepsinitializer='zero',name='{}_b'.format(self.name),regularizer=self.b_regularizer,constraint=self.b_constraint)else:self.b = Noneself.built = Truedef compute_mask(self, input, input_mask=None):# do not pass the mask to the next layersreturn Nonedef call(self, x, mask=None):features_dim = self.features_dimstep_dim = self.step_dimprint(K.reshape(x, (-1, features_dim)))# n, dprint(K.reshape(self.W, (features_dim, 1)))# w= dx1print(K.dot(K.reshape(x, (-1, features_dim)), K.reshape(self.W, (features_dim, 1))))#nx1eij = K.reshape(K.dot(K.reshape(x, (-1, features_dim)), K.reshape(self.W, (features_dim, 1))), (-1, step_dim))#batch,stepprint(eij)if self.bias:eij += self.beij = K.tanh(eij)a = K.exp(eij)# apply mask after the exp. will be re-normalized nextif mask is not None:# Cast the mask to floatX to avoid float64 upcasting in theanoa *= K.cast(mask, K.floatx())a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())print(a)a = K.expand_dims(a)print("expand_dims:")print(a)print("x:")print(x)weighted_input = x * aprint(weighted_input.shape)return K.sum(weighted_input, axis=1)def compute_output_shape(self, input_shape):# return input_shape[0], input_shape[-1]return input_shape[0], self.features_dim

3.3 multi-head attention


Google 在 attention is all you need 中发明了一种叫transformer的网络结构,其中用到了multi-head attention。

首先,google先定义了一下attention的参数 key,value,query三个元素(在seq2seq里面,query是st,key和value都是hi)在self 里面,query 是当前要计算的hi,k和v仍然一样,是其他单元的hidden state。在key value attention里面key和value则是分开了的。)

整个过程仍然没有脱离attention的基本结构,计算attention_score,然后得到权值,加权求和,不过这里可以设置多个head1组合在一起。

class MultiHeadAttention(Layer):def __init__(self, n_heads, head_dim, dropout_rate=.1, masking=True, future=False, trainable=True, **kwargs):self._n_heads = n_headsself._head_dim = head_dimself._dropout_rate = dropout_rateself._masking = maskingself._future = futureself._trainable = trainablesuper(MultiHeadAttention, self).__init__(**kwargs)def build(self, input_shape):self._weights_queries = self.add_weight(shape=(input_shape[0][-1], self._n_heads * self._head_dim),initializer='glorot_uniform',trainable=self._trainable,name='weights_queries')self._weights_keys = self.add_weight(shape=(input_shape[1][-1], self._n_heads * self._head_dim),initializer='glorot_uniform',trainable=self._trainable,name='weights_keys')self._weights_values = self.add_weight(shape=(input_shape[2][-1], self._n_heads * self._head_dim),initializer='glorot_uniform',trainable=self._trainable,name='weights_values')super(MultiHeadAttention, self).build(input_shape)def call(self, inputs):if self._masking:assert len(inputs) == 4, "inputs should be set [queries, keys, values, masks]."queries, keys, values, masks = inputselse:assert len(inputs) == 3, "inputs should be set [queries, keys, values]."queries, keys, values = inputsqueries_linear = K.dot(queries, self._weights_queries) keys_linear = K.dot(keys, self._weights_keys)values_linear = K.dot(values, self._weights_values)queries_multi_heads = tf.concat(tf.split(queries_linear, self._n_heads, axis=2), axis=0)keys_multi_heads = tf.concat(tf.split(keys_linear, self._n_heads, axis=2), axis=0)values_multi_heads = tf.concat(tf.split(values_linear, self._n_heads, axis=2), axis=0)if self._masking:att_inputs = [queries_multi_heads, keys_multi_heads, values_multi_heads, masks]else:att_inputs = [queries_multi_heads, keys_multi_heads, values_multi_heads]attention = ScaledDotProductAttention(masking=self._masking, future=self._future, dropout_rate=self._dropout_rate)att_out = attention(att_inputs)outputs = tf.concat(tf.split(att_out, self._n_heads, axis=0), axis=2)return outputsdef compute_output_shape(self, input_shape):return input_shape

4,总结
综合来看,attention的机制就是一个加权求和的机制,不管是什么变体目前都没有离开这个思路,只要根据已有信息计算的隐藏状态的加权和求和,那么就是使用了attention。self attention就是仅仅在句子内部做加权求和(区别与seq2seq里面的decoder对encoder的隐藏状态做的加权求和),key-value attention是将h分开,很多模型中都可以借鉴key-value方法,比如可以将key-value看作是一样的,multi-attention看成多核并联就好了。

参考资料:

https://www.leiphone.com/news/201709/8tDpwklrKubaecTa.html
https://blog.csdn.net/hahajinbu/article/details/81940355
https://zhuanlan.zhihu.com/p/67115572
https://zhuanlan.zhihu.com/p/118503318
https://zhuanlan.zhihu.com/p/116091338
https://blog.csdn.net/xiaosongshine/article/details/86595847

循环神经网络RNN 2—— attention注意力机制(附代码)相关推荐

  1. 图片的描述生成任务、使用迁移学习实现图片的描述生成过程、CNN编码器+RNN解码器(GRU)的模型架构、BahdanauAttention注意力机制、解码器端的Attention注意力机制

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

  2. 图像处理注意力机制Attention汇总(附代码)

    原文链接: 图像处理注意力机制Attention汇总(附代码,SE.SK.ECA.CBAM.DA.CA等) 1. 介绍 注意力机制(Attention Mechanism)是机器学习中的一种数据处理方 ...

  3. DL之Attention:Attention注意力机制的简介、应用领域之详细攻略

    DL之Attention:Attention注意力机制的简介.应用领域之详细攻略 目录 Attention的简介 1.Why Attention? 2.Attention机制的分类 3.Attenti ...

  4. 基于Transformer的文本情感分析编程实践(Encoder编码器-Decoder解码器框架 + Attention注意力机制 + Positional Encoding位置编码)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

  5. 机器翻译 MXNet(使用含注意力机制的编码器—解码器,即 Encoder编码器-Decoder解码器框架 + Attention注意力机制)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

  6. 基于Seq2Seq的中文聊天机器人编程实践(Encoder编码器-Decoder解码器框架 + Attention注意力机制)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

  7. Transform中的Attention注意力机制

    本文边讲细节边配合代码实战,代码地址为: https://github.com/princewen/tensorflow_practice/tree/master/basic/Basic-Transf ...

  8. Pytorch实现基本循环神经网络RNN (3)

    1.47.Pytorch实现基本循环神经网络RNN (3) Recurrent Neural networks(Rumelhart, 1986)主要用来处理序列型数据,具有对以往数据的记忆功能.下图所 ...

  9. 循环神经网络(RNN)相关知识

    文章目录 RNN概述 前向传播公式 通过时间反向传播(BPTT) RNN确定序列长度方式 其他RNN结构 基于RNN的应用 1,序列数据的分析 2,序列数据的转换 3,序列数据的生成 RNN的不足 1 ...

最新文章

  1. 探讨 | 目前SLAM存在的问题
  2. 我自学python的路-Python学习路线图的总结
  3. html 服务器运行exe,html运行exe文件,兼容浏览器
  4. PMCAFF出品|十一月30篇爆款文章合集,干货、技能、内涵齐飞,总有一款适合你
  5. oracle导出客户机使用us7a,导出已复制的文件系统 - Oracle® ZFS Storage Appliance 管理指南,发行版 OS8.6.0...
  6. 图片查看器 bmp jpg png 动态gif office 2007风格
  7. 【LeetCode】【HOT】208. 实现 Trie (前缀树)
  8. java bank项目答案_Bank项目-java
  9. 物资管理信息系统4 -- 修改密码界面
  10. keil5生成bin文件和axf文件
  11. 用QQ聊天记录生成一个词云
  12. 统计员工业绩app_一哥管家(员工绩效统计)app手机下载-一哥管家(员工绩效统计)安卓最新版下载1.0.8-闪电下载网...
  13. 共阳极管的代码_共阳极数码管显示
  14. 完美解决IDEA 中Maven插件报红详细攻略(含阿里云镜像下载失败),差点泪崩...冲冲冲
  15. 创业书籍推荐,这本书最经典!
  16. 客户端访问https时应无浏览器(含终端)安全警告信息;_(多图)老弟,你连HTTPS 原理都不懂,还给我讲“中间人攻击”,逗我吗......
  17. jovi语音助手安装包_jovi语音助手安装包2016
  18. excel数据透视表总结
  19. conda的常用命令
  20. 嫁我是你一生的赌注,我怎么舍得让你输

热门文章

  1. 每个月5千的工资不想干了想转行测试,软件测试薪资待遇怎么样?
  2. Ensemble Learning(集成学习--AdaBoost,GBDT,Xgboost等)
  3. 女程序员||想逃离的悲惨世界
  4. 有哪些赚钱的软件?说说我是如何每天赚上千元的!
  5. SPP、ASPP与PPM
  6. 黑苹果macOS机型对照表
  7. Pygame游戏 : PONG
  8. 2-44钟静雯_day05
  9. DIV+CSS布局之圣杯布局与双飞翼布局
  10. 特征锦囊:如何根据变量相关性画出热力图?