【问题标题】:Different results on multiple evaluating on the GPU and model loadingGPU和模型加载的多次评估结果不同
【发布时间】:2017-09-01 09:15:52
【问题描述】:

我刚刚第一次使用ModelCheckpoint 函数来保存最佳模型(best_model = True)并想测试它的性能。保存模型时,它说val_acc 在保存之前为 83.3%。我加载了模型并在validation_generator 上使用了evaluate_generator,但val_acc 的结果是0.639。我感到困惑并再次使用它并得到 0.654,然后是 0.647、0.744 等等。我在我的 PC 上测试了相同的配置(没有 GPU),它始终显示相同的结果(有时可能是小的舍入误差)

  1. 为什么不同 evaluate_generator 执行之间的结果仅在 GPU 上有所不同?
  2. 为什么模型 val_acc 与报告的不同?

我正在使用 Keras 的 Tensorflows 实现。

model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])
checkpointer = ModelCheckpoint(filepath='/tmp/weights.hdf5', monitor = "val_acc", verbose=1, save_best_only=True)
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
    rescale = 1./ 255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size = (img_height, img_width),
    batch_size = batch_size)
validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size = (img_height, img_width),
    batch_size = batch_size)
# fine-tune the model
model.fit_generator(
    train_generator,
    steps_per_epoch = math.ceil(train_samples/batch_size),
    epochs=100,
    workers = 120,
    validation_data=validation_generator,
    validation_steps=math.ceil(val_samples/batch_size),
    callbacks=[checkpointer])
model.load_weights(filepath='/tmp/weights.hdf5')
model.predict_generator(validation_generator, steps = math.ceil(val_samples/batch_size) )
temp_model = load_model('/tmp/weights.hdf5')
temp_model.evaluate_generator(validation_generator, steps = math.ceil(val_samples/batch_size), workers = 120)
>>> [2.1996076788221086, 0.17857142857142858]
temp_model.evaluate_generator(validation_generator, steps = math.ceil(val_samples/batch_size), workers = 120)
>>> [2.2661823204585483, 0.25]

【问题讨论】:

  • 您的生成器是否每次都返回相同的验证集?它如何选择样本有随机性吗?
  • 在代码中,我使用内置的 flow_from_directory。 train 和 test 这两个文件夹是分开的。我认为它使用一切=>没有随机性。 train_data_dir = '/data/datasets/NAME/train' validation_data_dir = '/data/datasets/NAME/test'
  • val_samples是否等于validation_data_dir下的图片文件总数?
  • 这实际上是我犯的一个错误,但即使在一切正常的 train_generator 中,错误仍然存​​在。
  • 改正后错误依旧

标签: python tensorflow neural-network keras tensorflow-gpu


【解决方案1】:

这是因为您只保存模型权重。这意味着您没有保存优化器状态,​​这解释了重新加载模型时的准确性差异。如果您在创建ModelCheckpoint 时添加save_weights_only=False,问题将得到解决:

如果您重新加载模型,请使用Kerasload_model 函数。否则,您仍然只会加载重量。

checkpointer = ModelCheckpoint(filepath='/tmp/full_model.hdf5', monitor = "val_acc", verbose=1, save_best_only=True, save_weights_only=False)

#reload model
from keras.models import load_model
model = load_model('/tmp/full_model.hdf5')

【讨论】:

  • 感谢您的回答。我现在使用相同的模型变量,并且只使用 load_weights 导入权重。评估之间的结果仍然不同,并且与据报道保存的结果大不相同。
  • 不仅要导入权重,还需要导入优化器状态。检查我的更新答案
  • 谢谢!解释为什么优化器状态很重要,它不仅仅是一种……嗯……优化的方法吗?我现在尝试一下,希望能得到同样的结果——由于集合相对较小,准确率波动很大——>它达到 79.1,然后下降到 0.667,我必须进一步降低学习率。
  • 很遗憾,没用。 >>> checkpointer = ModelCheckpoint(filepath='/tmp/weights4.hdf5', monitor = "val_acc", verbose=1, ... save_best_only=True, save_weights_only=False) >>> model.load_weights("/tmp/ weights4.hdf5") 评估1 => 0.75评估2 => 0.625
  • 不应该这样。您的模型在保存最佳模型后是否继续训练?例如,最好的模型在第 90 个 epoch,但您的模型一直训练到第 100 个 epoch。在这种情况下,evaluate1 在第 100 个 epoch 给出模型精度,在第 90 个 epoch 给出评估 2。
【解决方案2】:

好的,问题如下 - batch_size !我花了很长时间才弄清楚这一点 -

steps = math.ceil(val_samples/batch_size)

由于 batch_size 不是 number_of_samples 的除数,因此产生了问题。设置workers 变量也发生了一些小错误——使用GPU 实际使用它是没有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2021-09-11
    相关资源
    最近更新 更多