前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用netron对mnist网络结构分析「建议收藏」

使用netron对mnist网络结构分析「建议收藏」

作者头像
全栈程序员站长
发布2022-11-01 16:34:11
8650
发布2022-11-01 16:34:11
举报
文章被收录于专栏:全栈程序员必看

基于libonnx环境简要分析一下mnist网络算子结构,关于环境搭建可以参考前面两篇文章:

xboot大神的libonnx环境搭建

使用netron实现对onnx模型结构可视化


本文主要目的是搞清楚mnist各层之间数据shape的变化情况,关于什么是shape,引用一本书中的介绍:

“在tensorflow中,使用张量来表示计算图中的所有数据,张量在计算图的节点之间流动,张量可以看成N维数组,而数组的维数就是张量的阶数。因此,0阶张量对应标量数据,1阶张量对应一维数组,也就是向量。二阶张量对应二维数组,也就是矩阵,以此类推,N阶张量对应n维数组,例如,一张RGB图像可以表示为3阶张量,而多张RGB图构成的数据可以表示为4阶张量。shape(形状)代表的就是张量的一种属性,当然还有其他属性,比如数据类型等等”

再算子执行前面打断点,依次观察输入数据和输出数据的大小:

代码语言:javascript
复制
(gdb) b 2124
Breakpoint 2 at 0x555555560ef8: file onnx.c, line 2124.
(gdb) display n->inputs[0]->ndata
(gdb) display n->outputs[0]->ndata
(gdb) c
Continuing.
代码语言:javascript
复制
Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 2560
2: n->outputs[0]->ndata = 2560
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 784
2: n->outputs[0]->ndata = 6272
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 6272
2: n->outputs[0]->ndata = 6272
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 6272
2: n->outputs[0]->ndata = 6272
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 6272
2: n->outputs[0]->ndata = 1568
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 1568
2: n->outputs[0]->ndata = 3136
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 3136
2: n->outputs[0]->ndata = 3136
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 3136
2: n->outputs[0]->ndata = 3136
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 3136
2: n->outputs[0]->ndata = 256
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 256
2: n->outputs[0]->ndata = 256
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 256
2: n->outputs[0]->ndata = 10
(gdb) c
Continuing.

Breakpoint 2, onnx_run (ctx=0x555555a501e0) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 10
2: n->outputs[0]->ndata = 10
(gdb) c
Continuing.

可以看出一个简单的规律,就是前一级网络的输出size等于后一级网络的输入size.

对照网络,可以完全对应的上:

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

将shape打印出(由dims表示),可以看出和上图完全吻合。(图中一维向量表示为1*N,也看成2维的shape).

代码语言:javascript
复制
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 2560
2: n->outputs[0]->ndata = 2560
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 2
(gdb) c
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 784
2: n->outputs[0]->ndata = 6272
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) c
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 6272
2: n->outputs[0]->ndata = 6272
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) c
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 6272
2: n->outputs[0]->ndata = 6272
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) c
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 6272
2: n->outputs[0]->ndata = 1568
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) c
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 1568
2: n->outputs[0]->ndata = 3136
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) 
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 3136
2: n->outputs[0]->ndata = 3136
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) 
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 3136
2: n->outputs[0]->ndata = 3136
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) 
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 3136
2: n->outputs[0]->ndata = 256
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 4
(gdb) 
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 256
2: n->outputs[0]->ndata = 256
3: n->inputs[0]->ndim = 4
4: n->outputs[0]->ndim = 2
(gdb) 
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 256
2: n->outputs[0]->ndata = 10
3: n->inputs[0]->ndim = 2
4: n->outputs[0]->ndim = 2
(gdb) 
Continuing.
Breakpoint 3, onnx_run (ctx=0x5555559ff250) at onnx.c:2124
2124					n->operator(n);
1: n->inputs[0]->ndata = 10
2: n->outputs[0]->ndata = 10
3: n->inputs[0]->ndim = 2
4: n->outputs[0]->ndim = 2
(gdb) 
Continuing.

然后再以ndim为上限,索引dims,还是以reshape为例:

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

可以看出和netron解析的图中reshape模块的shape完全吻合:

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

darknet网络举例:

netron不但可以解析onnx格式的模型文件,还支持darknet中 .cfg格式的文件,比如:

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

不过貌似N,C,W,H的排列有所差别,在上面mnist网络中,顺序是,个数X通道数X长度X高度

而darknet的cfg中,对于输出数据,是WxHxC的方式,也即是宽X长X通道号,但是对于每个算子节点,则是CXNXWXH的方式,也即是通道数在前,之后依次是个数,宽和长. N是batch size.

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

从最后一层的模型看不出它的结构,实际上它是一个全连接层:

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

这一点可以通过芯原的模型转换工具的转换结果看出来,芯原的转换工具,可以将ONNX模型转换为芯原NPU吃的json文件模型,而netron是支持此类型的可视化输出的。

以下模型是和上图同一个模型文件,转换为芯原格式的JSON模型文件后,通过NETRON分析得到的网络模型结构,可以看到,最后一层是全连接。

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

lenet 模型都需要对吃进去的图像做数据归一化,libonnx实现也不例外

使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」
使用netron对mnist网络结构分析「建议收藏」

结束!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/179595.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结束!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档