【问题标题】:keras classifier wrong evaluation while learning is greatkeras 分类器错误评估而学习很棒
【发布时间】:2020-09-24 13:52:00
【问题描述】:

有小数据集

找到属于 2 个类别的 1836 张图片。 找到属于 2 个类别的 986 张图片。

模型的标准架构


image_generator = ImageDataGenerator(
        rescale=1./255,
        validation_split=0.35
    )
    train_data_gen = image_generator.flow_from_directory(
        directory=directory,
        target_size=(IMG_SHAPE, IMG_SHAPE),
        subset='training',
    )
    val_data_gen = image_generator.flow_from_directory(
        directory=directory,
        target_size=(IMG_SHAPE, IMG_SHAPE),
        subset='validation',
    )

---

model = tf.keras.models.Sequential([
                tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_SHAPE, IMG_SHAPE, 3)),
                tf.keras.layers.MaxPooling2D(2, 2),

                tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
                tf.keras.layers.MaxPooling2D(2, 2),

                tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
                tf.keras.layers.MaxPooling2D(2, 2),

                tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
                tf.keras.layers.MaxPooling2D(2, 2),

                tf.keras.layers.Flatten(),
                tf.keras.layers.Dense(512, activation='relu'),
                tf.keras.layers.Dense(2, activation='softmax'),
            ])

            model.compile(
                optimizer='adam',
                loss='categorical_crossentropy',
                metrics=['accuracy']
            )

            BATCH_SIZE = 128
            EPOCHS = 7
           
            total_train, total_val = train_data_gen.samples, val_data_gen.samples

            steps_per_epoch = int(np.ceil(total_train / float(BATCH_SIZE)))
            validation_freq = int(np.ceil(total_val / float(BATCH_SIZE)))

            history = model.fit(
                train_data_gen,
                epochs=EPOCHS,
                steps_per_epoch=steps_per_epoch,
                validation_data=val_data_gen,
                validation_freq=validation_freq
            )

获得完美的指标

Epoch 1/7
15/15 [==============================] - 66s 4s/step - loss: 1.0809 - accuracy: 0.4917
Epoch 2/7
15/15 [==============================] - 56s 4s/step - loss: 0.3475 - accuracy: 0.8729
Epoch 3/7
15/15 [==============================] - 60s 4s/step - loss: 0.1113 - accuracy: 0.9583
Epoch 4/7
15/15 [==============================] - 58s 4s/step - loss: 0.1987 - accuracy: 0.9109
Epoch 5/7
15/15 [==============================] - 59s 4s/step - loss: 0.1127 - accuracy: 0.9438
Epoch 6/7
15/15 [==============================] - 60s 4s/step - loss: 0.0429 - accuracy: 0.9854
Epoch 7/7
15/15 [==============================] - 49s 3s/step - loss: 0.0542 - accuracy: 0.9812

但是在我评估它之后,我完全偏向于一流的结果

它仅在我运行 1 个 epoch 时才有效,但缺乏准确性

评估代码

def make_pred(model, labled_dataset, IMG_SHAPE, img_path) -> LabelName:
    def make_image(img_path):
        # img = img_path.resize((IMG_SHAPE, IMG_SHAPE), Image.ANTIALIAS)
        img = image.load_img(img_path, target_size=(IMG_SHAPE, IMG_SHAPE))
        img = image.img_to_array(img)
        return np.expand_dims(img, axis=0)

    pred_id: List[List] = np.argmax(model.predict(make_image(img_path)), axis=1)
    all_labels = list(labled_dataset.class_indices.keys())
    return all_labels[int(pred_id)]

这有什么问题?

我应该在评估之前缩小源图像的大小吗?

【问题讨论】:

  • 您没有应用您在 make_pred 代码中告诉生成器执行的 1/255 重新缩放
  • @Dr.Snoopy 申请是什么意思? -- 哦,你的意思是我也应该重新调整 eval 图像,好的 - 这就是我有 def test_data_prep 的原因 - 我很久以前写过这段代码,但已经忘记了))
  • 您的模型是在标准化图像上训练的,您没有在 make_image 代码中对图像进行标准化,只需将像素值除以 255,如果您不这样做,模型将产生不正确的预测
  • 但为什么它在 1 个 epoch 上运行良好 90%?
  • 请显示 labeld_dataset 的代码。您也使用 image.load_img 请显示图像的导入语句。是PIL的吗?我的猜测是你没有调整你想要预测的图像的大小。

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

我相信你需要做两件事。一种是调整您希望预测的图像的大小,然后像对训练图像所做的那样重新调整图像的大小。我还建议您设置 validation_freq=1 以便您可以设置验证损失和准确性的趋势。这使您可以查看模型相对于过度拟合等的表现。如果训练损失继续下降,但在以后的时期您的验证损失开始增加,您可以检测模型是否过度拟合。如果您看到过度拟合,请在密集的 512 节点密集层之后添加一个 Dropout 层。文档是here. 预测准确度应该接近最后一个时期的验证准确度。我还建议您考虑使用 keras 回调 ModelCheckpoint。文档是here. 设置它以监控验证损失并保存具有最低验证损失的模型。然后加载保存的模型进行预测。最后,我发现使用可调整的学习率是有效的。 keras 回调 ReduceLROnPlateau 使这很容易做到。文档是 here. 设置它以监控验证损失。如果在(参数耐心)耐心的 epoch 数之后验证损失未能减少,回调将自动将学习率降低一个因子(参数因子)。我使用因子=.5 和耐心=1。这允许您最初使用较大的学习率,并根据需要降低学习率,这样收敛速度会更快。您的 val_data_gen 中还有一件事设置 shuffle=False,因此每次都以相同的顺序处理验证图像。

【讨论】:

  • 如果 val_dataset 太小,学习过程会在 epoch 结束时卡住,所以这就是我增加拆分量并降低 validation_freq 的原因
【解决方案2】:
  • 问题出在validation_freq 中,应该是 validation_steps 之后我们终于得到了val_accuracy,所以 培训开始以适当的方式验证

  • 除此之外,IMG_SHAPEImageDataGenerator 和 模型内input_shape=(IMG_SHAPE, IMG_SHAPE, 3)),

  • 使用 PIL 进行预测也可能有所帮助,它给出的结果略有不同 来自keras.preprocessing.image结果

def make_pred_PIL(model, labled_dataset, IMG_SHAPE, img_path) -> LabelName:
    img = cv2.imread(img_path)
    img = cv2.resize(img, (IMG_SHAPE, IMG_SHAPE))
    img = np.array(img, dtype=np.float32)
    img = np.reshape(img, (-1, IMG_SHAPE, IMG_SHAPE, 3))

    pred_id: List[List] = np.argmax(model.predict(img), axis=1)
    all_labels = list(labled_dataset.class_indices.keys())
    return all_labels[int(pred_id)]

【讨论】:

    猜你喜欢
    • 2013-05-08
    • 2020-02-08
    • 1970-01-01
    • 2019-02-28
    • 2019-10-24
    • 2016-10-13
    • 2017-03-01
    • 2021-10-27
    • 2020-09-18
    相关资源
    最近更新 更多