OpenVino 2023.0学习使用(2)- 转换ONNX模型

ONNX简介

ONNX是深度学习模型的表示格式,允许AI开发人员在不同框架之间轻松传输模型。它在深度学习工具中非常受欢迎,如PyTorch,Caffe2,Apache MXNet,Microsoft Cognitive Toolkit等。

转换ONNX模型

本页提供从ONNX格式到OpenVINO IR格式的模型转换说明。要使用模型转换API,请按照安装说明安装OpenVINO开发工具。

模型转换过程假设您拥有一个直接从公共存储库下载的ONNX模型,或从任何支持导出为ONNX格式的框架转换的ONNX模型。

要转换ONNX模型,请使用输入模型.onnx文件的路径运行模型转换:

mo --input_model .onnx

转换模型

要将模型转换为OpenVINO模型格式(ov.Model),可以使用以下命令:

mo --input_model INPUT_MODEL

如果开箱即用转换(仅指定input_model参数)不成功,请使用下面提到的参数覆盖输入形状并剪切模型:

  • 模型转换API提供了两个参数来覆盖用于模型转换的原始输入形状:#1和#2。

有关这些参数的详细信息,请参考手册的“设置输入形状”部分。

  • 要删除模型中不需要的部分(例如不支持的操作和训练子图),请执行以下操作:

使用inputoutput参数定义转换后模型的新输入和输出。 有关更详细的说明,请参阅“切断模型零件”指南。

您还可以通过使用将额外的输入预处理子图插入到转换后的模型中 所述mean_valuesscales_valueslayout和其它参数 嵌入式预处理计算文章。

compress_to_fp16命令行工具中的mo压缩参数允许生成压缩为FP16数据类型的常数(例如,卷积和矩阵乘法的权重)的IR。有关更多详细信息,请参阅将模型压缩到FP16指南。

要获取转换参数的完整列表,请运行以下命令:

mo --help

设置输入形状

指定input_shape参数

convert_model()支持使用包含未定义尺寸的动态输入形状转换模型。 然而,如果数据的形状不会从一个推断请求改变到另一个推断请求, 建议为输入设置静态形状(当所有尺寸都完全定义时)。 在这个阶段而不是在运行时的推理过程中执行它,在性能和内存消耗方面可能是有益的。 要设置静态形状,模型转换API提供了input_shape参数。 有关运行时下的输入形状的详细信息,请参阅更改输入形状指南。 若要了解有关运行时中的动态形状的详细信息,请参阅动态形状指南。

OpenVINO运行时API在某些硬件上推断具有未定义维度的模型时可能存在某些限制。请参阅功能支持矩阵以获取参考。 在这种情况下,input_shape参数和reshape方法可以帮助解决未定义的尺寸。

例如,使用单个输入为TensorFlow MobileNet模型运行模型转换 并指定[2,300,300,3]的输入形状:

mo --input_model MobileNet.pb --input_shape [2,300,300,3]

如果模型有多个输入,则必须将input_shapeinput参数结合使用。 input参数包含输入名称的列表通过input_shape为这些名称定义相同顺序的形状。 例如,使用一对输入dataseq_len启动ONNX OCR模型的模型转换 并为它们指定形状[3,150,200,1][3]

mo --input_model ocr.onnx --input data,seq_len --input_shape [3,150,200,1],[3]

或者,使用input参数指定输入形状,如下所示:

mo --input_model ocr.onnx --input data[3,150,200,1],seq_len[3]

为了优化运行时未定义维度的模型的内存消耗,模型转换API提供了定义维度边界的功能。 未定义尺寸的边界可以用省略号指定。 例如,启动ONNX OCR模型的模型转换,并为批次维度指定边界:

mo --input_model ocr.onnx --input data,seq_len --input_shape [1..3,150,200,1],[1..3]

实际上,一些模型还没有准备好输入形状的变化。 在这种情况下,不能通过模型转换API设置新的输入形状。 有关形状的详细信息,请参阅推理疑难解答 以及放松形状推断流程指南的方法。

切断模型的部分

有时,在将模型转换为OpenVINO IR时,需要删除模型的某些部分。本章介绍如何使用模型转换API参数来执行此操作。模型切割主要适用于TensorFlow模型,这就是为什么TensorFlow将在本章的示例中使用,但它也可能对其他框架有用。

模型切割的目的

以下示例是模型切割有用或甚至需要的情况:

  • 模型具有不能转换为现有OpenVINO操作的预处理或后处理部分。

  • 模型具有便于保持在模型中但在推理期间不使用的训练部分。

  • 一个模型太复杂了,不能一次转换,因为它包含了许多不受支持的操作,这些操作不能很容易地实现为自定义层。

  • OpenVINO™ Runtime中的模型转换或推断出现问题。要识别问题,请通过迭代搜索模型中的问题区域来限制转换范围。

  • 出于调试目的,单个自定义层或自定义层的组合被隔离。

模型转换API参数

模型转换API提供了命令行选项inputoutput来指定新的入口和出口节点,而忽略模型的其余部分:

  • input选项接受输入模型的层名称列表,这些层名称应被视为模型的新入口点。在Model Conversion Python API页面上查看可接受的输入类型的完整列表。

  • output选项接受输出模型的层名称列表,这些层名称应被视为模型的新出口点。

与模型切割无关的情况需要input选项。例如,当模型包含多个输入并且使用input_shapemean_values选项时,input选项指定用于在input_shapemean_values中提供的多个项目与模型中的输入之间正确映射的输入节点的顺序。

模型切割是用Inception V1模型来说明的,可以在models/research/slim存储库中找到。要继续本章,请确保执行了必要的步骤,以准备模型进行模型转换。

嵌入式预处理计算

用于推断的输入数据可以与训练数据集不同,并且需要 在推理之前进行额外的预处理。加快整个管道的建设,包括 预处理和推理,模型转换API提供了特殊的参数,如mean_valuesscale_valuesreverse_input_channelslayout。基于这些 参数,模型转换API生成OpenVINO IR,并额外插入子图 以执行所定义的预处理。该预处理块可以执行平均尺度 输入数据的归一化、沿着通道维度恢复数据以及改变 数据布局。有关参数或 预处理API概述 在OpenVINO Runtime中使用相同的功能。

指定布局

您可能需要设置输入布局,因为某些预处理需要这样做 例如,设置批次、应用平均值或比例以及反转输入通道(BGR<->RGB)。

布局定义形状中尺寸的含义,可以为这两种形状指定布局 输入和输出。某些预处理需要设置输入布局,例如, 设置批次、应用平均值或比例以及反转输入通道(BGR<->RGB)。

有关布局语法,请查看布局API概述。 要指定布局,可以使用layout选项,后跟布局值。

例如,以下命令为Tensorflow指定NHWC布局 导出为ONNX格式的nasnet_large型号:

mo --input_model tf_nasnet_large.onnx --layout nhwc

此外,如果模型具有多个输入或同时需要输入和输出 指定的布局,您需要提供每个输入或输出的名称以应用布局。

例如,以下命令指定ONNX Yolov3-Tiny的布局 模型,其第一输入input_1NCHW布局中,第二输入image_shape 具有两个维度:表示为N?布局的图像的批次和大小:

mo --input_model yolov3-tiny.onnx --layout input_1(nchw),image_shape(n?)

更改模型布局

 如果模型布局与输入数据显示的布局不同,则可能需要更改模型布局。 使用layoutsource_layouttarget_layout更改布局。

例如,对于前面提到的同一nasnet_large模型,可以使用 以下命令在NCHW布局中提供数据:

mo --input_model tf_nasnet_large.onnx --source_layout nhwc --target_layout nchw

mo --input_model tf_nasnet_large.onnx --layout "nhwc->nchw"

同样,如果模型有多个输入或同时需要输入和输出布局 如果指定了布局,则需要提供每个输入或输出的名称以应用布局。

例如,要在Yolo v3 Tiny模型的NHWC布局中提供数据 如前所述,使用以下命令:

mo --input_model yolov3-tiny.onnx --source_layout "input_1(nchw),image_shape(n?)" --target_layout "input_1(nhwc)"

mo --input_model yolov3-tiny.onnx --layout "input_1(nchw->nhwc),image_shape(n?)"

指定平均值和比例值

神经网络模型通常使用归一化的输入数据进行训练。这一 “转换”意味着输入数据值被转换到特定范围内,例如, #1或#2。有时,减去平均值(平均图像 作为预处理的一部分。

存在如何实现输入数据预处理的两种情况。

  • 输入预处理操作是模型的一部分。

    在这种情况下,应用程序不执行单独的预处理步骤: 一切都嵌入到模型本身。convert_model()将生成 ov.具有所需预处理操作的模型,并且没有mean和 scale参数是必需的。

  • 输入预处理操作不是模型的一部分,并且预处理 在应用程序内执行,该应用程序向模型提供输入数据。

    在这种情况下,应向convert_model()提供关于平均值/标度值的信息 将其嵌入到生成的ov.Model中。

convert_model()为代表的模型转换API提供命令行参数 要指定值,请执行以下操作:mean_valuesscale_valuesscale。使用这些参数, 模型转换API为均值嵌入相应的预处理块 该预处理模块对输入数据进行归一化,并优化该块,使得预处理 推理所需的时间可以忽略不计。

例如,以下命令运行PaddlePaddle UNet的模型转换 模型并将均值尺度归一化应用于输入数据:

mo --input_model unet.pdmodel --mean_values [123,117,104] --scale 255

反转输入通道

有时,应用程序的输入图像可以是RGB(或BGR)格式 并且该模型在BGR(或RGB)格式的图像上训练,该格式在 颜色通道的相反顺序。在这种情况下,预处理 通过在推断之前恢复颜色通道来处理输入图像。

为了将这个预处理步骤嵌入到ov.Model中,模型转换API提供了 reverse_input_channels命令行参数,用于混洗颜色通道。

reverse_input_channels参数可用于预处理模型 在以下情况下输入:

  • 输入形状中只有一个维度的大小等于3

  • 一个维度具有未定义的大小,并且使用C参数标记为layout通道。

使用reverse_input_channels参数,模型转换API嵌入相应的 预处理块,用于沿着信道维度还原输入数据并优化 该块使得预处理仅花费可忽略的时间用于推断。

例如,以下命令启动TensorFlow AlexNet的模型转换 模型并将reverse_input_channel预处理块嵌入OpenVINO IR:

mo --input_model alexnet.pb --reverse_input_channels

 将模型压缩到FP16

可选地,所有相关的浮点权重可以在模型转换期间被压缩为FP16数据类型。 它导致创建“压缩的FP16模型”,其占据了大约一半的 文件系统中的原始空间。压缩可能会导致准确度下降。 但是对于大多数模型来说可以忽略。

要压缩模型,请使用compress_to_fp16=True选项:

mo --input_model INPUT_MODEL --compress_to_fp16=False

你可能感兴趣的:(openvino,人工智能,深度学习)