添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

MNN Python API可以使用 源码安装 ,也可以直接使用 pip 安装预编译whl包; pip 安装用法如下:

# 外部版本安装
pip install MNN==$version
# 公司内部版本安装
pip install -i https://artifacts.antgroup-inc.cn/simple/ MNN-Internal==$version
# 配置执行后端,线程数,精度等信息;key-vlaue请查看API介绍
config = {}
config['precision'] = 'low' # 当硬件支持(armv8.2)时使用fp16推理
config['backend'] = 0       # CPU
config['numThread'] = 4     # 线程数
rt = nn.create_runtime_manager((config,))
# 加载模型创建_Module
net = nn.load_module_from_file('mobilenet_v1.mnn', ['data'], ['prob'], runtime_manager=rt)
# 读取图片
image = cv.imread('cat.jpg')
# 转换为float32, 形状为[224,224,3]
image = cv.resize(image, (224, 224), mean=[103.94, 116.78, 123.68], norm=[0.017, 0.017, 0.017])
# 增加batch HWC to NHWC
input_var = np.expand_dims(image, 0)
# NHWC to NC4HW4
input_var = expr.convert(input_var, expr.NC4HW4)
# 执行推理
output_var = net.forward(input_var)
# NC4HW4 to NHWC
output_var = expr.convert(output_var, expr.NHWC)
# 打印出分类结果, 282为猫
print("output belong to class: {}".format(np.argmax(output_var)))
# output belong to class: 282

其他示例可以参考示例;也可以参考示例工程

使用Python Session API [deprecated]

不建议使用该API执行推理,建议使用Module API

数据类型

Python中Session API的函数名与用法与C++基本一样。使用的主要数据类型如下:

  • Interpreter 解释器,持有模型资源

  • Session 会话,持有推理资源

  • Tensor 用来描述输入输出数据

  • CVImageProcess 图像处理模块

  • CVMatrix 用来描述图像的仿射变换

  • 推理流程

    基本推理流程如下:

  • 创建Interpreter

  • 创建Session

  • 获取Session的输入输出

  • 使用ImageProcess/cv进行图像处理(可选)

  • 拷贝数据到输入Tensor

  • 执行resize(可选)

  • 执行Session

  • 获取输出Tensor数据

  • import MNN
    import MNN.cv as cv
    import MNN.numpy as np
    import MNN.expr as expr
    # 创建interpreter
    interpreter = MNN.Interpreter("mobilenet_v1.mnn")
    # 创建session
    config = {}
    config['precision'] = 'low'
    config['backend'] = 'CPU'
    config['thread'] = 4
    session = interpreter.createSession(config)
    # 获取会话的输入输出
    input_tensor = interpreter.getSessionInput(session)
    output_tensor = interpreter.getSessionOutput(session)
    # 读取图片
    image = cv.imread('cat.jpg')
    dst_height = dst_width = 224
    # 使用ImageProcess处理第一张图片,将图片转换为转换为size=(224, 224), dtype=float32,并赋值给input_data1
    image_processer = MNN.CVImageProcess({'sourceFormat': MNN.CV_ImageFormat_BGR,
                                          'destFormat': MNN.CV_ImageFormat_BGR,
                                          'mean': (103.94, 116.78, 123.68, 0.0),
                                          'filterType': MNN.CV_Filter_BILINEAL,
                                          'normal': (0.017, 0.017, 0.017, 0.0)})
    image_data = image.ptr
    src_height, src_width, channel = image.shape
    input_data1 = MNN.Tensor((1, dst_height, dst_width, channel), MNN.Halide_Type_Float, MNN.Tensor_DimensionType_Tensorflow)
    #设置图像变换矩阵
    matrix = MNN.CVMatrix()
    x_scale = src_width / dst_width
    y_scale = src_height / dst_height
    matrix.setScale(x_scale, y_scale)
    image_processer.setMatrix(matrix)
    image_processer.convert(image_data, src_width, src_height, 0, input_data1)
    # 使用cv模块处理第二张图片,将图片转换为转换为size=(224, 224), dtype=float32,并赋值给input_data2
    image = cv.imread('TestMe.jpg')
    image = cv.resize(image, (224, 224), mean=[103.94, 116.78, 123.68], norm=[0.017, 0.017, 0.017])
    input_data2 = np.expand_dims(image, 0) # [224, 224, 3] -> [1, 224, 224, 3]
    # 合并2张图片到,并赋值给input_data
    input_data1 = expr.const(input_data1.getHost(), input_data1.getShape(), expr.NHWC) # Tensor -> Var
    input_data = np.concatenate([input_data1, input_data2])  # [2, 224, 224, 3]
    input_data = MNN.Tensor(input_data) # Var -> Tensor
    # 演示多张图片输入,所以将输入resize到[2, 3, 224, 224]
    interpreter.resizeTensor(input_tensor, (2, 3, 224, 224))
    # 重新计算形状分配内存
    interpreter.resizeSession(session)
    # 拷贝数据到输入Tensor
    input_tensor.copyFrom(input_data)
    # 执行会话推理
    interpreter.runSession(session)
    # 从输出Tensor拷贝出数据 
    output_data = MNN.Tensor(output_tensor.getShape(), MNN.Halide_Type_Float, MNN.Tensor_DimensionType_Caffe)
    output_tensor.copyToHostTensor(output_data)
    # 打印出分类结果: 282为猫,385为象
    output_var = expr.const(output_data.getHost(), [2, 1001])
    print("output belong to class: {}".format(np.argmax(output_var, 1)))
    # output belong to class: array([282, 385], dtype=int32)
    

    其他示例可以参考示例;也可以参考示例工程

    使用cv/numpy API

    数据类型

    Python的cvnumpy接口,其中cv是对C++中tools/cv实现的封装;numpy则是对expr接口的封装;这两个接口主要为了提高MNN的易用性,与opencvnumpy做到了再接口上的部分兼容,在用法和思路上基本一致。主要数据类型如下:

  • Var cv中的图像,numpy中的ndarray

  • 主要用法

    cvnumpy主要用作模型的前后处理部分,和一些数值计算任务。比如从图片直接读取数据后一般需要执行颜色空间变换,数据类型变换,缩放,裁剪等操作,这些可以用cv模块函数实现;模型输出的结果可能需要做一些额外的变换和计算,这些可以用numpy模块函数实现。

    使用cvnumpy中的函数做前后处理,执行模型推理的例子

    import MNN
    import MNN.cv as cv
    import MNN.numpy as np
    # 加载模型
    net = MNN.nn.load_module_from_file('mobilenet_v1.mnn', ["data"], ["prob"])
    # cv模块图片处理
    image = cv.imread('cat.jpg')
    image = cv.resize(image, (224, 224))
    # 类似ndarray的数值运算
    image = image - (103.94, 116.78, 123.68)
    image = image * (0.017, 0.017, 0.017)
    input_var = np.expand_dims(image, 0)
    input_var = MNN.expr.convert(input_var, MNN.expr.NC4HW4)
    output_var = net.forward(input_var)
    output_var = MNN.expr.convert(output_var, MNN.expr.NHWC)
    # 类似numpy操作的后处理
    print("output belong to class: {}".format(np.argmax(output_var)))
    

    其他示例可以参考示例;也可以参考示例工程

    cv能力列表

    cv模块提供了与OpenCV相似的接口函数,具备基础的图像处理能力,目前支持的cv函数60个。

    图像编解码