Keras 函数模型验证准确率高,但预测不正确

Posted

技术标签:

【中文标题】Keras 函数模型验证准确率高,但预测不正确【英文标题】:Keras Functional model giving high validation accuracy but incorrect prediction 【发布时间】:2020-02-02 08:31:38 【问题描述】:

我正在尝试使用 PASCAL VOC 2012 数据集上的“ImageNet”预训练权重对 VGG16 架构进行迁移学习。 PASCAL VOC 是一个包含 20 个类别的多标签图像数据集,因此我对内置的 VGG16 模型进行了如下修改:

def VGG16_modified():
    base_model = vgg16.VGG16(include_top=True,weights='imagenet',input_shape=(224,224,3))
    print(base_model.summary())
    x = base_model.get_layer('block5_pool').output
    x = (GlobalAveragePooling2D())(x)
    predictions = Dense(20,activation='sigmoid')(x)

    final_model = Model(input = base_model.input, output = predictions)
    print(final_model.summary())
    return final_model

而我的输入图像预处理是这样的:

img_val = []
for i in tqdm(range(dfval.shape[0])):
        img = image.load_img(train_images+y_val[0][i],target_size=(224,224))
        img = image.img_to_array(img)
        img_val.append(img)
x_val = np.array(img_val

我已经使用 pd.get_dummies 为 20 个类 [[0 0 0 0 1 0 0 0 0 1 0 .... ]] 转换了这样的分类标签,并且相应的标签的形状为 (number of image samples, 20)。输入图像的形状为(number of image samples, 224,224, 3)

当我对模型进行了几个 epoch 的训练时,我看到了非常好的验证准确度(大约 90%),但是当我使用相同的验证数据集来预测图像时,它为每个图像提供了相同的类输出。

我这样训练模型:

model = VGG16_modified()
model.summary()
model.compile(optimizer=Adam(),loss='binary_crossentropy',metrics = ['accuracy'])
model.fit(x_train, y_train, epochs=100, validation_data=(x_val, yval), batch_size=4)
model.save('CAMVGG16trainall.h5')
model.save_weights('CAMVGG16weightstrainall.h5')

后来我加载了模型并尝试预测相同验证数据集的标签。

model = load_model(model)
preds = model.predict(image)

但我为每张图片都得到了相同的输出。输出的形状为[[0 0 0 ......1 0 0 0...]] 我尝试了更多的时代,更少的时代,通过设置一些不可训练的层,通过设置所有层可训练,改变学习率,使用不同的优化器(SGD),不使用Imagenet权重和从头开始训练但没有他们给了我正确的结果。谁能告诉我哪里出错了。

【问题讨论】:

你如何定义准确度?我很好奇,因为它是多标签分类问题。我认为平均精度或召回率会更有意义。 我高度怀疑您的图像没有像训练或验证那样进行预处理。确保输入值在同一范围内,例如 (0,1) 您是否在训练图像上应用了任何增强技术? 我不认为 90% 的准确率是令人信服的。因为大多数值都是零。如果地面实况标签的平均数量为 3。那么即使所有预测为零,您仍然有 22/25=0.88 的准确度。 @Sree 尝试使用召回率或精度来监控训练。 【参考方案1】:

为了社区的利益,在此提及解决方案,因为有很多 cmets 知道解决方案。

这里的问题是模型被冻结了,即 PASCAL VOC 数据集上的 Layersnot Trained

预训练模型的权重应该被冻结,而在我们的数据集上训练的模型层的权重不应该被冻结。

问题已通过设置layer.trainable = True 解决。通过下面的截图可以更好地理解这一点。

注意:图片取自 Aurelien Geron 的机器学习和深度学习一书。

【讨论】:

以上是关于Keras 函数模型验证准确率高,但预测不正确的主要内容,如果未能解决你的问题,请参考以下文章

尽管准确率超过 99%,但随机森林模型产生了不正确的预测

使用 Keras 构建了一个模型,该模型报告了良好的准确性,但随后无法进行预测

Tensorflow Keras - 训练时准确率高,预测时准确率低

预测取决于 Keras 中的批量大小

Keras 图像分类 - 验证数据集的预测准确性与 val_acc 不匹配

Keras 是如何计算准确率的?