Image captioning(三)
来源:互联网 发布:ifashion淘宝什么意思 编辑:程序博客网 时间:2024/06/06 14:17
摘要
背景我们已经介绍了,现在我们上篇文章的基础上面引入比较流行的Attention机制
说下本篇文章的贡献:
- image captioning中使用同一种框架引入两种atttention机制。
- 可以洞察模型观察的点在哪里where, 以及观察的是什么what
- 代码我只会演示第二种attention 机制
模型
image encoder
第一层还是卷积层来处理图像信息,但是这里不同的是,我们不像上一篇提到的那样直接复用已有的模型,这里直接处理原始的图片。
为什么要处理原始图片?因为如果要做attention,那么势必要在decoder阶段需要知道聚焦在图片的哪个位置,这样我们就不能直接用encoder出来的很高级的单向量了
需要抽取出来一些原始的特征,每个特征能够表征图像的某一部分,这样在做decoder的时候,attention机制可以知道可以聚焦在哪一块,这样就提高了decoder描述的准确性
假设我们处理图片后生成L=196个D=512维的向量:a=(a1,...,aL),ai∈RD decoder
主要框架我们还是用LSTM,为了引入attention,我们稍微做下变形,就是在原有的state基础上面再增加一个图片的content的信息
假设需要decoder的序列为:经典的LSTM结构:
it ft ot gt Ct ht=σ(wi.[Eyt−1,ht−1]+bi)=σ(wf.[Eyt−1,ht−1]+bf)=σ(wo.[Eyt−1,ht−1]+bo)=tanh(wc.[Eyt−1,ht−1]+bc)=ft∗Ct−1+it∗gt=ot∗tanh(Ct) _, (c, h) = lstm_cell(inputs=x, axis=1), state=[c, h])
调整后:
it ft ot gt Ct ht =σ(wi.[Eyt−1,ht−1,ẑ t]+bi)=σ(wf.[Eyt−1,ht−1,ẑ t]+bf)=σ(wo.[Eyt−1,ht−1,ẑ t]+bo)=tanh(wc.[Eyt−1,ht−1,ẑ t]+bc)=ft∗Ct−1+it∗gt=ot∗tanh(Ct) _, (c, h) = lstm_cell(inputs=tf.concat([x, context], axis=1), state=[c, h])
ẑ t 就是我们的content
后面文中描述的content就是指这个向量,它代表的是我们decoder到目前这个词,应该聚焦的图片信息的哪块内容。
对比两组公式可以直接看出,在每一个计算input是原始的input x增加了content , 那么这样的content是怎么生成?以下的计算逻辑和机器翻译seq2seq的attention模型计算类似,
显现需要聚焦的区域向量为a=(a1,...,aL)
当前hidden output为:ht−1
针对每一个ai 我们会得到一个它和当前的output的相关性分数eti=fatt(ai,ht−1) 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)# features_proj=a_i, h = h_t-1h_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])
这里
fatt 是一个多层感知机层的attention 模型
然后得到softmax 分数αti=exp(eti)∑Lk=1exp(etk) alpha = tf.nn.softmax(out_att)
这样我们可以得到内容向量:
ẑ t=ϕ({ai},{αi}) 这里
ϕ 将多向量转化成单向量的函数,具体怎么计算我们下节介绍:然后是初始的
c0,h0 , 他们是a=(a1,a2,...,aL) 的向量平均分别经过多个线性层c0 h0=finit,c(1N∑iαi)=finit,h(1N∑iαi) with tf.variable_scope('initial_lstm'): # [batch_size, dim_D] 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) # [batch_size, dim_hidden] 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)
到这里,常规的做法我们已经得到输出
ht ,常用的预测yt 的方式是利用softmaxyt=argmaxC(softmax(f(ht)))
f是一个或者多个线性层,然后经过softmax之后,得到概率最大的一个词就是预测值yt 这里作者f定义为:
f=Lo(Eyt−1+Lhht+Lzẑ t) Lo∈Rk∗m,Lh∈Rm∗n,Lz∈Rm∗D
这样:p(yt|a,yt−11=a.exp(Lo(Eyt−1+Lhht+Lzẑ t)))
Attention 机制
本节我们介绍两种attention机制,随机attention 和 确定性 attention
随机attention
顾名思义,随机性attention的在计算
每次的结果可能不一样,所以是一种随机方法。
定义:
它代表在生成第t个词的时候,聚焦在L中各个区域的参数
这里用了p=multinoulli多项分布,那么
我们从分布p生成变量
然后:
本节以下可以忽略
上一篇文章我们知道,loss函数我们可以采用l2 loss 或者softmax 交叉熵的方式
这里因为参数是sample出来的,显然它是不能求导,从而不适用于链式法则,
下面我们引入对数似然来解决优化可导问题
它的对数似然函数为:
这里我们引入了变量
我们令
我们对
其中:
我们替换掉上式,最终得到:
这里的s是从multinoulli分布里面sample出来的,
所以这里:
整体的优化如上面所示,但是由于是采用采样的方式得到中间参数,所以算法波动可能很大,
这里我们使用两种方式降低波动:
梯度优化里面动量的机制类似,第k次mini-batch迭代使用大部分的k-1次的对数似然信息,这样保证足够稳定
bk=0.9bk−1+0.1log(y|s¯k,a) 另外一种是在后面加上一个熵的量
熵
H(s)=−∑np(sn|a)log(p(sn|a))
最终得到:∂Ls∂W≈1N∑n=1N[∂logp(s¯n|a)∂W(logp(y|s¯n,a)−b)λr+λe∂H(s¯n)∂W+∂logp(y|s¯n,a)∂W]
这里要注意点有两个:
ẑ t=∑ist,iai , 这里的st,i 是从分布里面sample出来的,分布的参数是αi - 目标函数是最大化似然函数,似然函数有两种优化形式来降低sample造成的波动
确定性的机制
上面我们使用sample出来的
这里我们不用sample的方式,直接求期望:
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) # (N, L, D) h_att = tf.nn.relu(features_proj + tf.expand_dims(tf.matmul(h, w), 1) + b) # (N, L) out_att = tf.reshape(tf.matmul(tf.reshape(h_att, [-1, self.D]), w_att), [-1, self.L]) alpha = tf.nn.softmax(out_att) context = tf.reduce_sum(features * tf.expand_dims(alpha, 2), 1, name='context') #(N, D)
这样其实整个模型就是可导的
另外:我们可以在这个内容前面增加一个gate常量,这个gate是和
这样
with tf.variable_scope('selector', reuse=reuse): w = tf.get_variable('w', [self.H, 1], initializer=self.weight_initializer) b = tf.get_variable('b', [1], initializer=self.const_initializer) beta = tf.nn.sigmoid(tf.matmul(h, w) + b, 'beta') # (N, 1) context = tf.multiply(beta, context, name='selected_context') return context, beta
当然到了这里其实就可以了
以下可以忽略
下面的步骤其实是为了可以和上面的 margin 对数似然
证明了一波,其实它们两种机制在对数似然的期望上面是一致的
所以统一后,负的对数似然函数为:
训练要点
作者用的是RMSProp/Adam,采用的是自适应学习率
这里还有一个重点是图像生成的特征向量
这里作者直接用VGGNet 在ImageNet上面的预先训练的模型,每张图片抽取出 L=196个D=512 维的像向量
效果:


- Image captioning(三)
- CNN-LSTM Image Captioning
- Image captioning(一)
- Image captioning(二)
- Fluency-Guided Cross-Lingual Image Captioning
- 论文笔记:Image Captioning with Semantic Attention
- image captioning-Show and Tell: A Neural Image Caption Generator
- MAT: A Multimodal Attentive Translator for Image Captioning
- Deep Reinforcement Learning-based Image Captioning with Embedding Reward
- Improved Image Captioning via Policy Gradient optimization of SPIDEr
- Deep Reinforcement Learning-based Image Captioning with Embedding Reward
- 论文笔记:Self-critical Sequence Training for Image Captioning
- Show and Tell: Lessons learned from the 2015 MSCOCO Image Captioning Challenge代码
- 【论文笔记】Show and Tell: Lesson learned from the 2015 MSCOCO Image Captioning Challenge
- 论文笔记:Bottom-Up and Top-Down Attention for Image Captioning and Visual Question Answering
- 17-11-22 Deep Reinforcement Learning-based Image Captioning with Embedding Reward论文随笔
- Show and Tell Lessons learned from the 2015 MSCOCO Image Captioning Challenge论文及tensorflow源码解读
- Show and Tell Lessons learned from the 2015 MSCOCO Image Captioning Challenge论文及tensorflow源码解读(2)
- 图片png,jpg转webp格式
- ELK 日志分析系统
- 表的记录查询(基础sql语句)
- okhttp实现 httpget 和 httppost 的java实现
- CutImage java实现
- Image captioning(三)
- 一文读懂AlphaGo背后的强化学习
- Dropout: A Simple Way to Prevent Neural Networks from Overtting 论文阅读
- iOS检测内存泄漏的方法
- SpringBoot非官方教程 | 第十三篇:springboot集成spring cache
- C++ 符号重载
- 电力窃漏电用户自动识别
- 解决IP分配提示Error, some other host already use address
- SpringCloud教程四:断路器(Hystrix)