我在进行一个项目,使用编译后的Keras ANN模型来根据传感器数据对不同位置进行分类。这些数据不断地输入模型,由后台运行的数据收集守护线程进行预测。我们遇到了一个问题,即model.predict()的执行时间长达2秒,即使输入的是小数据集。每个数据点都是包含38个浮点数的数组。预测时间似乎不受输入行数的影响,至少在一定数量范围内。我们尝试过只输入一行数据,以及输入数百行数据,但耗时始终保持在2秒左右。即使是对于较大的数据集,这样的时间消耗是不是也太高了?
如果有帮助的话:我们的程序使用多线程来收集传感器数据并重组它们,使之符合模型的predict方法。两个守护线程在后台运行,收集并重组数据,而主线程则从已结构化数据队列中主动提取数据,并基于这些数据进行分类。以下是我们基于收集的数据进行分类的代码:
values = []rows = 0while rows < 20: val = pred_queue.shift() if val != None: values.append(val) rows += 1rows = 0 values = np.squeeze(values)start_time = time.perf_counter()predictions = model.predict(values)elapsed_time = round(time.perf_counter() - start_time, 2)print("Predict time: ", elapsed_time) for i in range(len(predictions)): print(predictions[i].argmax()) #print(f"Predicted {classification_res} in {elapsed_time}s!")
代码的澄清说明:
shift()方法返回pred_queue()中的第一个条目。这可能是包含38个浮点数的数组,也可能是None,这取决于队列是否为空。
是什么可能导致这些预测如此缓慢?
编辑
关于预测时间的混淆原因是,我们之前在编译模型之前已经用一些数据运行过该模型。这些数据点是从csv文件中收集的,并放入pandas数据框中,最后传入predict方法。这些数据不是实时流传输的,但数据集要大得多,每个包含38个浮点数的行有9000行左右。我们计时后发现,这些预测只用了0.3秒,显然比我们当前的速度快得多!
回答:
你可以尝试直接使用__call__
方法,正如predict
方法的文档所述(强调是我的):
计算是以批次进行的。此方法旨在在大规模输入时提高性能。对于能够在一批中处理的小量输入,建议直接使用
__call__
以获得更快的执行速度,例如,model(x)
,或者如果您有像tf.keras.layers.BatchNormalization
这样的层,其在推理期间行为不同,则使用model(x, training=False)
。此外,请注意,测试损失不受噪声和丢弃等正则化层的影響。
请注意,您注意到的性能下降可能与机器资源有限有关。请调查CPU使用率、RAM使用情况等。