练手项目之image caption问题记录
20191230更新:
根据github上一位大神的作品,使用PyTorch框架,采用 Encoder-Decoder + Attention 方法重新完成image caption。当采用大小为3的Beam Search方式进行推理时,BLEU-4效果可以达到31%以上。在Flicker8K中随机抽几张图片试试效果,以下分别为原图和预测图。






可以看到语法和语义效果都很不错,直观感受比上次好太多。先占个坑,等有时间再把过程详细整理一下。
以下是2019年8月份记录
小白一个,刚刚费了老大的劲完成一个练手项目——image caption,虽然跑通训练,但是结果却惨不忍睹。于是贴上大神的作品,留待日后慢慢消化。顺便记录下自己踩坑的一些问题。
本次项目采用的模型结构如下。一路输入信息是利用VGG16提取的图像特征,另一路输入信息是利用LSTM提取的单词串特征,输出是预测的下一个单词。即模型的功能是,在给定图像特征和caption前面若干个单词的情况下,能预测出caption的下一个单词;所以循环若干次后即可得到一句完整的caption。采用的数据集是Flicker8K。

目前效果不怎么好,虽然BLEU4结果为17%,能完整输出一句话,但大部分只能识别出狗、草地等这种特别明显的特征,出现不少张冠李戴的描述,甚至于有些句子一直重复这些特征直到被截断,直观感受很不如意。暂认为可以从这几个方面进行改进:试试其他模型结构(比如Seq2Seq等),增加注意力机制,采用更大的数据集,网络调参。
问题目录
交叉验证
Bleu评价
迭代生成器问题(yield/next/send/generator)
Embedding层
模型保存与载入
LSTM层
keras中现成的模型及应用
模型的抽取、冻结、微调
文本预处理
图像预处理及归一化
交叉验证问题
提到交叉验证并非就特指k折交叉验证。交叉验证包括3种:简单交叉验证、k折交叉验证、留一交叉验证。
Bleu评价问题
生成器问题
yield、next、send:
- 有yield语句的函数,返回一个生成器对象;
- 调用next(g)或g.send()时才会正式执行该函数;
- 执行到yield语句时返回一个值,函数暂停,下一次调用时会接着这个断点继续执行;
- 项目中据此改写了图像生成器generator,使其每次返回多张图像信息,加快训练速度(每个epoch由700s缩减至220s)。
模型保存与载入问题
模型保存:
- 方法一:结构(存为json文件)+权重
model_json = model.to_json()
with open("model_architecture.json", "w") as f_obj:
f_obj.write(model_json)
model.save_weights("model_weights.h5")
- 方法二:直接保存模型
model.save('model.h5')
模型载入:
- 方法一:
model = keras.models.model_from_json(open('model_architecture.json').read())
model.load_weights('model_weight_epoch_1.h5')
- 方法二:
model = keras.models.load_model('CIFAR10_model_epoch_1.h5')
其他保存文件:
- np文件
np.save('bottleneck_features.npy', x_train_Dense) # 将提取出的特征保存在.npy文件中
train_data = np.load('bottleneck_features.npy')
- pickle库(参考)
pickle.dump(svm_classifier, open('svm_model_iris.pkl', 'wb')) #写入文件,需要二进制操作
model = pickle.load(open('svm_model_iris.pkl', 'rb'))
#下面还未见过应用
pickle.dumps(obj) #不需要写入文件中,直接返回一个序列化的bytes对象
pickle.loads(bytes_object) #直接从bytes对象中读取序列化的信息
Embedding问题
参考
main_input = Input(shape=(100,), dtype='int32', name='main_input')
x = Embedding(output_dim=512, input_dim=10000, input_length=100)(main_input)
- 任何layer均可以加name参数;
- Embedding层只能作为第一层;
- Input层到Embedding层,内部相当于已经进行onehot转换了,仅需要提供字典大小10000即可;
LSTM问题
LSTM重要参数:keras.layers.LSTM(units, activation='tanh',return_sequences=False, return_state=False),其中units为\(a^{<t>}\)和\(C^{<t>}\)的神经元个数。
LSTM中两个参数(return_sequences, return_state)的理解:
- 两者均默认为false,LSTM对象默认返回一个值,开启return_state后另外返回最后一个cell的隐态\(a^{<t>}\)和\(C^{<t>}\);
- keras中RNN和LSTM等模块没有参数V,要获得\(\hat y^{<t>}\),则需要再接一个Dense层(才是ng课中真正的参数V)转化一下;
- 理解1
- 理解2
LSTM中参数activation和recurrent_activation,暂时理解成前者为求\(\tilde C\)和\(a\)的激活函数,后者为求三大门的激活函数。(待验证。)
keras中现成的模型和应用
keras中自带了一些经典模型,比如VGG、ResNet、Inception等;并提供了这些模型的常见应用场景,比如利用ResNet50分类识别,利用VGG16提取图像特征,抽取模型中间层的输出来提取特征等等。(详见文档中Preprocessing模块的Applications。)
模型抽取、冻结、微调
模型抽取:(模型抽取参考)
- 获取层对象,以便获取其参数
- model.get_layer(name=None,index=None),或者model.layers[index]
- 获取模型输入
- model.input
- 例如:model = Model(inputs=model.input,outputs=model.get_layer(layer_name).output)
模型冻结:(模型冻结参考)
- 通过设置layer对象参数layer.trainable=False,或者模型参数model.trainable=False来控制;(注意layer和model这一参数冲突时默认顺序)
- 通过model.save()和load_model()方法载入的模型冻结时有问题,故推荐使用结构+权重分开的方式保存模型。(model.to_json() + model.save_weights())
模型fine-tune:模型微调参考【待消化】
文本预处理问题
text_to_word_sequence如何添加自定义过滤词?比如加's
- 目前解决:采用正则表达式先换掉's,再统一过滤掉。
三种常用函数:
- keras.preprocessing.text.text_to_word_sequence
- 将一句话打散成单词;输入是字符串,输出是单词列表;
- 参数:filter可以滤掉不必要的标点符号;lower默认转小写;split默认以空格划分;
- keras.preprocessing.text.Tokenizer
- 单词与编码的互换工具;
- 常用方法(注意输入输出格式):
- tokenizer.fit_on_texts(["今天 北京 下 雨 了", "我 今天 加班"])
- tokenizer.texts_to_sequences(["下 雨 我 加班", "北京 下雨"])
- keras.preprocessing.sequence.pad_sequences
- 填充序列至固定长度
- pad_sequences([[1,2,3],[4,5,6]],maxlen=10,padding='pre')
- 填充序列至固定长度
图像预处理及归一化问题
2.项目中利用VGG16提取图像特征前对图像预处理,为啥要把RGB转为BGR?这个VGG16训练时前处理是用BGR?
20191011注:keras.applications.vgg16.preprocess_input中根据不同的模式进行了通道互换(将RGB转为BGR)和通道零均值化(每个通道减去各自均值),源代码见D:\Anaconda3\Lib\site-packages\keras_applications\imagenet_utils.py。(至于为啥要由RGB转为BGR,推测可能是VGG16模型训练时候用了OpenCV,因为只有OpenCV用的BGR格式)
练手项目之image caption问题记录的更多相关文章
- 20个Java练手项目,献给嗜学如狂的人
给大家推荐一条由浅入深的JAVA学习路径,首先完成 Java基础.JDK.JDBC.正则表达式等基础实验,然后进阶到 J2SE 和 SSH 框架学习.最后再通过有趣的练手项目进行巩固. JAVA基础 ...
- 去哪找Java练手项目?
经常有读者在微信上问我: 在学编程的过程中,看了不少书.视频课程,但是看完.听完之后感觉还是不会编程,想找一些项目来练手,但是不知道去哪儿找? 类似的问题,有不少读者问,估计是大部分人的困惑. 练手项 ...
- Python学习路径及练手项目合集
Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159
- web前端学习部落22群分享给需要前端练手项目
前端学习还是很有趣的,可以较快的上手然后自己开发一些好玩的项目来练手,网上也可以一抓一大把关于前端开发的小项目,可是还是有新手在学习的时候不知道可以做什么,以及怎么做,因此,就整理了一些前端项目教程, ...
- webpack练手项目之easySlide(三):commonChunks(转)
Hello,大家好. 在之前两篇文章中: webpack练手项目之easySlide(一):初探webpack webpack练手项目之easySlide(二):代码分割 与大家分享了webpack的 ...
- webpack练手项目之easySlide(二):代码分割(转)
在上一篇 webpack练手项目之easySlide(一):初探webpack 中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但是乍一看webpack ...
- Python之路【第二十四篇】:Python学习路径及练手项目合集
Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...
- 练手项目:利用pygame库编写射击游戏
本项目使用pygame模块编写了射击游戏,目的在于训练自己的Python基本功.了解中小型程序框架以及学习代码重构等.游戏具有一定的可玩性,感兴趣的可以试一下. 项目说明:出自<Python编程 ...
- Vue练手项目(包含typescript版本)
本项目的git仓库https://github.com/lznism/xiachufang-vue 对应的使用typescript实现的版本地址https://github.com/lznism/xi ...
随机推荐
- JS基础入门篇(三十四)— 面向对象(一)
1.对象 对象的定义 : 对象 是 由 键值对 组成的无序集合. 创建对象两种方法 : 方法一 : 字面量方法 var obj = {name: "k"}; 方法二 : new O ...
- Java Web 之HttpServletRequest对象初识
通过request对象获得请求行 获得客户端请求方式:String getMethod(); 获得请求的资源: String getRequestURL(); String getQueryStrin ...
- python request post请求body中有json数组
今天被这个卡了好久,最后解决发现是个小问题,哈哈 记录: 用request发送post请求,原来当body都是普通的字符串和数字时一切顺利,今天遇到了body里面有json数组,结果就是报参数错误 解 ...
- restful风格接口和spring的运用
Restful风格的API是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机 ...
- ECS运维:操作系统有异常?诊断日志来帮忙!
云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新.阿里云使用严格的IDC标准.服务器准入标准 ...
- JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性
在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...
- Bugku | Easy_Re
学到一个函数: _mm_storeu_si128((__m128i *)&v5, _mm_loadu_si128((const __m128i *)&xmmword_413E34)); ...
- jQuery 问题收集
1.页面动态生成的dom元素,监听事件失效.需用事件代理进行监听. 对于动态绑定元素可以这样写 $(document).on('click', '.xxx', function() { // do s ...
- NOIP 历年试题大致考点总结
总的来说,水平还不够-- 要努力了! NOIP2012 D1T1 模拟, 字符串 D1T2 贪心, 数学 (推导贪心策略), 高精度 D1T3 unsolved 开车旅行 倍增 D2T1 解线性模方程 ...
- [CSP-S模拟测试]:Lighthouse(哈密顿回路+容斥)
题目背景 $Billions\ of\ lighthouses...stuck\ at\ the\ far\ end\ of\ the\ sky.$ 题目描述 平面有$n$个灯塔,初始时两两之间可以相 ...