首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在MXNet和Python2.7中同时对多个图像运行一个图像分类模型的推理

如何在MXNet和Python2.7中同时对多个图像运行一个图像分类模型的推理
EN

Stack Overflow用户
提问于 2019-04-08 19:40:17
回答 1查看 664关注 0票数 1

我使用Python2.7,MXNet V1.3.0ML框架在ONNX格式的图像分类模型(V1.2.1,opset 7)上运行推理,其中我一次向推断器提供一幅图像。我需要做什么来异步运行多个镜像的推理,同时还要等待它们全部完成?

我正在提取帧作为.jpeg图像从视频在30帧每秒。举个例子,当我在一个长度为20s的视频上运行这个过程时,它会生成600张.jpeg图像。现在,我遍历这些图像的列表,并将每个图像的相对路径传递给下面的函数,该函数随后从目标图像推断。

代码语言:javascript
复制
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

预期的行为将是异步地为每个映像运行推断,但也会等待整个批处理过程完成。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-12 02:00:47

您不应该做的一件事是为每个图像加载模型。应该加载模型一次,然后在所有600个图像上运行推断。

例如,你可以这样重构你的代码:

代码语言:javascript
复制
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_dictionary

MXNet在异步引擎上运行,您不必等待图像完成处理即可将新图像排入队列。

MXNet中的一些调用是异步的,例如,当您调用mod.forward()时,此调用立即返回,而不等待计算结果。其他调用是同步的,例如mod.get_outputs()[0].asnumpy(),这会将数据复制到CPU,因此它必须是同步的。在每次迭代之间进行同步调用会稍微减慢处理速度。

假设您可以访问image_paths列表,您可以这样处理它们,以最小化等待时间,并且只在末尾有一个同步点:

代码语言:javascript
复制
    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个,以增加处理的并行度。但是,这样做会增加内存消耗。由于您似乎正在使用弹性推理上下文,因此您的整体内存将是有限的,我建议您坚持使用较小的批处理大小,以避免出现内存不足的风险。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55572623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档