Keras功能模型可提供较高的验证准确性,但预测不正确

时间:2019-10-04 02:03:18

标签: python tensorflow keras deep-learning conv-neural-network

我正在尝试使用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)

当我对模型进行几个时期的训练时,我看到非常好的验证准确性(大约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权重和从头开始训练,但没有他们给我正确的结果。谁能告诉我我哪里出问题了。

1 个答案:

答案 0 :(得分:1)

此处提及该决议是为了社区的利益,因为有很多评论都知道解决方案。

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

应该冻结经过预训练的模型的权重,而不应对在我们的数据集中训练的模型各层的权重进行冻结。

问题可以通过设置layer.trainable = True来解决。下面的屏幕快照可以更好地理解这一点。

enter image description here

注意:图片摘自Aurelien Geron的《关于机器学习和深度学习的书》。