前言

这里学习的注意力模型是我在研究image caption过程中的出来的经验总结,其实这个注意力模型理解起来并不难,但是国内的博文写的都很不详细或说很不明确,我在看了 attention-mechanism后才完全明白。得以进行后续工作。

这里的注意力模型是论文 Show,Attend and Tell:Neural Image Caption Generation with Visual Attention里设计的,但是注意力模型在大体上来讲都是相通的。

先给大家介绍一下我需要注意力模型的背景。

I是图片信息矩阵也就是[224,224,3],通过前面的cnn也就是所谓的sequence-sequence模型中的encoder,我用的是vgg19,得到a,这里的a其实是[14*14,512]=[196,512],很形象吧,代表的是图片被分成了这么多个区域,后面就看我们单词注意在哪个区域了,大家可以先这么泛泛理解。通过了本文要讲的Attention之后得到z。这个z是一个区域概率,也就是当前的单词在哪个图像区域的概率最大。然后z组合单词的embedding去训练。

好了,先这么大概理解一下这张图就好。下面我们来详细解剖attention,附有代码~

attention的内部结构是什么?

这里的c其实一个隐含输入,计算方式如下

首先我们这么个函数:

def _get_initial_lstm(self, features):
with tf.variable_scope('initial_lstm'):
features_mean = tf.reduce_mean(features, 1) w_h = tf.get_variable('w_h', [self.D, self.H], initializer=self.weight_initializer)
b_h = tf.get_variable('b_h', [self.H], initializer=self.const_initializer)
h = tf.nn.tanh(tf.matmul(features_mean, w_h) + b_h) w_c = tf.get_variable('w_c', [self.D, self.H], initializer=self.weight_initializer)
b_c = tf.get_variable('b_c', [self.H], initializer=self.const_initializer)
c = tf.nn.tanh(tf.matmul(features_mean, w_c) + b_c)
return c, h

上面的c你可以暂时不用管,是lstm中的memory state,输入feature就是通过cnn跑出来的a,我们暂时考虑batch=1,就认为这个a是一张图片生成的。所以a的维度是[1,196,512]

y向量代表的就是feature。

下面我们打开这个黑盒子来看看里面到底是在做什么处理。

上图中可以看到

这里的tanh不能替换成ReLU函数,一旦替换成ReLU函数,因为有很多负值就会消失,会很影响后面的结果,会造成最后Inference句子时,不管你输入什么图片矩阵的到的句子都是一样的。不能随便用激活函数!!!ReLU是能解决梯度消散问题,但是在这里我们需要负值信息,所以只能用tanh

c和y在输入到tanh之前要做个全连接,代码如下。

        w = tf.get_variable('w', [self.H, self.D], initializer=self.weight_initializer)
b = tf.get_variable('b', [self.D], initializer=self.const_initializer)
w_att = tf.get_variable('w_att', [self.D, 1], initializer=self.weight_initializer) h_att = tf.nn.relu(features_proj + tf.expand_dims(tf.matmul(h, w), 1) + b) # (N, L, D)

这里的features_proj是feature已经做了全连接后的矩阵。并且在上面计算h_att中你可以看到一个矩阵的传播机制,也就是relu函数里的加法。features_proj和后面的那个维度是不一样的。

def _project_features(self, features):
with tf.variable_scope('project_features'):
w = tf.get_variable('w', [self.D, self.D], initializer=self.weight_initializer)
features_flat = tf.reshape(features, [-1, self.D])
features_proj = tf.matmul(features_flat, w)
features_proj = tf.reshape(features_proj, [-1, self.L, self.D])
return features_proj

然后要做softmax了,这里有个点,因为上面得到的m的维度是[1,196,512],1是代表batch数量。经过softmax后想要得到的是维度为[1,196]的矩阵也就是每个区域的注意力权值。所以

out_att = tf.reshape(tf.matmul(tf.reshape(h_att, [-1, self.D]), w_att), [-1, self.L])   # (N, L)
alpha = tf.nn.softmax(out_att)

最后计算s就是一个相乘。

context = tf.reduce_sum(features * tf.expand_dims(alpha, 2), 1, name='context')   #(N, D)

这里也是有个传播的机制,features维度[1,196,512],后面那个维度[1,196,1]。

最后给个完整的注意力模型代码。

    def _attention_layer(self, features, features_proj, h, reuse=False):
with tf.variable_scope('attention_layer', reuse=reuse):
w = tf.get_variable('w', [self.H, self.D], initializer=self.weight_initializer)
b = tf.get_variable('b', [self.D], initializer=self.const_initializer)
w_att = tf.get_variable('w_att', [self.D, 1], initializer=self.weight_initializer) h_att = tf.nn.relu(features_proj + tf.expand_dims(tf.matmul(h, w), 1) + b) # (N, L, D)
out_att = tf.reshape(tf.matmul(tf.reshape(h_att, [-1, self.D]), w_att), [-1, self.L]) # (N, L)
alpha = tf.nn.softmax(out_att)
context = tf.reduce_sum(features * tf.expand_dims(alpha, 2), 1, name='context') #(N, D)
return context, alpha

如果大家想研究整个完整的show-attend-tell模型,可以去看看github链接

以上我们讲的是soft_attention,还有一个hard_attention。hard_attention比较不适合于反向传播,其原理是取代了我们之前将softmax后的所有结果相加,使用采样其中一个作为z。反向传播的梯度就不好算了,这里用蒙特卡洛采样方式。

ok,回到我们的image_caption中,看下图

这个图其实不太准确,每一个z其实还会用tf.concat连接上当前这个lstm_cell的单词embedding输入。也就是维度变成[512]+[512]=[1024]

这样就可以结合当前单词和图像区域的关系了,我觉得注意力模型还是很巧妙的。

赞  |   1收藏  |  2
 

https://segmentfault.com/a/1190000011744246

attention 介绍的更多相关文章

  1. 6. 从Encoder-Decoder(Seq2Seq)理解Attention的本质

    1. 语言模型 2. Attention Is All You Need(Transformer)算法原理解析 3. ELMo算法原理解析 4. OpenAI GPT算法原理解析 5. BERT算法原 ...

  2. 机器翻译注意力机制及其PyTorch实现

    前面阐述注意力理论知识,后面简单描述PyTorch利用注意力实现机器翻译 Effective Approaches to Attention-based Neural Machine Translat ...

  3. Attention注意力机制介绍

    什么是Attention机制 Attention机制通俗的讲就是把注意力集中放在重要的点上,而忽略其他不重要的因素.其中重要程度的判断取决于应用场景,拿个现实生活中的例子,比如1000个人眼中有100 ...

  4. 模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理、分类及应用

    模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理.分类及应用 lqfarmer 深度学习研究员.欢迎扫描头像二维码,获取更多精彩内容. 946 人赞同了该文章 Atte ...

  5. Seq2Seq和Attention机制入门介绍

    1.Sequence Generation 1.1.引入 在循环神经网络(RNN)入门详细介绍一文中,我们简单介绍了Seq2Seq,我们在这里展开一下 一个句子是由 characters(字) 或 w ...

  6. 关于ArcGIS API for JavaScript中basemap的总结介绍(一)

    实际上basemap这个概念并不只在arcgis中才有,在Python中有一个matplotlib basemap toolkit(https://pypi.python.org/pypi/basem ...

  7. (转)注意力机制(Attention Mechanism)在自然语言处理中的应用

    注意力机制(Attention Mechanism)在自然语言处理中的应用 本文转自:http://www.cnblogs.com/robert-dlut/p/5952032.html  近年来,深度 ...

  8. 论文笔记之:Deep Attention Recurrent Q-Network

    Deep Attention Recurrent Q-Network 5vision groups  摘要:本文将 DQN 引入了 Attention 机制,使得学习更具有方向性和指导性.(前段时间做 ...

  9. 注意力机制(Attention Mechanism)在自然语言处理中的应用

    注意力机制(Attention Mechanism)在自然语言处理中的应用 近年来,深度学习的研究越来越深入,在各个领域也都获得了不少突破性的进展.基于注意力(attention)机制的神经网络成为了 ...

随机推荐

  1. Centos7关闭防火墙

    CentOS 7.0默认使用的是firewall作为防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewal ...

  2. Hillstone设备管理-恢复出厂设置

    1.CLI命令行操作 unset all: 根据提示选择是否保存当前配置y/n: 选择是否重启y/n: 系统重启后即恢复到出厂设置. 2.webUI操作 “系统”—“配置”,点击“清除”按钮,系统会提 ...

  3. json对象和字符串的相互转换

    JSON.stringify(obj)       将JSON对象转为字符串. JSON.parse(string)       将字符串转为JSON对象格式. 后台给你数据的时候,有时候会给你字符串 ...

  4. 记录Queue插入的时候报错

    Queue 队列  特性  先进先出     和栈 Stack  非常相似 不过 栈 遵循 后进先出 Queue 和Stack 都存在数据并发的 问题 public static Queue<P ...

  5. .net core中的分布式缓存和负载均衡

    通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性,缓存对不经常更改的数据效果最佳,缓存生成的数据副本的返回速度可以比从原始源返回更快.ASP.NET Core 支持多种不同的缓存,最简 ...

  6. rest_framework的视图组件继承过哪些类?

  7. 移动端h5调试方法

    charles代理 使用技巧如下: http://www.jianshu.com/p/fdd7c681929c 1.手机wifi连接代理 以iphone为例,长按住wifi, 进入下一页,可看到 HT ...

  8. NodeManager介绍

    原文链接: http://blog.csdn.net/zhangzhebjut/article/details/37730013 参考文档: https://blog.csdn.net/u013384 ...

  9. pyadb关于python操作adb的资料

    3.最后adb命令由于是android的原生操作命令,支持实现的功能非常多.这里举几个pyapp里实现的功能例子:获取,修改手机当前使用的输入法(adb shell ime list),获取当前手机界 ...

  10. github删除

    https://blog.csdn.net/weixin_42152081/article/details/80635777