【问题标题】:Tensorflow - adding Dropout layer increases inference time significantlyTensorflow - 添加 Dropout 层显着增加推理时间
【发布时间】:2020-07-03 01:31:24
【问题描述】:

我的 CNN 比较小

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(input_shape=(400,400,3), filters=6, kernel_size=5, padding='same', activation='relu'),
    tf.keras.layers.Conv2D(filters=12, kernel_size=3, padding='same', activation='relu'),
    tf.keras.layers.Conv2D(filters=24, kernel_size=3, strides=2, padding='valid', activation='relu'),
    tf.keras.layers.Conv2D(filters=32, kernel_size=3, strides=2, padding='valid', activation='relu'),
    tf.keras.layers.Conv2D(filters=48, kernel_size=3, strides=2, padding='valid', activation='relu'),
    tf.keras.layers.Conv2D(filters=64, kernel_size=3, strides=2, padding='valid', activation='relu'),
    tf.keras.layers.Conv2D(filters=96, kernel_size=3, strides=2, padding='valid', activation='relu'),
    tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=2, padding='valid', activation='relu'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dense(240, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy')

我使用以下代码来衡量模型性能:

for img_per_batch in [1, 5, 10, 50]:
    # warm up the model
    image = np.random.random(size=(img_per_batch, 400, 400, 3)).astype('float32')
    model(image, training=False)

    n_iter = 100
    start_time = time.time()
    for _ in range(n_iter):
        image = np.random.random(size=(img_per_batch, 400, 400, 3)).astype('float32')
        model(image, training=False)
    dt = (time.time() - start_time) * 1000
    print(f'img_per_batch = {img_per_batch}, {dt/n_iter:.2f} ms per iteration, {dt/n_iter/img_per_batch:.2f} ms per image')

我的输出(Nvidia Jetson Xavier,tensorflow==2.0.0):

img_per_batch = 1, 21.74 ms per iteration, 21.74 ms per image
img_per_batch = 5, 42.35 ms per iteration, 8.47 ms per image
img_per_batch = 10, 68.37 ms per iteration, 6.84 ms per image
img_per_batch = 50, 312.83 ms per iteration, 6.26 ms per image

然后我在每个全连接层之后添加 dropout 层:

model = tf.keras.models.Sequential([
    # ... convolution layers are same
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(.3),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(.3),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(.3),
    tf.keras.layers.Dense(240, activation='softmax')
])

添加层后输出如下:

img_per_batch = 1, 31.18 ms per iteration, 31.18 ms per image
img_per_batch = 5, 76.15 ms per iteration, 15.23 ms per image
img_per_batch = 10, 127.91 ms per iteration, 12.79 ms per image
img_per_batch = 50, 513.85 ms per iteration, 10.28 ms per image

理论上,dropout 层不应影响推理性能。但是在上面的代码中,添加 dropout 层会使单张图像预测时间增加 1.5 倍,而 10 图像批量预测几乎比没有 dropout 慢两倍。我做错了吗?

【问题讨论】:

  • 查看 model.summary() 中的形状,计算其中有多少元素以及 dropout 需要做多少工作。你的网络几乎没有下采样,所以很多层会输出很多元素。
  • 问题不是为什么 dropout 层很慢,而是为什么它会减慢 inference。在我的理解中,dropout 层应该仅在训练模式下处于活动状态,并在预测期间禁用(当通过 training=False 时)。而且Flatten层的输出是形状(None, 3200),dropout层的参数不是很多,不能解释两倍的性能下降(每个卷积层的strides=2,所以网络确实有下采样)
  • 我同意这没有任何意义。但无论这里出了什么问题,它都在 tf2.2 中明确修复:colab.research.google.com/drive/…
  • 嗯,从技术上讲,在推理时,您仍然应该将层输入乘以 p_keep 以保持训练分布的形状,对吧?也许这可以解释差异

标签: performance tensorflow deep-learning


【解决方案1】:

显然这是 TensorFlow 2.0.0 中的一个已知问题:see this GitHub comment

尝试使用model.predict(x) 而不是model(x)

这也可以通过更新到 TensorFlow 的更新版本(例如 2.1.0)来解决。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 2021-03-27
    • 2023-03-30
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 2013-08-30
    相关资源
    最近更新 更多