首页 > 解决方案 > keras 模型具有良好的准确性和 val acc,但无法预测,甚至无法预测训练数据

问题描述

我正在尝试建立一个计算机视觉来对寺庙的图像进行分类,其中包含 16 个类和每类大约 60-70 个图像(很少有只有 40 个数据的图像)。

这是我的数据传播的图:

绘制每个类中的数据量

我正在使用 VGG19 架构,并稍微修改了最后一层。

def get_base_model():
    model = VGG19(input_shape=(224, 224, 3), weights='imagenet', include_top=False)
    model.layers.pop()
    model.layers.pop()
    model.layers.pop()
    model.outputs = [model.layers[-1].output]
    model.layers[-2].outbound_nodes= []
    x = Conv2D(256, kernel_size=(2,2),strides=2)(model.output)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)    
    x = Conv2D(128, kernel_size=(2,2),strides=1)(x)
    x = BatchNormalization()(x)
    x = Dropout(0.3)(x)
    x = Activation('relu')(x)
    x = Flatten()(x)
    x = Dense(len(class_names), activation='softmax')(x)
    model=Model(model.input,x)

    for layer in model.layers[:22]:
        layer.trainable = False

    return model
optimizer = SGD(lr=0.0001, momentum=0.9)
model.compile(optimizer=optimizer,
              loss='categorical_crossentropy',
              metrics=['accuracy'])

model.fit(
    train_data_gen,
    steps_per_epoch=int(np.ceil(train_data_gen.n/batch_size)),
    validation_data=val_data_gen,
    epochs=epochs,
    validation_steps=int(np.ceil(val_data_gen.n/batch_size)),
    shuffle=True,
    callbacks=[callback]
)

我使用从目录流出的图像增强

image_gen_train = ImageDataGenerator(
                    rescale=1./255,
                    #preprocessing_function=preprocess_input,
                    width_shift_range=0.02,
                    height_shift_range=0.02,
                    horizontal_flip=False,
                    fill_mode='nearest'
                    )

train_data_gen = image_gen_train.flow_from_directory(
                                                batch_size=batch_size,
                                                directory=train_dir,
                                                shuffle=True,
                                                target_size=(IMG_SHAPE,IMG_SHAPE),
                                                class_mode='categorical',
                                                )

image_gen_val = ImageDataGenerator(
                                    rescale=1./255
                                    #preprocessing_function=preprocess_input
                                    )

val_data_gen = image_gen_val.flow_from_directory(batch_size=batch_size,
                                                 directory=test_dir,
                                                 target_size=(IMG_SHAPE, IMG_SHAPE),
                                                 class_mode='categorical',
                                                 shuffle=False)

(请原谅我非常尴尬的缩进)看到我评论了 preprocessing_function 参数,因为我尝试过使用和不使用它。

这是我尝试预测火车文件夹中所有数据的方法

folder = 'candi_borobudur'
imgs = [img_to_array(load_img(f'images/train/{folder}/{img}').resize((224, 224))) for img in os.listdir(f'images/train/{folder}')]
class_names = ['candi_borobudur', 'candi_brahu', 'candi_banyunibo', 'candi_cangkuang', 'candi_dieng', 'candi_sambisari', 'candi_kalasan', 'candi_pawon', 'candi_padas', 'candi_prambanan', 'candi_jago', 'candi_jabung', 'candi_muara_takus', 'candi_mendut', 'candi_sewu', 'candi_sari_']
print(len(imgs))
for img in imgs:
    #img = preprocess_input(img)
    img = img/255.
    img = np.expand_dims(img, axis=0)
    result = model.predict(img)
    print(result)
    print(np.argmax(result[0]))
    print(class_names[np.argmax(result[0], axis=-1)])

该模型在大约 40 个 epoch 后获得了相当大的 90% 验证准确率,但该模型甚至无法准确预测训练数据。当我运行上面的代码时,它会预测其他类。

我做过的事情:

我没有做过的事情:

标签: pythontensorflowkerasdeep-learning

解决方案


通过阅读以上所有尝试,我认为您的网络很好。您的load_img方法很有可能是基于 PIL 的。这与 OpenCV 不同的是,每个像素值都将在 [0, 1] 的范围内。您的代码要求图像在 [0, 255] 范围内且为浮点类型。

您能否在这一行中提供 load_img 和 img_to_array 的详细信息。或者打印img_to_array(load_imgload_img返回的图像数组

imgs = [img_to_array(load_img(f'images/train/{folder}/{img}').resize((224, 224))) for img in os.listdir(f'images/train/{folder}')]

推荐阅读