作为 Keras lambda 层的图像预处理与单独预处理

Image preprocessing as a Keras lambda layer vs preprocessing on its own

我正在尝试在通过网络传播图像之前应用从 Keras 中的 resnet50 模块导入的预处理。由于在尝试将其应用于生成器对象时出现错误,因此我将其作为 lambda 层添加到网络中。

但是由于模型比我之前训练的模型差,当我分别对每个图像应用预处理时,我比较了两种方法的结果,它们看起来非常不同,虽然我看不出有什么不同应用操作。

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

model = keras.models.Sequential()
model.add(keras.layers.Lambda(preprocess_input, name='preprocessing', input_shape=(224, 224, 3)))

file = '/path/to/an/image.jpeg'
x = np.array(image.img_to_array(image.load_img(file, target_size=(224, 224))))

preprocessed_x = preprocess_input(x)
predicted_x = model.predict(x.reshape(1,224,224,3)).reshape(224,224,3)

结果(左:直接使用预处理函数;右:预处理为lambda层。

我认为这可能是keras代码中的错误,但我发现preprocess_input(x)正在修改x

参见:

x = np.array(image.img_to_array(image.load_img(file, target_size=(224, 224))))
print("x before preprocess - max: " + str(x.max()) + " / min: " + str(x.min()))
preprocessed_x = preprocess_input(x)
print("x after preprocess - max: " + str(x.max()) + " / min: " + str(x.min()))

结果:

x before preprocess - max: 255.0 / min: 0.0
x after preprocess - max: 151.061 / min: -123.68

一开始我当然不会想到这种行为,但仔细想想,它节省了内存(这在神经网络中很有价值...)。

如果您 运行 使用 numpy 版本之前的模型版本进行测试,则不会出现此问题(因为在张量中工作的模型不会就地修改 x)。

在模型内部或外部进行预处理?

我认为最好在生成器中的模型外预处理图像。 这样你在训练和预测时可以更快地执行。