【问题标题】:Keras wrong accuracy using model.predictKeras 使用 model.predict 的准确性错误
【发布时间】:2020-07-15 10:08:30
【问题描述】:

我正在将此代码用于 CNN

train_batches = ImageDataGenerator().flow_from_directory('dice_sklearn/train', target_size=(IMG_WIDTH, IMG_HEIGHT),
                                        classes=['1', '2', '3', '4', '5', '6'],
                                        batch_size=cv_opt['batch'],
                                        color_mode="grayscale")

test_batches = ImageDataGenerator().flow_from_directory('dice_sklearn/test', target_size=(IMG_WIDTH, IMG_HEIGHT),
                                       class_mode='categorical',
                                       batch_size=cv_opt['batch'],
                                       shuffle=False)
train_num = len(train_batches)
test_num = len(test_batches)

model = Sequential([
    Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(IMG_WIDTH, IMG_HEIGHT, 1)),
    Conv2D(32, (3, 3), activation='relu'),
    MaxPooling2D(pool_size=(2, 2)),
    Dropout(0.30),

    Conv2D(64, (3, 3), padding='same', activation='relu'),
    Conv2D(64, (3, 3), activation='relu'),
    MaxPooling2D(pool_size=(2, 2)),
    Dropout(0.30),

    Conv2D(64, (3, 3), padding='same', activation='relu'),
    Conv2D(64, (3, 3), activation='relu'),
    MaxPooling2D(pool_size=(2, 2)),
    Dropout(0.30),

    Flatten(),
    Dense(512, activation='relu'),
    Dropout(0.5),
    Dense(6, activation='softmax'),

])
print(model.summary())

model.compile(Adam(lr=cv_opt['lr']), loss='categorical_crossentropy', metrics=['accuracy'])
history = model.fit(train_batches, steps_per_epoch=train_num,
                              epochs=cv_opt['epoch'], verbose=2)

model.save('cnn-keras.h5')

test_batches.reset()
prediction = model.predict(test_batches, steps=test_num, verbose=1)
predicted_class = np.argmax(prediction, axis=1)
classes = test_batches.classes[test_batches.index_array]
accuracy = (predicted_class == classes).mean()
print("Final accuracy:", accuracy * 100)

在哪里

  • cv_opt['batch'] 设置为 50
  • cv_opt['lr'] 设置为 0.0003
  • cv_opt['epoch'] 设置为 50

最后一行(last epoch)的训练阶段(使用model.fit)的输出返回:

192/192 [==============================] - 98s 510ms/step - loss: 0.0514 - accuracy: 0.9818 - val_loss: 0.0369 - val_accuracy: 0.9833

但是当我运行这部分代码时:

test_batches.reset()
prediction = model.predict(test_batches, steps=test_num, verbose=1)
predicted_class = np.argmax(prediction, axis=1)
classes = test_batches.classes[test_batches.index_array]
accuracy = (predicted_class == classes).mean()
print("Final accuracy:", accuracy * 100)

我的准确度得分非常低:(0.16)。 但是,如果绘制学习曲线,我可以看到测试/验证曲线(如果在测试或参数调整中)都达到接近 90% 的准确度。

我是否以错误的方式使用了 model.predict?

【问题讨论】:

  • 不,问题是使用 generator.classes 是不可靠的,因为生成器有一个状态并且可能与 generator.classes 中的顺序不匹配,您应该迭代生成器以获取输入和目标为了计算任何指标,model.evaluate 是如何工作的。
  • 很久以前我遇到了一个类似且非常奇怪的错误,您可以尝试从 model.fit 中删除验证拆分然后尝试验证吗?

标签: machine-learning keras deep-learning neural-network conv-neural-network


【解决方案1】:

您的模型没有过度拟合。为了解决您的问题,根本不必执行步骤 1 和 2。事实上,这是更错误的,因为作者指出在过度拟合的情况下你需要添加更多的层,强烈建议不要这样做:当一个人有一个过度拟合的模型时,模型需要变得更简单,而不是更复杂。

您的问题的解决方案在于@Dr.Snoopy 的回答:类的顺序不匹配。

我的建议是手动迭代整个测试集,获取基本事实,获取预测(确保对测试集图像应用与训练集中相同的图像预处理),然后再将它们提供给您的型号。

然后,计算您的指标。这将解决您的问题。

例如,您可以使用以下想法:

    correctly_predicted = 0
    for image in os.scandir(path_to_my_test_directory):
        image_path = image.path
        image = cv2.imread(image_path)
        image = apply_the_same_preprocessing_like_in_training(image)
        #transform from (H,W,3) to (1,H,W,3) because TF + Keras predict only on batches
        image = np.expand_dims(image,axis=0)
        prediction_label = np.argmax(model.predict(image))
        if prediction_label == ground_truth_label:
              correctly_predicted+=1

【讨论】:

  • 添加更多层不会使您的模型复杂,但会使您的模型更深。可能的问题可能是梯度消失。即使你要攻击我也要使用正确的术语
  • 抱歉,但是让模型更深确实使它更复杂。浅/不复杂的反面确实是深而复杂。同时,我不认为在这种情况下提出支持真理的论点意味着攻击你。确实,您的建议具有误导性,因为在网络中堆叠更多层绝对不能解决过度拟合。我什至没有否决您的评论,但您可以看到其他人对此的反应。请理解这不是竞争,而是应该带来真相/解决方案的健康对话。
  • 此外,从 Adam 切换到 AdaDelta 也没有任何帮助。
猜你喜欢
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
相关资源
最近更新 更多