我使用Python2.7,MXNet V1.3.0ML框架在ONNX格式的图像分类模型(V1.2.1,opset 7)上运行推理,其中我一次向推断器提供一幅图像。我需要做什么来异步运行多个镜像的推理,同时还要等待它们全部完成?
我正在提取帧作为.jpeg图像从视频在30帧每秒。举个例子,当我在一个长度为20s的视频上运行这个过程时,它会生成600张.jpeg图像。现在,我遍历这些图像的列表,并将每个图像的相对路径传递给下面的函数,该函数随后从目标图像推断。
def infer(self, target_image_path):
target_image_path = self.__output_directory + '/' + target_image_path
image_data = self.__get_image_data(target_image_path) # Get pixel data
'''Define the model's input'''
model_metadata = onnx_mxnet.get_model_metadata(self.__model)
data_names = [inputs[0]
for inputs in model_metadata.get('input_tensor_data')]
Batch = namedtuple('Batch', 'data')
ctx = mx.eia() # Set the context to elastic inference
'''Load the model'''
sym, arg, aux = onnx_mxnet.import_model(self.__model)
mod = mx.mod.Module(symbol=sym, data_names=data_names,
context=ctx, label_names=None)
mod.bind(data_shapes=[(data_names[0], image_data.shape)],
label_shapes=None, for_training=False)
mod.set_params(arg_params=arg, aux_params=aux,
allow_missing=True, allow_extra=True)
'''Run inference on the image'''
mod.forward(Batch([mx.nd.array(image_data)]))
predictions = mod.get_outputs()[0].asnumpy()
predictions = predictions[0].tolist()
'''Apply emotion labels'''
zipb_object = zip(self.__emotion_labels, predictions)
prediction_dictionary = dict(zipb_object)
return prediction_dictionary预期的行为将是异步地为每个映像运行推断,但也会等待整个批处理过程完成。
发布于 2019-04-12 02:00:47
您不应该做的一件事是为每个图像加载模型。应该加载模型一次,然后在所有600个图像上运行推断。
例如,你可以这样重构你的代码:
def load_model(self):
'''Load the model'''
model_metadata = onnx_mxnet.get_model_metadata(self.__model)
data_names = [inputs[0]
for inputs in model_metadata.get('input_tensor_data')]
Batch = namedtuple('Batch', 'data')
ctx = mx.eia() # Set the context to elastic inference
'''Load the model'''
sym, arg, aux = onnx_mxnet.import_model(self.__model)
mod = mx.mod.Module(symbol=sym, data_names=data_names,
context=ctx, label_names=None)
mod.bind(data_shapes=[(data_names[0], image_data.shape)],
label_shapes=None, for_training=False)
mod.set_params(arg_params=arg, aux_params=aux,
allow_missing=True, allow_extra=True)
return mod
def infer(self, mod, target_image_path):
target_image_path = self.__output_directory + '/' + target_image_path
image_data = self.__get_image_data(target_image_path) # Get pixel data
'''Run inference on the image'''
mod.forward(Batch([mx.nd.array(image_data)]))
predictions = mod.get_outputs()[0].asnumpy()
predictions = predictions[0].tolist()
'''Apply emotion labels'''
zipb_object = zip(self.__emotion_labels, predictions)
prediction_dictionary = dict(zipb_object)
return prediction_dictionaryMXNet在异步引擎上运行,您不必等待图像完成处理即可将新图像排入队列。
MXNet中的一些调用是异步的,例如,当您调用mod.forward()时,此调用立即返回,而不等待计算结果。其他调用是同步的,例如mod.get_outputs()[0].asnumpy(),这会将数据复制到CPU,因此它必须是同步的。在每次迭代之间进行同步调用会稍微减慢处理速度。
假设您可以访问image_paths列表,您可以这样处理它们,以最小化等待时间,并且只在末尾有一个同步点:
results = []
for target_image_path in image_paths:
image_data = self.__get_image_data(target_image_path) # Get pixel data
'''Run inference on the image'''
mod.forward(Batch([mx.nd.array(image_data)]))
results.append(mod.get_outputs()[0])
predictions = [result.asnumpy()[0].tolist() for result in results]您可以在这里阅读更多关于使用MXNet进行异步编程的内容:http://d2l.ai/chapter_computational-performance/async-computation.html
更好的是,如果您知道您有N个图像要处理,您可以将它们分批处理,例如16个,以增加处理的并行度。但是,这样做会增加内存消耗。由于您似乎正在使用弹性推理上下文,因此您的整体内存将是有限的,我建议您坚持使用较小的批处理大小,以避免出现内存不足的风险。
https://stackoverflow.com/questions/55572623
复制相似问题