65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Model Optimizer 转换 MXNet 模型

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019年1月23日

CPOL
viewsIcon

4044

模型优化器是一个跨平台的命令行工具,它能够促进训练环境和部署环境之间的过渡,执行静态模型分析,并调整深度学习模型以在终端目标设备上实现最优执行。

引言

模型优化器是一个跨平台的命令行工具,它能够促进训练环境和部署环境之间的过渡,执行静态模型分析,并调整深度学习模型以在终端目标设备上实现最优执行。

模型优化器流程假设您拥有一个使用支持的框架训练的网络模型。下图说明了部署已训练深度学习模型的典型工作流程。

使用 MXNet* 框架训练的模型的优化和部署步骤摘要。

  1. 为 MXNet*(使用 MXNet* 训练您的模型)配置模型优化器
  2. 转换 MXNet 模型,基于训练的网络拓扑、权重和偏差值生成优化的模型中间表示 (IR)。
  3. 使用目标环境中的 推理引擎,通过提供的推理引擎 验证应用程序示例应用程序 来测试中间表示格式的模型。
  4. 推理引擎 集成到您的应用程序中,以便在目标环境中部署模型。

模型优化器工作流程

模型优化器流程假设您拥有一个使用支持的框架之一训练的网络模型。工作流程如下:

  1. 通过从 <INSTALL_DIR>/deployment_tools/model_optimizer/install_prerequisites 文件夹运行 Linux* OS 的配置 bash 脚本或 Windows* OS 的批处理文件,为 MXNet* 框架配置模型优化器。
    • 对于 Linux* OS
      install_prerequisites_mxnet.sh
    • 对于 Windows* OS
      install_prerequisites_mxnet.bat

    有关配置模型优化器的更多详细信息,请参阅 配置模型优化器

  2. 提供已训练的模型作为输入,该模型包含由 .json 文件描述的特定拓扑,以及由 .params 文件描述的调整后的权重和偏差。
  3. 将 MXNet* 模型转换为优化的中间表示。

模型优化器输出的中间表示 (IR) 可以被推理引擎读取、加载和推理。推理引擎 API 为许多支持的 Intel® 平台提供统一的 API。中间表示是一对描述整个模型的文件:

  • .xml:描述网络拓扑
  • .bin:包含权重和偏差的二进制数据

支持的拓扑

下表显示了支持的模型,以及模型库、符号文件和参数文件的链接。

模型名称 模型文件
VGG-16 符号参数
VGG-19 符号参数
ResNet-152 v1 符号参数
SqueezeNet_v1.1 符号参数
Inception BN 符号参数
CaffeNet 符号参数
DenseNet-121 符号参数
DenseNet-161 符号参数
DenseNet-169 符号参数
DenseNet-201 符号参数
MobileNet 符号参数
SSD-ResNet-50 符号 + 参数
SSD-VGG-16-300 符号 + 参数
SSD-Inception v3 符号 + 参数
FCN8(语义分割) 符号参数

其他支持的拓扑

转换 MXNet* 模型

要转换 MXNet 模型:

  1. 转到 <INSTALL_DIR>/deployment_tools/model_optimizer 目录。
  2. 要转换包含 model-file-symbol.jsonmodel-file-0000.params 的 MXNet* 模型,请运行模型优化器启动脚本 mo.py,并指定输入模型文件的路径。
    python3 mo_mxnet.py --input_model model-file-0000.params

提供两组参数来转换您的模型:

使用框架无关转换参数

您可以使用通用(框架无关)参数来调整转换过程。

	optional arguments:
  -h, --help            show this help message and exit
  --framework {tf,caffe,mxnet,kaldi,onnx}
                        Name of the framework used to train the input model.

Framework-agnostic parameters:
  --input_model INPUT_MODEL, -w INPUT_MODEL, -m INPUT_MODEL
                        Tensorflow*: a file with a pre-trained model (binary
                        or text .pb file after freezing). Caffe*: a model
                        proto file with model weights
  --model_name MODEL_NAME, -n MODEL_NAME
                        Model_name parameter passed to the final create_ir
                        transform. This parameter is used to name a network in
                        a generated IR and output .xml/.bin files.
  --output_dir OUTPUT_DIR, -o OUTPUT_DIR
                        Directory that stores the generated IR. By default, it
                        is the directory from where the Model Optimizer is
                        launched.
  --input_shape INPUT_SHAPE
                        Input shape(s) that should be fed to an input node(s)
                        of the model. Shape is defined as a comma-separated
                        list of integer numbers enclosed in parentheses or
                        square brackets, for example [1,3,227,227] or
                        (1,227,227,3), where the order of dimensions depends
                        on the framework input layout of the model. For
                        example, [N,C,H,W] is used for Caffe* models and
                        [N,H,W,C] for TensorFlow* models. Model Optimizer
                        performs necessary transformations to convert the
                        shape to the layout required by Inference Engine
                        (N,C,H,W). The shape should not contain undefined
                        dimensions (? or -1) and should fit the dimensions
                        defined in the input operation of the graph. If there
                        are multiple inputs in the model, --input_shape should
                        contain definition of shape for each input separated
                        by a comma, for example: [1,3,227,227],[2,4] for a
                        model with two inputs with 4D and 2D shapes.
  --scale SCALE, -s SCALE
                        All input values coming from original network inputs
                        will be divided by this value. When a list of inputs
                        is overridden by the --input parameter, this scale is
                        not applied for any input that does not match with the
                        original input of the model.
  --reverse_input_channels
                        Switch the input channels order from RGB to BGR (or
                        vice versa). Applied to original inputs of the model
                        if and only if a number of channels equals 3. Applied
                        after application of --mean_values and --scale_values
                        options, so numbers in --mean_values and
                        --scale_values go in the order of channels used in the
                        original model.
  --log_level {CRITICAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}
                        Logger level
  --input INPUT         The name of the input operation of the given model.
                        Usually this is a name of the input placeholder of the
                        model.
  --output OUTPUT       The name of the output operation of the model. For
                        TensorFlow*, do not add :0 to this name.
  --mean_values MEAN_VALUES, -ms MEAN_VALUES
                        Mean values to be used for the input image per
                        channel. Values to be provided in the (R,G,B) or
                        [R,G,B] format. Can be defined for desired input of
                        the model, for example: "--mean_values
                        data[255,255,255],info[255,255,255]". The exact
                        meaning and order of channels depend on how the
                        original model was trained.
  --scale_values SCALE_VALUES
                        Scale values to be used for the input image per
                        channel. Values are provided in the (R,G,B) or [R,G,B]
                        format. Can be defined for desired input of the model,
                        for example: "--scale_values
                        data[255,255,255],info[255,255,255]". The exact
                        meaning and order of channels depend on how the
                        original model was trained.
  --data_type {FP16,FP32,half,float}
                        Data type for all intermediate tensors and weights. If
                        original model is in FP32 and --data_type=FP16 is
                        specified, all model weights and biases are quantized
                        to FP16.
  --disable_fusing      Turn off fusing of linear operations to Convolution
  --disable_resnet_optimization
                        Turn off resnet optimization
  --finegrain_fusing FINEGRAIN_FUSING
                        Regex for layers/operations that won't be fused.
                        Example: --finegrain_fusing Convolution1,.*Scale.*
  --disable_gfusing     Turn off fusing of grouped convolutions
  --move_to_preprocess  Move mean values to IR preprocess section
  --extensions EXTENSIONS
                        Directory or a comma separated list of directories
                        with extensions. To disable all extensions including
                        those that are placed at the default location, pass an
                        empty string.
  --batch BATCH, -b BATCH
                        Input batch size
  --version             Version of Model Optimizer
  --silent              Prevent any output messages except those that
                        correspond to log level equals ERROR, that can be set
                        with the following option: --log_level. By default,
                        log level is already ERROR.
  --freeze_placeholder_with_value FREEZE_PLACEHOLDER_WITH_VALUE
                        Replaces input layer with constant node with provided
                        value, e.g.: "node_name->True"
  --generate_deprecated_IR_V2
                        Force to generate legacy/deprecated IR V2 to work with
                        previous versions of the Inference Engine. The
                        resulting IR may or may not be correctly loaded by
                        Inference Engine API (including the most recent and
                        old versions of Inference Engine) and provided as a
                        partially-validated backup option for specific
                        deployment scenarios. Use it at your own discretion.
                        By default, without this option, the Model Optimizer
                        generates IR V3.

注意: 模型优化器默认不会像 2017 R3 Beta 版本那样将输入通道从 RGB 转换为 BGR。必须手动指定命令行参数 --reverse_input_channels 来执行转换。有关详细信息,请参阅 何时反转输入通道 章节。

以下各节详细介绍了特定参数的使用以及命令行示例。

何时指定均值和缩放值

通常,神经网络模型是在归一化输入数据的情况下训练的。这意味着输入数据的数值被转换为特定的范围,例如 [0, 1][-1, 1]。有时,在预处理过程中,会从输入数据值中减去均值(均值图像)。输入数据预处理的实现有两种情况:

  • 输入预处理操作是拓扑的一部分。在这种情况下,使用该框架推断拓扑的应用程序不会预处理输入。
  • 输入预处理操作不是拓扑的一部分,并且预处理是在向模型提供输入数据的应用程序中执行的。

在第一种情况下,模型优化器会生成带有必需的预处理层的 IR,并且可以使用推理引擎示例来推断模型。

在第二种情况下,应将均值/缩放值的信息提供给模型优化器,以便将其嵌入生成的 IR 中。模型优化器提供了一些命令行参数来指定它们:--scale--scale_values--mean_values--mean_file

如果同时指定了均值和缩放值,则先减去均值,然后再应用缩放。输入值将乘以缩放值。

没有一个通用的方法来确定特定模型的均值/缩放值。以下步骤有助于确定它们:

  1. 阅读模型文档。通常,如果需要预处理,文档会描述均值/缩放值。
  2. 打开执行模型的示例脚本/应用程序,并跟踪如何读取输入数据并将其传递给框架。
  3. 在可视化工具中打开模型,并检查执行减法或乘法的层(例如 SubMulScaleShiftEltwise 等)。如果存在这些层,则预处理很可能是模型的一部分。

何时指定输入形状

在某些情况下,模型的输入数据形状不是固定的,例如全卷积神经网络。在这种情况下,例如,TensorFlow* 模型会在 Placeholder 操作的 shape 属性中包含 -1 值。推理引擎不支持具有未定义大小的输入层,因此如果模型中未定义输入形状,模型优化器将无法转换模型。

解决方案是使用 --input_shape 命令行参数为模型的所有输入提供输入形状,或者如果模型只有一个输入且仅未定义批次大小,则使用 -b 命令行参数提供批次大小。在后一种情况下,TensorFlow* 模型的 Placeholder 形状如下所示:[-1, 224, 224, 3]

何时反转输入通道

推理引擎示例以 BGR 通道顺序加载输入图像。但模型可能是在 RGB 通道顺序加载的图像上训练的。在这种情况下,使用推理引擎示例的推理结果将不正确。解决方案是提供 --reverse_input_channels 命令行参数。然后,模型优化器会修改第一个卷积或其他依赖于通道的操作权重,使其输出就像图像是以 RGB 通道顺序传入一样。

使用框架无关参数的命令行界面 (CLI) 示例

  • 以调试日志级别启动模型优化器,用于 <model>.params:用于更好地了解模型转换内部发生的情况。
    python3 mo_mxnet.py --input_model <model>.params --log_level DEBUG
  • 启动模型优化器,用于 <model>.params,并将输出的中间表示称为 result.xmlresult.bin,它们位于指定的 ../../models/ 目录中。
    python3 mo_mxnet.py --input_model <model>.params --model_name result --output_dir ../../models/
  • 启动模型优化器,用于 <model>.params,并为单个输入提供缩放值。
    python3 mo_mxnet.py --input_model <model>.params --scale_values [59,59,59]
  • 启动模型优化器,用于 model.params,该模型有两个输入,每个输入都有两组缩放值。缩放/均值值的集合数量应与给定模型的输入数量完全相同。
    python3 mo_mxnet.py --input_model <model>.params --input data,rois --scale_values [59,59,59],[5,5,5]
  • 启动模型优化器,用于 <model>.params,并指定输入层(data),将输入层的形状更改为 [1,3,224,224],并指定输出层的名称。
    python3 mo_mxet.py --input_model <model>.params --input data --input_shape [1,3,224,224] --output pool5
  • 启动模型优化器,用于 <model>.params,禁用与卷积的线性运算的融合,通过 --disable_fusing 标志设置,并禁用分组卷积,通过 --disable_gfusing 标志设置。
    python3 mo_mxnet.py --input_model <model>.params --disable_fusing --disable_gfusing
  • 启动模型优化器,用于 <model>.params,反转 RGB 和 BGR 之间的通道顺序,指定输入的均值,并将中间表示的精度设置为 FP16
    python3 mo_mxnet.py --input_model <model>.params --reverse_input_channels --mean_values [255,255,255] --data_type FP16
  • 启动模型优化器,用于 <model>.params,并使用指定目录中的扩展。特别是,来自 /home//home/some/other/path
    此外,以下命令显示了如何将均值文件传递到中间表示。均值文件必须是 binaryproto 格式。
    python3 mo_mxnet.py --input_model <model>.params --extensions /home/,/some/other/path/ --mean_file mean_file.binaryproto

使用 MXNet* 特定转换参数

以下列表提供了 MXNet* 特定参数。

MXNet-specific parameters:
  --input_symbol <symbol_file_name>
                        Symbol file (for example, "model-symbol.json") that contains a topology structure and layer attributes
  --nd_prefix_name <nd_prefix_name>
                        Prefix name for args.nd and argx.nd files
  --pretrained_model_name <pretrained_model_name>
                        Name of a pretrained MXNet model without extension and epoch number. This model will be merged with args.nd and argx.nd files
  --save_params_from_nd
                        Enable saving built parameters file from .nd files
  --legacy_mxnet_model
                        Enable MXNet loader to make a model compatible with the latest MXNet version. Use only if your model was trained with MXNet version lower than 1.0.0

注意:默认情况下,模型优化器不使用 MXNet 加载器,因为它将拓扑转换为另一种格式,该格式与最新版本的 MXNet 兼容,但对于使用较低版本 MXNet 训练的模型是必需的。如果您的模型是用低于 1.0.0 的 MXNet 版本训练的,请指定 --legacy_mxnet_model 键来启用 MXNet 加载器。但是,该加载器不支持带有自定义层的模型。在这种情况下,您必须手动重新编译 MXNet 并安装到您的环境中。

从 MXNet* 转换样式迁移模型

本教程解释了如何使用公共 MXNet* 神经样式迁移示例生成样式迁移模型。要使用 Intel® Distribution of OpenVINO™ toolkit 中的样式迁移示例,请按照以下步骤操作,因为 Intel Distribution of OpenVINO toolkit 未提供公共预训练的样式迁移模型。

  1. 下载或克隆带有 MXNet 神经样式迁移示例的存储库:Zhaw 的神经样式迁移存储库
  2. 准备使用克隆的存储库所需的环境。
    1. 安装包依赖项。
      sudo apt-get install python-tk
    2. 安装 Python* 要求。
      pip3 install --user mxnet
      pip3 install --user matplotlib
      pip3 install --user scikit-image
  3. 下载预训练的 VGG19 模型,并将其保存在克隆存储库的根目录中,因为示例期望模型 vgg19.params 文件位于该目录中。
  4. 修改克隆存储库中样式迁移示例的源代码文件。
    1. 转到 fast_mrf_cnn 子目录。
      cd ./fast_mrf_cnn
    2. 打开 symbol.py 文件并修改 decoder_symbol() 函数。替换
      def decoder_symbol():
      data = mx.sym.Variable('data')
      data = mx.sym.Convolution(data=data, num_filter=256, kernel=(3,3), pad=(1,1), stride=(1, 1), name='deco_conv1')

      为以下代码:

      def decoder_symbol_with_vgg(vgg_symbol):
      data = mx.sym.Convolution(data=vgg_symbol, num_filter=256, kernel=(3,3), pad=(1,1), stride=(1, 1), name='deco_conv1')
    3. 保存并关闭 symbol.py 文件。
    4. 打开并编辑 make_image.py 文件:修改 Maker 类中的 __init__() 函数。替换
      decoder = symbol.decoder_symbol()

      为以下代码:

      decoder = symbol.decoder_symbol_with_vgg(vgg_symbol)
    5. 要将预训练权重与解码器权重合并,请进行以下更改:在加载解码器权重后
      args = mx.nd.load('%s_decoder_args.nd'%model_prefix)
      auxs = mx.nd.load('%s_decoder_auxs.nd'%model_prefix)

      添加以下行:

      arg_dict.update(args)
    6. args 作为参数传递给 decoder.bind() 函数,改用 arg_dict。替换该行:
      self.deco_executor = decoder.bind(ctx=mx.cpu(), args=args, aux_states=auxs)

      为以下内容:

      self.deco_executor = decoder.bind(ctx=mx.cpu(), args=arg_dict, aux_states=auxs)
    7. decoder.bind() 函数中的所有 mx.gpu 替换为 mx.cpu
    8. 要将结果模型保存为 .json 文件,请将以下代码添加到 Maker 类中的 generate() 函数的末尾:
      self.vgg_executor._symbol.save('{}-symbol.json'.format('vgg19'))
      self.deco_executor._symbol.save('{}-symbol.json'.format('nst_vgg19'))
    9. 保存并关闭 make_image.py 文件。
  5. 根据克隆存储库中 README.md 文件中的说明,运行带有解码器模型的示例。

    例如,要运行带有 models 文件夹中预训练解码器权重的示例并指定输出形状,请使用以下代码:

    import make_image
    maker = make_image.Maker('models/13', (1024, 768))
    maker.generate('output.jpg', '../images/tubingen.jpg')

    其中 'models/13' 字符串由以下子字符串组成:

    • 'models/' - 包含预训练样式权重 .nd 文件的文件夹路径,以及 '13'
    • 解码器前缀:存储库包含一个默认解码器,即 13_decoder

    您可以从 预训练权重集合 中选择任何样式。generate() 函数为指定的形状生成 nst_vgg19-symbol.jsonvgg19-symbol.json 文件。在代码中,对于 4:3 的比例是 [1024 x 768],您可以指定其他值,例如,对于正方形比例是 [224,224]。

  6. 运行模型优化器以生成中间表示 (IR)。
    1. 创建一个新目录。例如:
      mkdir nst_model
    2. 将初始和生成的模型文件复制到创建的目录。例如,要将预训练解码器权重从 models 文件夹复制到 nst_model 目录,请运行以下命令:
      cp nst_vgg19-symbol.json nst_model
      cp vgg19-symbol.json nst_model
      cp ../vgg19.params nst_model/vgg19-0000.params
      cp models/13_decoder_args.nd nst_model
      cp models/13_decoder_auxs.nd nst_model

      注意:确保所有 .params.json 文件与 .nd 文件位于同一目录中。否则,转换过程将失败。

    3. 运行 MXNet 的模型优化器。使用 --nd_prefix_name 选项指定解码器前缀,并使用 --input_shape 以 [N,C,W,H] 顺序指定输入形状。例如:
      python3 mo.py --input_symbol <path/to/nst_model>/nst_vgg19-symbol.json --framework mxnet --output_dir <path/to/output_dir> --input_shape [1,3,224,224] --nd_prefix_name 13_decoder --pretrained_model <path/to/nst_model>/vgg19-0000.params
    4. IR 已生成(.bin.xml.mapping 文件),位于指定的输出目录中,可供推理引擎使用。

支持的层及其到中间表示层的映射

数字 MXNet* 中的符号名称 中间表示中的层名称
1 BatchNorm BatchNormalization
2 裁剪 裁剪
3 ScaleShift ScaleShift
4 池化 池化
5 SoftmaxOutput SoftMax
6 SoftmaxActivation SoftMax
7 null 已忽略,不会出现在 IR 中
8 卷积 卷积
9 反卷积 反卷积
10 Activation(act_type = relu) ReLU
11 ReLU ReLU
12 LeakyReLU ReLU (negative_slope = 0.25)
13 Concat Concat
14 elemwise_add Eltwise(operation = sum)
15 _Plus Eltwise(operation = sum)
16 Flatten Flatten
17 Reshape Reshape
18 FullyConnected FullyConnected
19 UpSampling Resample
20 transpose Permute
21 LRN Norm
22 L2Normalization Normalize
23 Dropout 已忽略,不会出现在 IR 中
24 _copy 已忽略,不会出现在 IR 中
25 _contrib_MultiBoxPrior PriorBox
26 _contrib_MultiBoxDetection DetectionOutput
27 broadcast_mul ScaleShift
28 sigmoid sigmoid
29 Activation (act_type = tanh) Activation (operation = tanh)
30 LeakyReLU (act_type = prelu) PReLU
31 LeakyReLU (act_type = elu) Activation (operation = elu)
32 elemwise_mul Eltwise (operation = mul)
33 add_n
Eltwise (operation = sum)
34

ElementWiseSum

Eltwise (operation = sum)
35 _mul_scalar
36 broadcast_add Eltwise (operation = sum)
37 slice_axis 裁剪
38 自定义 请参阅 模型优化器中的自定义层
39 _minus_scalar
40 Pad 池化
41 _contrib_Proposal 提案
42 ROIPooling ROIPooling

带有自定义层的 MXNet* 模型

在内部,当您运行模型优化器时,它会加载模型,遍历拓扑,并尝试在已知层列表中查找每种层类型。自定义层是指未包含在已知层列表中的层。如果您的拓扑包含此列表中未知的任何层,模型优化器会将其归类为自定义层。

要了解如何从 MXNet* 模型创建扩展或自定义层,请参阅模型优化器开发者指南中的 带有自定义层的 MXNet* 模型 部分。

常见问题解答 (FAQ)

如果模型优化器由于拼写错误、选项使用不当或其他问题而无法成功运行,它会提供解释性消息。该消息描述了问题的可能原因,并提供指向 模型优化器 FAQ 的链接。FAQ 提供了解决大多数问题的说明。FAQ 还包含指向模型优化器开发者指南中相关部分的链接,以帮助您理解问题所在。

摘要

在本文件中,您了解了:

  • 关于模型优化器如何处理 MXNet* 模型的基本信息。
  • 哪些 MXNet* 模型受支持。
  • 如何使用框架无关和 MXNet 特定命令行选项的模型优化器来转换已训练的 MXNet* 模型。

法律信息

您不得在涉及此处描述的 Intel 产品侵权或其他法律分析时使用或协助使用本文档。您同意授予 Intel 对之后起草的包含此处披露的主题内容的任何专利声明非排他性、免版税的许可。

本文档不授予任何知识产权的许可(明示或暗示,禁止反言或以其他方式)。

此处提供的所有信息如有更改,恕不另行通知。请联系您的Intel代表以获取最新的Intel产品规格和路线图。

描述的产品可能包含设计缺陷或称为errata的错误,这些错误可能导致产品偏离已发布的规格。当前已确定特征的errata可根据要求提供。

Intel技术的特性和优势取决于系统配置,并可能需要启用硬件、软件或服务激活。了解更多信息,请访问http://www.intel.com/或联系OEM或零售商。

没有计算机系统可以绝对安全。

Intel、Arria、Core、Movidia、Pentium、Xeon 和 Intel 徽标是 Intel Corporation 在美国和/或其他国家的商标。

OpenCL 和 OpenCL 徽标是 Apple Inc. 的商标,已获得 Khronos 的许可使用。

*其他名称和品牌可能被声明为他人的财产。

版权所有 © 2018,Intel Corporation。保留所有权利。

© . All rights reserved.