Keras:rescale=1./255 vs preprocessing_function=preprocess_input - 使用哪一个?

Aar*_*nDT 8 python keras tensorflow

背景

我发现了很多代码示例,其中人们使用 usingrescale=1./255或正在使用来预处理他们的图像数据,他们将其preprocessing_function设置preprocess_input为他们在 ImageDataGenerator 中使用的相应模型的 。首先,我认为 usingrescale=1./255仅在处理预训练的 vgg16 模型时有效,但我一直看到它与预训练的 resetnet50、inception 等一起使用的示例。

虽然 keras-blog ( https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html ) 使用这种方法......

ImageDataGenerator(rescale=1./255, ...
Run Code Online (Sandbox Code Playgroud)

... Keras 文档 ( https://keras.io/applications/ ) 使用这种方法:

from keras.applications.vgg19 import preprocess_input
ImageDataGenerator(preprocessing_function=preprocess_input, ...
Run Code Online (Sandbox Code Playgroud)

我认为使用我想要训练的相应模型的相应 preprocess_input 总是优于使用 rescale=1./255 方法,因为它将 100% 反映在训练预训练模型期间使用的预处理。

在预处理图像以进行迁移学习时,我需要澄清何时使用我想要训练的各个模型的rescale=1./255vs keras 内置preprocess_input。这是否仅在使用预训练模型(即加载权重与从头开始训练)时有所不同?

小智 9

我有类似的问题,在运行下面的小实验后,我认为您preprocess_input在使用预训练模型时需要始终使用,而在从头开始训练时使用 rescale。

显然,当您直接使用预先训练的模型进行推理时,您必须使用preprocess_input:例如我尝试resnet50kaggle dog-vs-cats数据集上使用,rescale=1./255它返回索引 111(nematode, nematode worm, roundworm)作为所有图像最可能的类,而使用preprocess_input它主要返回与预期的狗和猫相对应的索引。

然后我试着用resnet50include_top=False,从imagenet,一个冰冻的权重GlobalAveragePooling2D层和一个最终的致密层乙状结肠。我与 Adam 在kaggle dog-vs-cats数据集的2000 张图像上对其进行了训练(并且我使用了 1000 张图像作为验证)。使用重新缩放它在 5 个时期后无法适应任何东西,它总是预测第一类(虽然奇怪的是训练准确度是97%,但是当我运行evaluate_generator`` on the training images, the accuracy is **50%**). But withpreprocess_input , it achieves **98%** accuracy on the validation set. Also note that you do not really need the images to be of the same dimensions as the trained models, for example if I use 150 instead of 224, I still get a **97.5%** accuracy. Without any rescaling orpreprocess_input` 时,我得到了95% 的验证准确度。

我试着用同样的事情vgg16,与重新调整它并设法适应,但87% VS 97%使用preprocess_input,并且95%没有任何东西。

然后我从头开始用 10 个 epoch 训练了一个小型 conv 网络,没有任何东西或使用resnet50 preprocess_input,它根本不适合,但是通过重新缩放我得到了70% 的验证准确度。


Jua*_*ano 4

First I thought using rescale=1./255 only works when dealing with a pretrained vgg16 model, but I keep seeing examples where it is being used with pre-trained resetnet50, inception etc. as well.

这样做的原因是因为您需要对输入进行标准化。通常最小-最大归一化的公式是

在此输入图像描述

这相当于做

1./255

由于图像的像素值将在 0 和 1 之间

对输入进行归一化的原因与数值稳定性和收敛性有关(从技术上讲,您不需要它,但有了它,神经网络就有更高的收敛机会,并且梯度下降/亚当算法更有可能稳定)

根据Does this only make a difference when using pretrained-models i.e. with loaded weights vs training from scratch?“否”,它不仅仅与预训练模型相关,它是在机器学习中使用某些算法时的一种常用技术(神经网络就是其中之一)。

如果您有兴趣真正了解这一切背后发生的事情以及为什么标准化如此重要,我强烈建议您参加Andrew Ng 的机器学习课程

  • 所以你的意思是使用 1./255 与使用手头模型的相应 preprocess_input 之间基本上没有区别?例如,查看 inception_resnet_v2 实现(https://github.com/fchollet/deep-learning-models/blob/master/inception_resnet_v2.py),标准化看起来与 1./255 不同 - 必须有一个原因或不?请记住,我也在考虑想要使用迁移学习和微调的情况。我认为当使用与训练期间相同的归一化进行微调时,预训练权重效果最好 (2认同)
  • 我非常感谢您的努力,但我的问题仍未得到解答。我只想知道为什么您会选择 1./255 与 preprocessing_input 变体。我确实知道您需要使用标准化,并且我知道您可以使用任何标准化来使其“起作用”。但这是否意味着您应该这样做?为了在微调期间获得最佳结果,必须有一种首选方法(重新缩放与 preprocess_input)。如果两个归一化过程会产生完全相同的结果,那么 keras 中不同模型的所有 preprocess_input 函数将是多余的。 (2认同)