【问题标题】:Extremely slow training speed with Keras when using steps_per_epoch argument使用 steps_per_epoch 参数时,Keras 的训练速度极慢
【发布时间】:2019-07-05 04:51:56
【问题描述】:

当我在 model.fit(..) 方法中指定 steps_per_epoch 参数时,我注意到训练模型速度大幅下降。当我将 steps_per_epoch 指定为 None(或不使用它)时,epoch 的 ETA 是连续 2 秒:

9120/60000 [===>.......................] - ETA:2s - 损失:0.7055 - acc:0.7535

当我添加 steps_per_epoch 参数时,ETA 会增加 5 小时,训练速度变得非常慢:

5/60000 [.......................] - 预计到达时间:5:50:00 - 损失:1.9749 - 累积:0.3437

这是可重现的脚本:

import tensorflow as tf
from tensorflow import keras
import time

print(tf.__version__)


def get_model():
    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(28, 28)),
        keras.layers.Dense(128, activation='relu'),
        keras.layers.Dense(10, activation='softmax')
    ])
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    return model


(train_images, train_labels), (test_images, test_labels) = keras.datasets.fashion_mnist.load_data()
train_images = train_images / 255.0

model = get_model()

# Very quick - 2 seconds
start = time.time()
model.fit(train_images, train_labels, epochs=1)
end = time.time()
print("{} seconds", end - start)

model = get_model()

# Very slow - 5 hours
start = time.time()
model.fit(train_images, train_labels, epochs=1, steps_per_epoch=len(train_images))
end = time.time()
print("{} seconds", end - start)

我也尝试过使用纯 Keras,但问题仍然存在。我使用 1.12.0 版本的 Tensorflow、python 3 和 Ubuntu 18.04.1 LTS。

为什么steps_per_epoch 参数会导致如此显着的速度下降,我该如何避免这种情况?

谢谢!

【问题讨论】:

  • 这会很慢,但是 mnist 数据集中的 5 张图像需要 5 小时?看起来太多了。 (如果steps_per_epoch为60000,批量大小为1张)。
  • 尝试使用steps_per_epoch(有大步和小步)运行示例代码,在这两种情况下都无法在我的GPU上分配内存。但是使用batch_size (100) 运行正常。
  • 貌似steps_per_epoch切换到None,是切换batch_size的默认值(32)。猜猜你可以在另一个 [SO 主题:fit_generator 中的 Keras steps_per_epoch 如何工作](stackoverflow.com/questions/46820609) 中找到答案
  • @Butuzov 我也尝试在第一个示例中将 batch_size 设置为 1,它的工作速度相对较快 - 只需一分钟的训练。

标签: python tensorflow keras


【解决方案1】:

请注意,您将 fit 与一组数据一起使用。您没有使用 fit_generator 或使用任何生成器。

除非您有非常规的想法,否则使用steps_per_epoch 毫无意义。

fit 中的默认批量大小为 32,这意味着您正在以每个 epoch 的 60000 // 32 = 1875 步数进行训练。

如果您使用这个数字 1875,您将训练与默认 None 相同数量的批次。如果您使用60000 步骤,则将一个纪元乘以 32。(由于速度的巨大差异,我想说在这种情况下默认批量大小也发生了变化)


输出中显示的无步骤拟合的总数是图像的总数。请注意已完成项目的数量如何以 32 的倍数增长。

使用步数时显示的总数是步数。请注意已完成的步骤数是如何从 1 到 1 增长的。

【讨论】:

  • 感谢详细的解释!看起来就是这样。我已将第二个示例更改为使用生成器(批量大小=32),它的工作速度与第一个示例相同。明天我会在我的工作中尝试这个,如果一切顺利,我会标记答案。
  • 按预期在 Ubuntu 上工作。谢谢!
猜你喜欢
  • 2018-08-14
  • 2017-05-11
  • 2020-02-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 2018-03-12
  • 2018-05-07
  • 1970-01-01
相关资源
最近更新 更多