zoukankan      html  css  js  c++  java
  • 使用Relay部署编译ONNX模型

    使用Relay部署编译ONNX模型

    本文介绍如何使用Relay部署ONNX模型的入门。

    首先,必须安装ONNX软件包。

    一个快速的解决方案是安装protobuf编译器,然后

    pip install onnx --user

    或参考官方网站。 https://github.com/onnx/onnx

    import onnx
    import numpy as np
    import tvm
    from tvm import te
    import tvm.relay as relay
    from tvm.contrib.download import download_testdata

    加载预训练的ONNX模型

    使用的示例超分辨率模型与onnx教程http://pytorch.org/tutorials/advanced/super_resolution_with_caffe2.html中的模型完全相同,跳过pytorch模型构建部分,下载保存的onnx模型

    model_url = "".join(
        [
            "https://gist.github.com/zhreshold/",
            "bcda4716699ac97ea44f791c24310193/raw/",
            "93672b029103648953c4e5ad3ac3aadf346a4cdc/",
            "super_resolution_0.2.onnx",
        ]
    )
    model_path = download_testdata(model_url, "super_resolution.onnx", module="onnx")
    # now you have super_resolution.onnx on disk
    onnx_model = onnx.load(model_path)

    输出:

    File /workspace/.tvm_test_data/onnx/super_resolution.onnx exists, skip.

    加载测试图像

    一只猫占主导地位的例子!此模型采用尺寸为224x224的单个输入图像,并输出比沿每个轴的输入大3x的缩放图像672x672图像。重新缩放猫咪图像以适合此输入形状,然后转换为YCbCr。然后,超分辨率模型将应用于亮度(Y)通道。

    from PIL import Image
     
    img_url = "https://github.com/dmlc/mxnet.js/blob/main/data/cat.png?raw=true"
    img_path = download_testdata(img_url, "cat.png", module="data")
    img = Image.open(img_path).resize((224, 224))
    img_ycbcr = img.convert("YCbCr")  # convert to YCbCr
    img_y, img_cb, img_cr = img_ycbcr.split()
    x = np.array(img_y)[np.newaxis, np.newaxis, :, :]

    输出:

    File /workspace/.tvm_test_data/data/cat.png exists, skip.

    用Relay编译模型

    ONNX模型将模型输入值与参数值混合,输入的名称为1。此模型取决于模型,查阅模型的文档,确定完整的输入和参数名称空间。

    将形状字典传递给relay.frontend.from_onnx方法,告诉中继哪些ONNX参数是输入,哪些是参数,并提供输入大小的静态定义。

    target = "llvm"
     
    input_name = "1"
    shape_dict = {input_name: x.shape}
    mod, params = relay.frontend.from_onnx(onnx_model, shape_dict)
     
    with tvm.transform.PassContext(opt_level=1):
        intrp = relay.build_module.create_executor("graph", mod, tvm.cpu(0), target)

    输出:

    /workspace/docs/../python/tvm/relay/frontend/onnx.py:3132: UserWarning: Mismatched attribute type in ' : kernel_shape'
     
    ==> Context: Bad node spec: input: "1" input: "2" output: "11" op_type: "Conv" attribute { name: "kernel_shape" ints: 5 ints: 5 } attribute { name: "strides" ints: 1 ints: 1 } attribute { name: "pads" ints: 2 ints: 2 ints: 2 ints: 2 } attribute { name: "dilations" ints: 1 ints: 1 } attribute { name: "group" i: 1 }
      warnings.warn(str(e))

    在TVM上执行

    dtype = "float32"
    tvm_output = intrp.evaluate()(tvm.nd.array(x.astype(dtype)), **params).asnumpy()

    显示结果

    将输入和输出图像并列放置。亮度通道Y是模型的输出。调整色度通道CbCr的大小,以与简单的双三次算法匹配。然后将图像重新组合并转换回RGB

    from matplotlib import pyplot as plt
     
    out_y = Image.fromarray(np.uint8((tvm_output[0, 0]).clip(0, 255)), mode="L")
    out_cb = img_cb.resize(out_y.size, Image.BICUBIC)
    out_cr = img_cr.resize(out_y.size, Image.BICUBIC)
    result = Image.merge("YCbCr", [out_y, out_cb, out_cr]).convert("RGB")
    canvas = np.full((672, 672 * 2, 3), 255)
    canvas[0:224, 0:224, :] = np.asarray(img)
    canvas[:, 672:, :] = np.asarray(result)
    plt.imshow(canvas.astype(np.uint8))
    plt.show()

     

    Readme

    默认情况下,ONNX根据动态形状定义模型。ONNX导入器在导入时会保留这种动态性,并且编译器会在编译时尝试将模型转换为静态形状。如果失败,则模型中可能仍存在动态操作。并非所有的TVM内核当前都支持动态形状,如果在使用动态内核时遇到错误,在ask.tvm.apache.org上提出问题。

    该特定模型是使用较旧版本的ONNX构建的。在导入阶段,ONNX导入程序将运行ONNX验证程序,这可能会引发不匹配的属性类型警告。由于TVM支持许多不同的ONNX版本,中继模型仍然有效。

    人工智能芯片与自动驾驶
  • 相关阅读:
    iOS多线程_06_GCD其它用法
    iOS多线程_05_线程间通信NSThread/GCD
    iOS多线程_04_GCD
    iOS多线程_03_Block
    iOS多线程_02_多线程的安全问题
    iOS多线程_01_简介和NSThread
    shell 根据端口号输出所有的pid
    【java核心36讲】接口和抽象类的区别
    CSS布局
    CSS基础
  • 原文地址:https://www.cnblogs.com/wujianming-110117/p/14484038.html
Copyright © 2011-2022 走看看