使用 Keras (PIL) 和 TensorFlow 调整图像大小不一致?

2024-03-04

我对以下之间明显的不一致感到困扰:

  1. 图像调整大小功能来自keras.preprocessing,它们是 PIL 函数的包装器
  2. TensorFlow 中的图像大小调整函数tf.image.

我正在使用 Keras 为计算机视觉任务训练深度学习模型(实际上,使用tf.keras,但这在这里并不重要)。然后,我使用 TF Serving 为模型提供服务,这要求我将图像作为编码的字节字符串发送到模型,并使用它们进行解码tf.image.decode_png在查看模型图之前。

当我调整图像大小时会出现问题。与使用双线性插值(或任何其他方法)调整大小相比,PIL 给出了不同的结果tf.image,以至于模型的分类根据我使用的函数而变化。

下面的代码提供了一个可重现的示例。

import numpy as np 
from PIL import Image
from keras.preprocessing.image import load_img, img_to_array
import tensorflow as tf

# Generate an 'image' with numpy, save as png
np.random.seed(42)
image = np.random.randint(0, 255, size=(256, 256, 3)).astype(np.uint8)
Image.fromarray(image).convert("RGB").save('my_image.png')

现在,让我们通过两种方式加载图像。首先使用 Keras 的 PIL 包装器(如在模型训练期间),然后编码为二进制字符串并使用 TensorFlow 函数进行解码(如在我的模型服务器中)。

# Using Keras PIL wrappers
keras_image = img_to_array(load_img('./my_image.png')) 

# Using TF functionalities
with tf.Session() as sess:
    with open('./my_image.png', 'rb') as f:
        tf_image_ = tf.image.decode_png(f.read())
    tf_image = sess.run(tf_image_)

到目前为止一切都很好,因为两个图像完全相同(除了 dtype,因为 Keras 已将图像转换为 float32):

# Assert equality
np.array_equal(keras_image, tf_image)
> True

然而,重复此代码并调整大小会产生不同的结果:

# Using Keras PIL wrappers, with resizing
keras_image_rs = img_to_array(load_img('./my_image.png',
                             target_size=(224, 224),
                             interpolation='bilinear'))

# Using TF functionalities, with resizing
with tf.Session() as sess:
    with open('./my_image.png', 'rb') as f:
        tf_image_ = tf.image.decode_png(f.read())
        # Add and remove dimension
        # As tf.image.resize_* requires a batch dimension
        tf_image_ = tf.expand_dims(tf_image_, 0)
        tf_image_ = tf.image.resize_bilinear(tf_image_,
                                            [224, 224], 
                                             align_corners=True)
        tf_image_ = tf.squeeze(tf_image_, axis=[0])

    tf_image_rs = sess.run(tf_image_)

# Assert equality
np.array_equal(keras_image_rs, tf_image_rs)
> False

两个图像之间的平均绝对差异是不可忽略的:

np.mean(np.abs(keras_image_rs - tf_image_rs))
7.982703

我玩的是align_corners论点,并尝试了其他可用的插值方法。没有一个提供与使用 PIL 调整图像大小时相同的输出。这很烦人,因为它让我在训练和测试结果之间产生偏差。有谁知道导致这种行为的原因或如何解决它?


所描述的行为完全符合本文中所写的内容:Tensorflow 的 tf.image.resize 如何偷走了我 60 天的生活 https://hackernoon.com/how-tensorflows-tf-image-resize-stole-60-days-of-my-life-aba5eb093f35

简而言之:是的,PIL/sklearn/OpenCV 和其他用于图像处理的常见库具有正确的行为,而 tf.image.resize 具有不同的行为,不会更改,以免破坏旧的训练模型。

因此,您应该始终使用计算图之外的相同库来预处理图像。

相关 github 线程的链接:https://github.com/tensorflow/tensorflow/issues/6720 https://github.com/tensorflow/tensorflow/issues/6720

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Keras (PIL) 和 TensorFlow 调整图像大小不一致? 的相关文章

随机推荐

  • 如何更新TileOverlay而不闪烁?

    我有一些动态图块内容要显示在地图顶部 具体来说 天气图像 雷达 卫星 温度等 我正在使用适用于 Android v2 的 Google 地图 API 我遇到的问题是 显然更新图块图像的唯一方法 即当新数据到达时 或者当帧在延时动画中前进时
  • 使用 LoadLibrary 在 .pyd 中加载 cython cdef 函数时出现问题

    我正在尝试在 C 中动态加载 cythonized pyd 在 Linux 机器中创建一个 so 文件 使用 so 我可以执行以下操作 plugin dlopen foo so RTLD LAZY init dlsym plugin PyI
  • 调试 Jersey 解组错误 - 错误请求语法不正确

    我正在 Glassfish 上的 Jersey 的帮助下构建 REST Web 服务 现在我正在为我的搜索查询的自定义输入源而苦苦挣扎 如果有搜索方法 POST Path search Consumes application xml ap
  • HSTS 预加载列表 - www 网站可能存在 SEO 问题

    让我在这里解释一下现实世界的情况 我运行网站https www liloo ro https www liloo ro我想为其启用 HSTS HSTS 预加载 问题是为了将其提交给预加载列表 https hstspreload org th
  • 无法制作固定大小数组的向量?

    我有这个奇怪的问题 vector
  • 更改 igraph 图中子图的颜色

    我有以下代码来绘制图的最小生成树 g is an igraph graph mst minimum spanning tree g E g color lt SkyBlue2 how to I make mst a different co
  • 无法访问用户控制组件[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 在我的用户控件中 我有一个名为的 datagridviewdgvCustomers 我想在 gridview 中加载客户
  • 延长 R 中绘图轴的长度?

    如何在 R 中扩展轴线以覆盖数据范围 例如 在 我的数据大约为 2100 我希望 x 轴的线能走那么远 但不要在 2100 处做刻度线或标签 这在 R 中是否可能 这是用于制作上述绘图的代码 hist x breaks 50 xlab ma
  • 对python的LOAD_FAST/STORE_FAST感到困惑

    当我写一些代码时 我发现一个有趣的事情 def test l for i in range 10 def f pass print f l append f test import dis dis dis test 输出是
  • 如何从 pandas 邻接矩阵数据帧创建有向 networkx 图?

    我有一个以下形式的 pandas 数据框 df A B C D A 0 0 5 0 5 0 B 1 0 0 0 C 0 8 0 0 0 2 D 0 0 1 0 我正在尝试由此创建一个 networkx 图 我尝试过以下代码变体 A G ne
  • “cordova 平台添加 android”shasum 错误

    我正在完成设置和 HelloWorld 示例http cordova apache org docs en 3 5 0 guide cli index md html The 20Command Line 20Interface http
  • 当我导入 Xerces 库时无法构建应用程序(退出值 1)

    当我导入 Xerces 库时 我似乎无法构建我的应用程序 由于之前的问题 我已经在使用 multidex 因此我知道这一切都设置正确 我花了几天时间在网上查找并尝试各种版本的 Xerces 并对我的 build gradle 进行调整 但无
  • CSS open-quote 显示 1 个引号

    我使用以下 CSS 在段落前添加左引号 blockquote padding 22px quotes 201C 201D 2018 2019 font size 15px blockquote before color 111 conten
  • Postgres:整数范围的唯一约束

    给定两个整数 开始和结束 以及一个外键 我如何定义一个unique对区间 start end 和foreign key 的约束 鉴于我的表中有以下条目 start end foreign key 10 20 04ef8258 917c 46
  • Java中如何获取字符类型的类别名称?

    The Character getType int codePoint 返回一个整数 但我找不到方法 从中获取 unicode 类别名称 例如 Lu 或 Cn 我想要的是一种方法 例如Character getCategoryTypeNam
  • scala 中的构造函数(主/辅助/默认主)

    一个非常简单的练习凯霍斯特曼的 book Scala 适合不耐烦的人 一直让我困惑 是关于primary auxiliary and default primary构造函数 例如 5 10 考虑班级 class Employee val n
  • 不会采用父级
  • 我有一个 ul 与几个 li 其中的所有项目都在一行中 这 li li 有一个嵌套的 span and an img The img 所有项目的高度都相同 但是 span 项目包含可以跨越单行或两行的文本 取决于文本 我尝试过申请displ
  • ParseException:无效的会话令牌错误

    我做了一个简单的注册用户界面只是为了检查解析 但由于某种原因每次我尝试注册用户时都会出现此错误 这是代码 final ProgressDialog dlg new ProgressDialog this dlg setTitle Pleas
  • Java 中的内存映射集合

    我正在填满 JVM 堆空间 更改参数以为 JVM 提供更多堆空间 或更改代码中算法中的某些内容以不使用这么多空间是最推荐的两个选项 但是 如果这两个已经被尝试和应用 并且我仍然遇到内存不足的异常 我想看看其他选项是什么 我发现了这个例子 对
  • 使用 Keras (PIL) 和 TensorFlow 调整图像大小不一致?

    我对以下之间明显的不一致感到困扰 图像调整大小功能来自keras preprocessing 它们是 PIL 函数的包装器 TensorFlow 中的图像大小调整函数tf image 我正在使用 Keras 为计算机视觉任务训练深度学习模型