【每天进步一点点】如何在Atlas 200 DK 上创建推理引擎执行推理(Python版)

举报
Tianyi_Li 发表于 2020/05/25 10:12:07 2020/05/25
【摘要】 在Ascend 310上运行程序,每一个环节都被视为一个engine,比如预处理engine,模型推理engine,这里创建的就是模型推理的engine。模型engine创建首先要初始化,一般是指定Graph和engine的ID,做一些设置,比如图像输入的宽度和高度等。这里使用官方例程中的模板进行基本设置,之后根据模板设计自己的推理过程,主要是Inference这部分代码。

原因:

有些时候,可能需要多个模型做推理,一般一个模型要创建一个model_engine,这个时候就要自己创建了。当然,也可以参考官方多模型推理的例子,不过还是自己知道如何创建比较方便。

介绍:

这里要说一下,在Ascend 310上运行程序,每一个环节都被视为一个engine,比如预处理engine,模型推理engine,这里创建的就是模型推理的engine。模型engine创建首先要初始化,一般是指定Graph和engine的ID,做一些设置,比如图像输入的宽度和高度等。这里使用官方例程中的模板进行基本设置,之后根据模板设计自己的推理过程,主要是Inference这部分代码,这是对模型推理返回的resultList做解析的部分,也就是后处理部分。以官方例程基于的人脸识别为例。

  1. 首先是得到模板,这个模板与模型推理具体操作无关,因此,可以适用于任何模型engine的创建。

# encoding=utf-8

import hiai
import time

class ModelManager(object):
    def __init__(self):
        pass

    '''
    初始化成功返回Graph实例,初始化失败返回None
    '''

    def CreateGraph(self, model,graph_id, model_engine_id):
    
        # 获取Graph实例
        myGraph = hiai.Graph(hiai.GraphConfig(graph_id = graph_id))
        if myGraph is None:
            print('get graph failed')
            return None
        with myGraph.as_default():
            model_engine = hiai.Engine(hiai.EngineConfig(engine_name='ModelInferenceEngine', side=hiai.HiaiPythonSide.Device,internal_so_name='/lib64/libhiai_python_device2.7.so',engine_id = model_engine_id))
            if model_engine is None:
                print('get model_engine failed')
                return None
            else:
                print('get model_engine ok!')
            with model_engine.as_default():
                if (None == model_engine.inference(input_tensor_list=hiai.NNTensorList(), ai_model=model)):
                    print('Init model_engine failed ')
                    return None
                else:
                    print('Init model_engine ok!')
                    
        # 创建Graph
        if (hiai.HiaiPythonStatust.HIAI_PYTHON_OK == myGraph.create_graph()):
            print('create graph ok ')
            return myGraph
        else:
            print('create graph failed')
            return None

    '''
    传参失败或是推理失败,皆返回None
    '''

    def Inference(self, graphHandle, inputTensorList):
        if not isinstance(graphHandle, hiai.Graph):
            print("graphHandle is not Graph object")
            return None
            
        # 模型输入tensorlist
        resultList = graphHandle.proc(inputTensorList)
        if resultList is None:
            print('Inference error')
        return resultList

2. 接下来就是人脸识别模型engine的创建了。

# encoding=utf-8

from ConstManager import *
import ModelManager
import hiai
from hiai.nn_tensor_lib import DataType
import numpy as np
import cv2
import time
import datetime

'''
人脸特征向量抽取模型不需要对齐,输入96x112,图像输入必须处理成numpy格式
返回值:512维度人脸特征向量
'''


class FaceRecognitionInference(object):
    def __init__(self):
        # 由用户指定人脸识别推理引擎的所在Graph的id号
        self.graph_id = 1002
        self.model_engine_id = 100
        # 基于输入图片的人脸特征向量
        self.embList = []
        # 实例化模型管理类
        self.model = ModelManager.ModelManager()
        self.width = 96
        self.height = 112
        # 描述推理模型以及初始化Graph
        self.graph = None
        self._getgraph()

    def __del__(self):
        self.graph.destroy()

    def _getgraph(self):
        # 描述推理模型
        inferenceModel = hiai.AIModelDescription('face_recognition', face_recognition_model_path)
        # 初始化Graph
        self.graph = self.model.CreateGraph(inferenceModel, self.graph_id, self.model_engine_id)
        if self.graph is None:
            print("Init Graph failed")

    '''
    1.定义输入Tensor的格式
    2.调用推理接口
    3.对一帧推理的正确结果保存到self.resultList中
    4.根据返回值True和False判断是否推理成功
    '''
    # face_image = boxList
    def Inference(self, face_image):
        if isinstance(face_image, np.ndarray) is None:
            print("face_image must is np.ndarray ")
            return False
        # h, w, c = face_image.shape
        # 将上一帧图片推理出的人脸数据清空
        del(self.embList[:])
        del(self.face_image_horizontal_flip_embList[:])

        # 将推理结果的数据保存到临时列表
        # 再从临时列表中去筛选出有效的人脸坐标,保存到self.resultList中
        # 从原始图片中crop出的人脸(数据类型为numpy数组),保存到一个列表中self.nparray
        for i in range(len(face_image)):
            face_image = cv2.resize(face_image, (96, 112))

            face_image = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)

            inputImageTensor = hiai.NNTensor(face_image)

            nntensorList = hiai.NNTensorList(inputImageTensor)

            # 调用推理接口
            resultList = self.model.Inference(self.graph, nntensorList)

            if resultList is not None:
                self.embList.append(resultList)
            else:
                print('Face Recognition Failed! Please Check.')
                return False
        return True

注:这只是示例,代码真正执行需要根据自己模型的推理结果做具体解析


这里还需要执行.om存放模型的路径,在ConstManager.py文件中:

face_recognition_model_path = './sphereface.om'

至此,这个模型engine的创建就完成了,推理主要使用的是Inference(self, face_image)函数,输入是一张人脸图片(96*112,RGB格式,这里使用opencv直接获取,是BGR格式的,在模型转换时,做了BGR到RGB的色域转换,所以在代码中没有体现),得到的一个512维的特征向量。

注:sphereface应该是拼接人脸和水平翻转之后的人脸两个特征向量,这里只是做了人脸的特征向量提取,没有做水平翻转之后的特征提取。


总的来说,创建一个模型推理engine还是比较简单的,对于移植应用到Atlas 200 DK来说,最难得应该就是模型转换以及转换后推理结果是否与原模型大体一致,以及对推理结果的解析了。但基本的常见推理engine还是要了解的,不过最近好像官方码云出了atlasutils,从预处理到模型推理engine的创建和推理做了封装,操作和执行更简单了,有机会,大家可以试一试。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。