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

时间:2019-02-15 03:12:29

标签: python tensorflow keras

背景

我发现很多代码示例,其中人们使用rescale=1./255或使用preprocessing_function对其图像数据进行预处理以将其设置为相应模型的preprocess_input他们正在ImageDataGenerator中使用。首先,我认为使用rescale=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, ...

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

from keras.applications.vgg19 import preprocess_input
ImageDataGenerator(preprocessing_function=preprocess_input, ...

我认为使用要训练的各个模型的各个preprocess_input总是比使用rescale = 1. / 255方法更好,因为它会100%反映在训练预训练模型过程中使用的预处理。

问题

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

3 个答案:

答案 0 :(得分:1)

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.

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

enter image description here

相当于做

1./255

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

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

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

如果您有兴趣真正了解所有这些背后的原因以及进行标准化的重要性,强烈建议您使用Andrew Ng course on machine learning

答案 1 :(得分:1)

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

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

然后,我尝试将resnet50include_top=False一起使用,从imagenet冻结权重,一层GlobalAveragePooling2D层,最后一层密集的S型层。我用亚当在 kaggle dogs-vs-cats 数据集的2000张图像上对它进行了训练(我使用了1000张图像作为验证)。使用重新缩放,它在5个纪元后并不能适应任何情况,它总是可以预测第一堂课(尽管奇怪的是,培训的准确度是 97%,但是当我运行evaluate_generator`` on the training images, the accuracy is **50%**). But with preprocess_input {{1} } preprocess_input`,验证精度为 95%

我尝试过使用, 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 or进行相同的操作,但重新缩放确实可以适应,但是使用vgg16分别达到了 87% 97% ,并且 95%

然后,我从头开始训练了一个小型的转换网络,历时10个纪元,没有任何内容,也没有使用preprocess_input resnet50,虽然完全不适合,但是通过重新缩放,我得到了 70%< / strong>验证准确性。

答案 2 :(得分:1)

如果您以仅利用网络结构但重新训练整个网络的方式使用转移学习(可能从杠杆加权开始),则可以选择设置自己的预处理策略。这意味着您可以通过扩展255.0进行扩展,或者使用preprocess_input甚至是preprocess的自定义实现。

如果在不学习整个网络的情况下使用传输学习,而是用一些完全连接的密集层代替最后一层,则强烈建议使用与您正在训练的网络关联的preprocess_input。这是因为与您未训练的图层关联的权重已习惯于特定的预处理步骤。例如,如果您查看InceptionResNetV2的preprocess_input并遵循_preprocess_numpy_input的代码路径,则仅在mode为“ tf”或“ pytorch”时,它不会在每种情况下都对图像进行规范化。因此,如果您训练了InceptionResNetV2并通过将其除以0归一化了图像,则可能无法按照您的预期训练分类器。