ga9*_*dil 19 python performance keras tensorflow tensorflow2.0
我试图估计我的 keras 模型的预测时间并意识到一些奇怪的事情。除了正常情况下相当快之外,模型每隔一段时间需要很长时间才能做出预测。不仅如此,这些时间也会随着模型运行的时间而增加。我添加了一个最小的工作示例来重现错误。
import time
import numpy as np
from sklearn.datasets import make_classification
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
# Make a dummy classification problem
X, y = make_classification()
# Make a dummy model
model = Sequential()
model.add(Dense(10, activation='relu',name='input',input_shape=(X.shape[1],)))
model.add(Dense(2, activation='softmax',name='predictions'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(X, y, verbose=0, batch_size=20, epochs=100)
for i in range(1000):
# Pick a random sample
sample = np.expand_dims(X[np.random.randint(99), :], axis=0)
# Record the prediction time 10x and then take the average
start = time.time()
for j in range(10):
y_pred = model.predict_classes(sample)
end = time.time()
print('%d, %0.7f' % (i, (end-start)/10))
Run Code Online (Sandbox Code Playgroud)
时间不取决于样本(它是随机挑选的)。如果重复测试,for 循环中预测需要更长时间的索引将(几乎)再次相同。
我正在使用:
tensorflow 2.0.0
python 3.7.4
Run Code Online (Sandbox Code Playgroud)
对于我的应用程序,我需要保证在特定时间内执行。然而,考虑到这种行为,这是不可能的。出了什么问题?是 Keras 中的错误还是 tensorflow 后端中的错误?
编辑:
predict_on_batch
显示相同的行为,但是,更稀疏:
y_pred = model(sample, training=False).numpy()
也显示了一些严重的异常值,但是,它们并没有增加。
编辑 2:我降级到最新的 tensorflow 1 版本 (1.15)。不仅问题不再存在,“正常”的预测时间也显着提高!我不认为这两个尖峰有问题,因为当我重复测试时它们没有出现(至少不是在相同的指数和线性增加)并且百分比没有第一个图中那么大。
因此我们可以得出结论,这似乎是 tensorflow 2.0 固有的问题,它在其他情况下表现出与@OverLordGoldDragon 提到的类似的行为。
Ove*_*gon 10
在我遇到的几个实例中,TF2 通常表现出糟糕和类似错误的内存管理 -此处和此处的简要说明。特别是预测,最高效的喂养方法是通过model(x)
直接 - 请参阅此处及其相关讨论。
概括地说:model(x)
通过其它的作用__call__
方法(其从继承base_layer.Layer
),而predict()
,predict_classes()
等经由涉及专用回路功能_select_training_loop()
; 每个都使用适合不同用例的不同数据预处理和后处理方法,并且model(x)
在 2.1 中专门设计用于产生最快的小模型/小批量(可能是任意大小)性能(并且在 2.0 中仍然是最快的)。
从相关讨论中引用TensorFlow 开发人员:
您可以使用模型调用而不是模型预测来预测输出,即调用
model(x)
会使这个更快,因为没有“转换为数据集”部分,而且它直接调用缓存的tf.function
.
注意:这在 2.1 中应该不是问题,尤其是 2.2 - 但无论如何都要测试每种方法。我也意识到这并不能直接回答你关于时间峰值的问题;我怀疑它与 Eager 缓存机制有关,但最可靠的确定方法是 via TF Profiler
,它在 2.1中被破坏了。
更新:关于增加峰值,可能的 GPU 节流;你已经完成了大约 1000 次迭代,请尝试 10,000 次 - 最终,增加应该停止。正如您在评论中指出的,这不会发生在model(x)
; 有意义,因为少了一个 GPU 步骤(“转换为数据集”)。
更新 2:如果您遇到此问题,您可以在这里向开发人员提出问题;主要是我在那里唱歌
归档时间: |
|
查看次数: |
1932 次 |
最近记录: |