ONNX 现场演示教程

译者:冯宝宝

本教程将向您展示如何使用ONNX将已从PyTorch导出的神经模型传输模型转换为Apple CoreML格式。这将允许您在Apple设备上轻松运行深度学习模型,在这种情况下,可以从摄像机直播演示。

什么是ONNX

ONNX(开放式神经网络交换)是一种表示深度学习模型的开放格式。借助ONNX,AI开发人员可以更轻松地在最先进的工具之间移动模型,并选择最适合它们的组合。ONNX由合作伙伴社区开发和支持。 您可以访问 onnx.ai,了解有关ONNX的更多信息以及支持的工具。

教程预览

本教程将带你走过如下主要4步:

  1. 下载(或训练)Pytorch风格装换模型
  2. 将PyTorch模型转换至ONNX模型
  3. 将ONNX模型转换至CoreML模型
  4. 在支持风格转换iOS App中运行CoreML模型

环境准备

我们将在虚拟环境工作,以避免与您的本地环境冲突。在本教程中使用Python 3.6,但其他版本也应该可以正常工作。

  1. python3.6 -m venv venv
  2. source ./venv/bin/activate

我们需要安装Pytorch和 onnx->coreml 转换器:

  1. pip install torchvision onnx-coreml

如果要在iPhone上运行iOS样式传输应用程序,还需要安装XCode。您也可以在Linux中转换模型,但要运行iOS应用程序本身,您将需要一台Mac。

下载(或训练)Pytorch风格装换模型

在本教程中,我们将使用与pytorch一起发布的样式传输模型,地址为https://github.com/pytorch/examples/tree/master/fast_neural_style。如果您想使用其他PyTorch或ONNX模型,请随意跳过此步骤。

这些模型用于在静态图像上应用样式传输,并且实际上没有针对视频进行优化以获得足够快的速度。但是,如果我们将分辨率降低到足够低,它们也可以很好地处理视频。

我们先下载模型:

  1. git clone https://github.com/pytorch/examples
  2. cd examples/fast_neural_style

如果您想自己训练模型,您刚刚克隆下载的的pytorch/examples存储库有更多关于如何执行此操作的信息。目前,我们只需使用存储库提供的脚本下载预先训练的模型:

  1. ./download_saved_models.sh

此脚本下载预先训练的PyTorch模型并将它们放入saved_models文件夹中。 你的目录中现在应该有4个文件,candy.pth,mosaic.pth,rain_princess.pth和udnie.pth。

将PyTorch模型转换至ONNX模型

现在我们已将预先训练好的PyTorch模型作为saved_models文件夹中的.pth文件,我们需要将它们转换为ONNX格式。模型定义在我们之前克隆的pytorch/examples存储库中,通过几行python我们可以将它导出到ONNX。在这种情况下,我们将调用torch.onnx._export而不是实际运行神经网络,它将PyTorch作为api提供,以直接从PyTorch导出ONNX格式的模型。但是,在这种情况下,我们甚至不需要这样做,因为脚本已经存在Neural_style / neural_style.py,它将为我们执行此操作。如果要将其应用于其他模型,也可以查看该脚本。

从PyTorch导出ONNX格式本质上是追踪您的神经网络,因此这个api调用将在内部运行网络“虚拟数据”以生成图形。为此,它需要输入图像来应用样式转移,其可以简单地是空白图像。但是,此图像的像素大小很重要,因为这将是导出的样式传输模型的大小。为了获得良好的性能,我们将使用250x540的分辨率。如果您不太关心FPS,可以随意采取更大的分辨率,更多关于风格转移质量。

让我们使用ImageMagick创建我们想要的分辨率的空白图像:

  1. convert -size 250x540 xc:white png24:dummy.jpg

然后用它来导出PyTorch模型用它来导出PyTorch模型:

  1. python ./neural_style/neural_style.py eval --content-image dummy.jpg --output-image dummy-out.jpg --model ./saved_models/candy.pth --cuda 0 --export_onnx ./saved_models/candy.onnx
  2. python ./neural_style/neural_style.py eval --content-image dummy.jpg --output-image dummy-out.jpg --model ./saved_models/udnie.pth --cuda 0 --export_onnx ./saved_models/udnie.onnx
  3. python ./neural_style/neural_style.py eval --content-image dummy.jpg --output-image dummy-out.jpg --model ./saved_models/rain_princess.pth --cuda 0 --export_onnx ./saved_models/rain_princess.onnx
  4. python ./neural_style/neural_style.py eval --content-image dummy.jpg --output-image dummy-out.jpg --model ./saved_models/mosaic.pth --cuda 0 --export_onnx ./saved_models/mosaic.onnx

你应该得到4个文件,candy.onnxmosaic.onnxrain_princess.onnxudnie.onnx,由相应的.pth文件创建。

将ONNX模型转换至CoreML模型

现在我们有了ONNX模型,我们可以将它们转换为CoreML模型,以便在Apple设备上运行它们。为此,我们使用之前安装的onnx-coreml转换器。转换器附带一个convert-onnx-to-coreml脚本,上面的安装步骤添加到我们的路径中。遗憾的是,这对我们不起作用,因为我们需要将网络的输入和输出标记为图像,并且虽然这是转换器支持的,但只有在从python调用转换器时才支持它。

通过查看样式传输模型(例如在像Netron这样的应用程序中打开.onnx文件),我们看到输入名为’0’,输出名为’186’。这些只是PyTorch分配的数字ID。我们需要将它们标记为图像。

所以让我们创建一个python小文件并将其命名为onnx_to_coreml.py。这可以通过使用touch命令创建,并使用您喜欢的编辑器进行编辑,以添加以下代码行。

  1. import sys
  2. from onnx import onnx_pb
  3. from onnx_coreml import convert
  4. model_in = sys.argv[1]
  5. model_out = sys.argv[2]
  6. model_file = open(model_in, 'rb')
  7. model_proto = onnx_pb.ModelProto()
  8. model_proto.ParseFromString(model_file.read())
  9. coreml_model = convert(model_proto, image_input_names=['0'], image_output_names=['186'])
  10. coreml_model.save(model_out)

现在来运行:

  1. python onnx_to_coreml.py ./saved_models/candy.onnx ./saved_models/candy.mlmodel
  2. python onnx_to_coreml.py ./saved_models/udnie.onnx ./saved_models/udnie.mlmodel
  3. python onnx_to_coreml.py ./saved_models/rain_princess.onnx ./saved_models/rain_princess.mlmodel
  4. python onnx_to_coreml.py ./saved_models/mosaic.onnx ./saved_models/mosaic.mlmodel

现在,您的saved_models目录中应该有4个CoreML模型:candy.mlmodel,mosaic.mlmodel,rain_princess.mlmodel和udnie.mlmodel。

在支持风格转换iOS App中运行CoreML模型

此存储库(即您当前正在阅读README.md的存储库)包含一个iOS应用程序,可以在手机摄像头的实时摄像头流上运行CoreML样式传输模型。

  1. git clone https://github.com/onnx/tutorials

并在XCode中打开tutorials/examples/CoreML/NNXLive/ONNXLive.xcodeproj项目。我们建议使用XCode 9.3和iPhone X。在旧设备或XCode版本上可能会出现问题。

在Models/文件夹中,项目包含一些.mlmodel文件。我们将用我们刚刚创建的模型替换它们。

然后你在iPhone上运行应用程序就可以了。点击屏幕可切换模型。

结论

我们希望本教程能够概述ONNX的内容以及如何使用它来在框架之间转换神经网络,在这种情况下,神经风格的传输模型从PyTorch转移到CoreML。

您可以随意尝试这些步骤并在自己的模型上进行测试。如果您遇到任何问题或想要提供反馈,请告诉我们。我们倾听你的想法。