前言
在人工智能领域中,深度学习模型的训练和部署是非常重要的环节。而ONNX是一种开放的深度学习模型表示格式,可以让不同的深度学习框架之间进行模型的转换和共享。而ONNX-Modifier则是一个能够对ONNX模型进行修改的工具,可以对模型进行简化、优化等操作,以达到更好的性能和效果。在本篇博客中,我们将详细介绍ONNX-Modifier的使用方法和优势。
安装
源码+命令行启动
- 拉取
onnx-modifier
,安装所需要的Python库 - bash
- 复制代码
git clone git@github.com:ZhangGe6/onnx-modifier.git cd onnx-modifier pip install onnx flask
- 运行
- 复制代码
python app.py
从可执行文件启动
- Windows: 下载可执行文件onnx-modifier.exe (27.6MB) Google Drive / Baidu NetDisk,双击即可启动。
- 默认使用Edge浏览器作为运行环境。
生成可执行文件的步骤记录在
app_desktop.py
文件中。未来会为其他平台生成可执行文件。
点击输出中的url(默认为http://127.0.0.1:5000/
),即可在浏览器中进入onnx-modifier界面。点击Open Model...
,上传所需要编辑的模型文件,上传完毕后,网络可视化结构会自动显示。
目前已支持下列操作:
✅ 删除/恢复节点
✅ 修改节点输入输出名
✅ 修改模型输入输出名
✅ 增加模型输出节点
✅ 编辑节点属性值
✅ 增加新节点
✅ 修改模型batch size
✅ 修改模型initializers
实操
我们采用从可执行文件启动方式为例子,为大家逐一介绍如何进行实操。这里我们使用一个随意的onnx文件导入到onnx-modifier中:
删除/恢复节点
删除节点有两种模式:Delete With Children
和 Delete Single Node
. 后者只删除当前单个节点;而前者还会自动删除以这个节点为根节点的所有子节点,当我们需要删除一长串节点时,这个功能会比较有用。
Delete With Children
基于回溯算法实现。
执行删除操作后,被删除的节点首先会变灰显示,以供预览。如果某一个节点被误删了,在该节点的侧边栏点击Recover Node
即可以将其恢复到图中。预览确认删除操作无误后,点击Enter
,图结构会刷新,显示节点删除后的状态。
例如我们需要删除第一个sigmoid节点:
修改节点输入输出名
通过修改节点的输出输出名,我们可以对模型拓扑结构进行修改(如删除一些预处理/后处理节点)。该功能同样可以用在更改模型的输出的名称(即修改模型叶子节点的输出名)。
那在onnx-modifer
中要怎么做呢?很简单,找到节点侧边栏的输入输出对应的输入框,键入新的名称就可以啦。图结构会根据键入的名称即时自动刷新。
举个栗子,在下图所示的模型中,我们想要删除预处理对应的节点(Sub->Mul->Sub->Transpose
),可以这样做:
- 点击第一个
Conv
节点,在弹出的属性栏中,将输入名称改为serving_default_input:0 (data_0
节点的输出名); - 图结构自动刷新,可以发现,输入节点已经和第一个
Conv
节点直接相连,几个预处理节点也已经从前向图中分离出来,将它们删除; - 完工(点击
Download
就可以获得编辑后的ONNX模型啦)。
如果我们希望通过修改,让节点AAA(比如上例中的
data_0
节点)连向节点BBB(比如上例中的第一个Conv
节点),建议的方式是:将节点BBB的输入名称修改为节点AAA的输出名称,而不是把AAA的输出名称修改为节点BBB的输入名称。 因为节点BBB的输入名称可能同时为其他节点(比如上例中的Transpose
节点)的输出名称,会导致一些预料外的结果。
上例的修改过程如下图所示:
修改模型输入输出名称
点击模型输入或输出节点,在弹出的侧边栏中,为模型输入输出键入新的名称即可。
增加模型输出节点
有时候我们需要增加/抽取某个特定节点的输出作为整个模型的输出。比如之前的模型输出节点在编辑过程中被删除了,需要增加新的,或者有时候我们需要抽取一些中间层特征输出做更细致的分析。
通过onnx-modifier
,我们只需要在对应节点的侧边栏中,点击Add Output
按钮即可在该节点后部增加一个模型输出节点,其名称与原节点的输出名相同。
如下图,我们增加了两个模型输出节点,分别为第一个卷积层的输出和第二个卷积层的输出。
编辑节点属性值
在节点侧边栏对应的属性值输入框中,键入新的属性值即可。
点击属性值输入框右侧的
+
,可显示该属性的参考信息。
增加新节点
有时候我们希望向模型中添加新节点。onnx-modifier
已开始支持该功能。
在主页面的左上方,有一个Add node
按钮和一个selector选择器,我们可以通过这二者的配合,完成节点的添加,只需3步:
- 在selector中选择要添加的节点类型,在点击
Add node
按钮后,一个对应类型的新节点将自动出现在图上。
selector中包含来自
ai.onnx
(171),ai.onnx.preview.training
(4),ai.onnx.ml
(18) 和com.microsoft
(1)的所有节点类型。
- 点击这个新节点,在弹出的侧边栏中进行节点的编辑:
- 节点属性:初始化为
null
(显示为undefined
)。同上节,在对应的属性框中输入新值即可。 - 修改节点输入输出名。输入输出名决定了节点将插入在图结构中的位置。
- 完工(点击
Download
即可获得编辑后的ONNX模型)。
以下是该功能的一些提醒和小tip:
- 点击节点侧边栏的
NODE PROPERTIES
的type
框右侧的?
,和节点属性框右侧的+
,可以显示关于当前节点类型/属性值的参考信息。 - 为确保正确性,节点的各属性值建议全部填写(而不是留着
undefined
)。默认值在当前版本可能支持得还不够好。 - 如果一个属性值是列表类型,则各元素之间使用‘
,
’分隔,无需'[]'。 - 在当前版本中,如果一个节点的输入/输出是一个列表类型(如
Concat
),限制最多显示8个。如果一个节点实际输入/输出小于8个,则填写对应数目的输入输出即可,多出来的应以list_custom
开头,它们会在后续处理中自动被忽略。
修改模型batch size
动态batch size和固定batch size均已支持。
- 动态batch size:点击
Dynamic batch size
即可; - 动态bacth size:在
Fixed batch size
后方输入框内填入预期的batch size值;
修改模型initializers
有时候我们要修改一些保存在模型initializer中的数值,比如卷积层的权重/偏置参数,Reshape
节点的shape
参数等。使用onnx-modifier
,这一操作将非常简单:在对应节点侧边栏的initializer中键入新的数值,点击Download
即可。
如果要修改我们新增加的节点的initializer,除了键入其数值之外,还要键入其数据类型。(如果我们不确定数据类型,可以点击
NODE PROPERTIES->type->?
,在弹出的节点的详细介绍界面中,可能会找到线索。)
参考资料
- Netron
- Flask
- ONNX IR Official doc
- ONNX Python API Official doc, Leimao's Blog
- ONNX IO Stream Leimao's Blog
- onnx-utils
- sweetalert