反复核对了代码,数据集,然后重新执行了多次仍然只有90%的精度。 使用goolge搜索using-a-pretrained-convnet,可以找到https://github.com/fchollet/deep-learning-with-python-notebooks/issues/21。 阅读其中的讨论,最终可以在https://forums.manning.com/posts/list/42880.page 中找到较为完整的解释。 When I run the code given in the book, my validation accuracy plateaus around 0.90, exactly like the original poster described. I think the problem is that in the book’s code, the images are being read in from disk as numpy arrays of float32 values in the range [0.0, 1.0], due to the keyword argument [tt]rescale=1./255[/tt] in the ImageDataGenerator constructors. These images are then automatically fed directly to the VGG16 convolutional base when the model’s [tt]fit_generator[/tt] method is called.
However, the original VGG16 network was trained on images that were preprocessed by zero-centering each color channel with respect to the ImageNet database. In Keras, there is a function available (in keras.applications.vgg16) that does this transformation, called [tt]preprocess_input[/tt]. In fact, if you test the full pretrained VGG16 network by itself, you will find that in order to get accurate classification results, you must call [tt]preprocess_input[/tt] first before calling the [tt]predict[/tt] method. Furthermore, [tt]preprocess_input[/tt] must be called on images of float32 values in the range [0., 255.], not [0., 1.].
So to summarize, there are two problems with the book’s example: first, it uses images with values in the range [0., 1.], and second, it does not call [tt]preprocess_input[/tt] before feeding the images to the VGG16 base. 问题的本质是本书作者在这一节犯了一个低级错误,在使用VGG16这个预训练模型时,再次训练时送入的数据没有按照VGG16模型的要求进行预处理。同时,作者使用的keras老版本有一个bug,conv_base.trainable = False这句没有生效,所以作者实际上是对整个VGG16模型做了再次完整的训练,网络自动适配了新的值域,精度仍然达到了96%。