在Keras中反转VGG的图像预处理以返回原始图像

GRS*_*GRS 5 python keras tensorflow

我正在使用 keras 应用程序中的 VGG19 模型。我原以为图像会被缩放,[-1, 1]但相反,它似乎preprocess_input正在做其他事情。

为了预处理输入,我使用以下两行首先加载图像,然后缩放它:

from keras.preprocessing import image
from keras.applications.vgg19 import preprocess_input

img = image.load_img("./img.jpg", target_size=(256, 256))
img = preprocess_input(np.array(img))

print(img)
>>> array([[[151.061  , 138.22101, 131.32   ],
    ... ]]]
Run Code Online (Sandbox Code Playgroud)

输出似乎在 [0,255] 区间内,但是,原始 255 被映射到 151 左右的值(可能居中)。VGG实际需要的输入是什么?通过查看源代码(对于 ),我认为它应该在 [-1,1] 中mode='tf'。它是否非常灵活,我可以使用我想要的任何类型的缩放?(我使用 VGG 来提取中级特征 - Conv4 块)。

当查看源代码时,preprocess_input我看到:

...
    if mode == 'tf':
        x /= 127.5
        x -= 1.
        return x
...
Run Code Online (Sandbox Code Playgroud)

这表明对于张量流后端(keras 使用的),它应该缩放到 [-1,1]。

我需要做的是创建一个函数restore_original_image_from_array(),它将获取img并重建我输入的原始图像。问题是我不确定 VGG19 的缩放是如何发生的。

简而言之,我想做:

img = image.load_img("./img.jpg", target_size=(256, 256))
scaled_img = preprocess_input(np.array(img))
restore_original_image_from_array(scaled_img) == np.array(img)
>>> True
Run Code Online (Sandbox Code Playgroud)

Gab*_*gon 4

函数的“模式”preprocess_input取决于预训练网络权重的训练框架。Keras 中的 VGG19 网络使用 caffe 中原始 VGG19 模型的权重,因此,中的参数preprocess_input应为默认值 ( mode='caffe')。看到这个问题:Keras VGG16 preprocess_input models

为了您的目的,请使用preprocess_input中找到的函数keras.applications.vgg19并从那里对其进行逆向工程。

原始预处理位于: https: //github.com/keras-team/keras-applications/blob/master/keras_applications/imagenet_utils.py#L21

这涉及 1) 将图像从 RGB 转换为 BGR 2) 从图像中减去数据集平均值

下面是恢复原始图像的代码:

def restore_original_image_from_array(x, data_format='channels_first'):
    mean = [103.939, 116.779, 123.68]

    # Zero-center by mean pixel
    if data_format == 'channels_first':
        if x.ndim == 3:
            x[0, :, :] += mean[0]
            x[1, :, :] += mean[1]
            x[2, :, :] += mean[2]
        else:
            x[:, 0, :, :] += mean[0]
            x[:, 1, :, :] += mean[1]
            x[:, 2, :, :] += mean[2]
    else:
        x[..., 0] += mean[0]
        x[..., 1] += mean[1]
        x[..., 2] += mean[2]

    if data_format == 'channels_first':
        # 'BGR'->'RGB'
        if x.ndim == 3:
            x = x[::-1, ...]
        else:
            x = x[:, ::-1, ...]
    else:
        # 'BGR'->'RGB'
        x = x[..., ::-1]

    return x
Run Code Online (Sandbox Code Playgroud)