Image captioning(二)
来源:互联网 发布:effective java 知乎 编辑:程序博客网 时间:2024/06/08 13:16
技术上来说
- 往粗了讲,大家听到的是:RNN,CNN,ATTENTION,Embedding 比较有名的名词。
- 往细了讲:卷积,max/min/avg pooling, self-attention, gated-weight,sigmod weight,softmax weight等这些具体的技术细节可能在你构建graph的时候都会或多或少的使用,万变不离其宗,熟悉使用这些东西,后面在遇到各种模型,业务应用的时候就很容易掌握。
- 还有正则化(regularization),归一化(normalization)是很有用的东西,特别是dropout在模型层面防止过拟合,normalization用来平衡各层级的单元的影响范围这些都有很有用的效果。
什么场景用什么技术
我举几个例子:
- 就图像上面来说,附近的点应该是很相关的,所以一个区域附近的点其实可以做sample,平均,max等,所以这是卷积层能够在图像处理里面获得很好收益的基础。
同样传统nlp里面常用的ngram处理技术,很和卷积层的处理有类似之处,特别是类似电商商品标题,或者网页seo优化过的描述,其实他们算不上真正意义上的句子或者有逻辑的语句,可能更多的是名词形容词的堆砌,邻近的词表达的是类似的意思,这个使用卷积做encoder也可以取得不错的效果。
对于RNN来说,它训练的是一个有逻辑的序列,当处理每个元素的时候,它应该记住什么,忘记什么,最终一个序列在不断的记住和忘记之后,生成最终的内容。RNN比较复杂,它的变形也很多,具体可以参见我以往的微文,可以根据具体的东西来修改RNN结构。
对于Attention的应用,更好直观的解释,我们在处理这个任务的时候是不是要聚焦在某个点上面,比如:在看长颈鹿在吃树叶的时候,当我们生成长颈鹿的时候我们聚焦的是图片中的长颈鹿部分,当我们生成树叶的时候我们聚焦的是树叶区域,其他的诸如天空,草地我们其实是没有关注的,对于attention用到的技术,大家也千万不要觉得有多高大上,就是各种求解权重的技巧,求解权重最终一般会落到sigmod或者softmax,关键词是找到重要性的业务逻辑。
模型
回归我们的image caption的模型,简单描述这个模型就是:
利用CNN网络讲图像encoder成一个固定维度的向量,然后这个向量作为RNN输入序列的第一个元素(后面的元素是描述caption序列)来做迭代生成模型训练。
对于生成模型的每一步(生成到序列中的元素),和encoder-decoder里面的decoder模型基本一致,只是我们这里的第一个输入元素是图片encoder向量I,我们给一个生成概率:
当前字符
理论逻辑只有上面这么多,是一个很简单的模型,能够通俗理解。
我们给出论文的 graph 结构如下:

这个结构看起来复杂,其实原理很简单:
- 首先左边是一个CNN encoder结构 I,它的目的就是要将图片encoder成一个固定向量,这里用的CNN结构,可以使用当前比较流行的,比如inception,ResNet等。考虑到一方面由于图像的训练本身需要大量的数据,资源,时间;另一方面图像的描述相对来说是独立的,不应该收到caption生成的影响。所以,这里的图像graph参数需要提前做训练,也可以用其他人已经训练好的模型。
- 然后I作为LSTM的第一个输入input,这里是作为第一个输入,而不是直接作为state,这样输入层就会对图像的结果进行过滤。两外一个注意的是,I作为第一个输入就可以了,不必要在后面每一个都输入,不然会因为图像的噪音造成过拟合。
- 后续就是caption序列生成模型,首先对输入的图像向量I,会生成状态state0,然后s0是一个开始标志比如:这样的字符,然后s0经过LSTM Cell之后,会得到一个output向量输出O1,然后O1经过softmax后会得到每一个term的生成概率, 然后不带迭代这个步骤,直到每个词都生成,这里注意结尾也会加一个标志字符, 比如这种,模型就知道什么词之后最大概率就ende了。
- BeamSearch: 上面说的生成模型是一个迭代的模型,每次生成一个词是一个局部的概率,每个局部词的概率最大不意味着整句话生成的概率最大。这里常用的是BeamSearch递归查询。它的原理是:假设对步骤t,已经生成k个历史最高的结果的序列
[s0,s1,...,sk] ,然后对这k个结果,分别生成N个, 然后对 N*K个结果生成top K个结果,这样增加必要的搜索空间。
结合代码
图片encoder
我们可以从google 模型链接里面下载已经训练好的模型, 比如Inception v3(附件一)。
在代码中,我们直接加载就可以了:
首先记载Inception V3 的训练好的模型文件:
saver = tf.train.Saver(self.inception_variables)saver.restore(sess, self.config.inception_checkpoint_file)
对于输入的images, 我们的目标是获得一个固定维度的tensor
这里直接用tensorflow的graph build,然后经过一个pooling层,
这样每一个图片经过处理后得到一个512维的向量I:
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_basenet, end_points = inception_v3_base(images, scope=scope)with tf.variable_scope("logits"): shape = net.get_shape() net = slim.avg_pool2d(net, shape[1:3], padding="VALID", scope="pool") net = slim.dropout( net, keep_prob=dropout_keep_prob, is_training=is_inception_model_training, scope="dropout") net = slim.flatten(net, scope="flatten")I = net
sequence decoder
- 首先我们初始化一个带droupout的LSTM Cell:
lstm_cell = tf.contrib.rnn.BasicLSTMCell( num_units=512, state_is_tuple=True)lstm_cell = tf.contrib.rnn.DropoutWrapper( lstm_cell, input_keep_prob=0.7, output_keep_prob=0.7)
- 然后图像的encoder向量I作为第一个元素经过Cell
# init zero statezero_state = lstm_cell.zero_state( batch_size=batch_size, dtype=tf.float32)# fist element_, initial_state = lstm_cell(I, zero_state)
- 后续的词开始一次经过LSTM Cell
lstm_outputs, _ = tf.nn.dynamic_rnn(cell=lstm_cell, inputs=seq_input_embedding, sequence_length=sequence_length, initial_state=initial_state, dtype=tf.float32)
- 经过Cell的词xi经过Cell后得到一个decoder的向量,然后需要对这个向量经过一个全联接层后利用softmax得到预测的词yi
logits = tf.contrib.layers.fully_connected( inputs=lstm_outputs, num_outputs=vocab_size)
如果是生成过程:这个已经足够了,只用用logits经过softmax后,得到概率最大的几个词就是生成的下一个词的候选集:
如果是train的过程,生成的概率最大的词是predict yi,label是下一个词xi+1,这样可以利用predict和label得到loss,从而进行优化。
防止过拟合
由于这种监督训练比分类任务更加复杂,需要极大的数据量,而我们的训练数据只有不到10w的数据,所以极易造成过拟合
- CNN模型的参数需要预先训练,比如应用到ImageNet的模型,这里可以用一个训练的比较完整的模型参数,并且保持这些参数在训练的时候不变,这个作用非常大。
- 词向量可以提前训练,但是实时表明这个收益不是很大。
- 模型层面的防止过拟合:dropout,或者ensembling模型(主要是权衡模型隐藏层的宽度和整体的深度)
问题
数据的不可迁移性,不同的数据集很难迁移数据
描述的多样性,一个图片生成的话很多,很难以评估生成效果的好差。
附件一:
https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models
- 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)
- 强化学习的分类
- Virtualbox 下LVS-NAT模式集群部署
- javascript 数组以及对象的深拷贝的方法
- EditText 字数限制,并提醒,解决了粘贴文本不提示bug
- 顶嵌
- Image captioning(二)
- 我们一起学ABAP(05)~流程控制
- Java设计模式-责任链模式
- VMware tool 和window共享文件夹,被坑了许久!!!
- 本地存储SharedPreferecesUtil
- 基于Matlab的对RSA加密算法的一个验证
- aop注解(@around)
- Layui laytpl模板引擎的学习
- oracle数据库初学