浅谈Tensorflow加载Vgg预训练模型的几个注意事项


Posted in Python onMay 26, 2020

写这个博客的关键Bug: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64。本博客将围绕 加载图片 和 保存图片到本地 来详细解释和解决上述的Bug及其引出来的一系列Bug。

加载图片

首先,造成上述Bug的代码如下所示

image_path = "data/test.jpg" # 本地的测试图片
 
image_raw = tf.gfile.GFile(image_path, 'rb').read()
# 一定要tf.float(),否则会报错
image_decoded = tf.image.decode_jpeg(image_raw)
 
# 扩展图片的维度,从三维变成四维,符合Vgg19的输入接口
image_expand_dim = tf.expand_dims(image_decoded, 0)
 
# 定义Vgg19模型
vgg19 = VGG19(data_path)
net = vgg19.feed_forward(image_expand_dim, 'vgg19')
print(net)

上述代码是加载Vgg19预训练模型,并传入图片得到所有层的特征图,具体的代码实现和原理讲解可参考我的另一篇博客:Tensorflow加载Vgg预训练模型。那么,为什么代码会出现: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64,这个Bug呢?

这句英文翻译过来是指:传递的值类型是uint8,但是接受的参数类型必须是float的那几种。故原因就是传入值的数据类型错了,那么如何解决这个Bug呢,很简单

image_path = "data/test.jpg" # 本地的测试图片
 
image_raw = tf.gfile.GFile(image_path, 'rb').read()
# 一定要tf.float(),否则会报错
image_decoded = tf.to_float(tf.image.decode_jpeg(image_raw))
 
# 扩展图片的维度,从三维变成四维,符合Vgg19的输入接口
image_expand_dim = tf.expand_dims(image_decoded, 0)
 
# 定义Vgg19模型
vgg19 = VGG19(data_path)
net = vgg19.feed_forward(image_expand_dim, 'vgg19')
print(net)

这两个代码块唯一的变动就是:image_decoded结果在输出前加了一个tf.float(),将其转换为float类型。

在tensorflow API中,tf.image.decode_jpeg()默认读取的图片数据格式为unit8,而不是float。uint8数据的范围在(0, 255)中,正好符合图片的像素范围(0, 255)。但是,保存在本地的Vgg19预训练模型的数据接口为float,所以才造成了本文开头的Bug。

这里还要提一点,若是使用PIL的方法来加载图片,则不会出现上述的Bug,因为通过PIL得到的图片格式是float,而不是uint8,故不需要转换。

很多同学可能会疑惑,若是强行改变了原图片的数据格式,从uint8类型转变成float,会不会导致数据改变或者出错?故我做了下面这个实验:

image_path = "data/3.jpg"
image_raw = tf.gfile.GFile(image_path, 'rb').read()
image_unit8 = tf.image.decode_jpeg(image_raw)
image_float = tf.to_float(image_unit8)
 
with tf.Session() as sess:
 image_unit8_, image_float_ = sess.run([image_unit8, image_float])
 
print("image_unit8_", image_unit8_)
print("image_float_ ", image_float_ )

代码结果如下:

image_unit8_
 [180, 192, 204],
 [183, 195, 207],
 [186, 198, 210],
 ...,
 [191, 205, 218],
 [191, 205, 218],
 [190, 204, 217]],
 
 image_float_ 
 [180., 192., 204.],
 [183., 195., 207.],
 [186., 198., 210.],
 ...,
 [191., 205., 218.],
 [191., 205., 218.],
 [190., 204., 217.]],

可以看到,数据根本没有变化,只是后面多加了个小数点,变得只有类型,而没有强制改变值,故同学们不需要过度担心。

保存图片到本地

在加载图片的时候,为了使用保存在本地的预训练Vgg19模型,我们需要将读取的图片由uint8格式转换成float格式。那若是我们想将已经转换为float格式的图片再保存到本地,该怎么做呢?

首先,我们根据上述的文字的意思读取图片,并且将其转换为float格式,在将读取的图片再次保存到本地之前,我们首先可视化一下转换格式后的图片,代码如下:

import tensorflow as tf
from matplotlib import pyplot as plt
image_path = "data/boat.jpg"
 
image_raw = tf.gfile.GFile(image_path, 'rb').read()
image_decoded = tf.image.decode_jpeg(image_raw)
image_decoded = tf.to_float(image_decoded)
 
with tf.Session() as sess:
 image_decoded_ = sess.run(image_decoded)
 plt.imshow(image_decoded_)
 plt.show()

生成的图片如下图所示:

浅谈Tensorflow加载Vgg预训练模型的几个注意事项

左边是原图,右边是转换为float格式的图片,可见将图片转换为float格式,虽然数值没有造成太大影响,但是若想将图片保存到本地就会出现问题。

说了这么多,只为了说一点,在保存图片到本地之前,需要将其格式从float转回uint8,否则会造成一系列错误:图片显示异常,API报错等。正确的保存代码如下:

save_path = "data/boat_copy.jpg"
image_uint = tf.cast(image_decoded, tf.uint8)
with tf.Session() as sess:
 with open(save_path, 'wb') as img:
 image_saved = sess.run(tf.image.encode_jpeg(image_uint))
 img.write(image_saved)

其中只有一句话最关键,即 tf.cast(image_decoded, tf.uint8)。

以上这篇浅谈Tensorflow加载Vgg预训练模型的几个注意事项就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python获取标准北京时间的方法
Mar 24 Python
约瑟夫问题的Python和C++求解方法
Aug 20 Python
Python基础中所出现的异常报错总结
Nov 19 Python
Python反转序列的方法实例分析
Mar 21 Python
Python自动抢红包教程详解
Jun 11 Python
对python中的*args与**kwgs的含义与作用详解
Aug 28 Python
Python使用matplotlib绘制三维参数曲线操作示例
Sep 10 Python
使用Bazel编译TensorBoard教程
Feb 15 Python
python目标检测给图画框,bbox画到图上并保存案例
Mar 10 Python
动态设置django的model field的默认值操作步骤
Mar 30 Python
keras 解决加载lstm+crf模型出错的问题
Jun 10 Python
python利用proxybroker构建爬虫免费IP代理池的实现
Feb 21 Python
Tensorflow加载Vgg预训练模型操作
May 26 #Python
PyQt5如何将.ui文件转换为.py文件的实例代码
May 26 #Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
May 26 #Python
python 日志模块 日志等级设置失效的解决方案
May 26 #Python
python3.7+selenium模拟淘宝登录功能的实现
May 26 #Python
TensorFlow固化模型的实现操作
May 26 #Python
Python 如何批量更新已安装的库
May 26 #Python
You might like
PHP的FTP学习(一)[转自奥索]
2006/10/09 PHP
php获取url字符串截取路径的文件名和扩展名的函数
2010/01/22 PHP
PHP 冒泡排序算法的实现代码
2010/08/08 PHP
基于php设计模式中单例模式的应用分析
2013/05/15 PHP
PHP无限分类(树形类)
2013/09/28 PHP
PHP中防止SQL注入方法详解
2014/12/25 PHP
PHP中预定义的6种接口介绍
2015/05/12 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
JS 页面自动加载函数(兼容多浏览器)
2009/05/18 Javascript
jquery实现下拉菜单的二级联动利用json对象从DB取值显示联动
2014/03/27 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
2015/08/09 Javascript
JS+CSS实现带小三角指引的滑动门效果
2015/09/22 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
javascript实现图片轮播效果
2016/01/20 Javascript
bootstrap组件之导航组件使用方法
2017/01/19 Javascript
运用jQuery写的验证表单(实例讲解)
2017/07/06 jQuery
基于jquery实现多选下拉列表
2017/08/02 jQuery
使用webpack打包koa2 框架app
2018/02/02 Javascript
详解vue-cli 本地开发mock数据使用方法
2018/05/29 Javascript
使用Sonarqube扫描Javascript代码的示例
2018/12/26 Javascript
webpack DllPlugin xxx is not defined解决办法
2019/12/13 Javascript
基于Vue的侧边目录组件的实现
2020/02/05 Javascript
python读写csv文件方法详细总结
2019/07/05 Python
Python脚本去除文件的只读性操作
2020/03/05 Python
html5 浏览器支持 如何让所有的浏览器都支持HTML5标签样式
2012/12/07 HTML / CSS
移动端html5 meta标签的神奇功效
2016/01/06 HTML / CSS
运动鞋、足球鞋和慕尼黑球衣:Sport Münzinger
2019/08/26 全球购物
工作失误检讨书范文大全
2014/01/13 职场文书
计算机专业毕业生自我鉴定
2014/01/16 职场文书
土木工程专业推荐信
2014/02/19 职场文书
房屋公证委托书
2014/04/03 职场文书
小学安全教育月活动总结
2014/07/07 职场文书
开工典礼致辞
2015/07/29 职场文书
laravel ajax curd 搜索登录判断功能的实现
2021/04/17 PHP
JAVA 线程池(池化技术)的实现原理
2022/04/28 Java/Android