做个游戏吧?玩儿转Mnn模型存储结构!

1 倡导

我们来做个游戏吧,游戏内容是:
MNN二进制模型文件 中找到我们想要的 目标数据

游戏的部分基础信息可以在 这篇文章 中找到一二。

2 游戏说明

2.1 我们有 mnn模型文件 的信息

一个简单的 Conv + Conv + Relu 三层网络,其全部内容如下图:

游戏模型文件 json信息

2.2 我们有 mnn模型文件 的二进制信息

左边第一列为我加的索引列,二进制信息统一使用16进制打印,即一个数字是8位即一个字节

游戏模型文件 二进制信息

2.3 游戏目标

2.2 的 二进制信息 中找到 2.1 中json信息 目标字段的存储位置。

举例:
2.1 图中倒数第二行的 "0",在 2.2 图中对应 02行的 第6组 开始的五个字节 : 01 00 00 00 30
2.1 图中倒数第二行的 "5",在 2.2 图中对应 02行的 第4组 开始的五个字节 : 01 00 00 00 35

举例说明

有趣么?马上开始我们的游戏

3 带你玩

3.1 Mission 1 : 找到 tensorName "0"、"5"、"6"

056

3.1.1 找到MNN:Net 的数据起点

MNN 的二进制模型文件 的前四个字节是 根节点的偏移,它指向一个 继承于 flatbuffers::Table 名为 MNN::Net 数据结构

寻找MNN::Net结构内存起点

0x0000001C = 28
为什么是 0x0000001C,而不是0x1C000000呢?因为 小端模式
28位置 即 MNN::Net 结构的数据内存数据起点位置

3.1.2 寻找 字符串指针数组 的数据起点

MNN::Net 有一个tensorName的属性,即为我们的目标,
它是一个 字符串指针的数组(Vector<flatbuffers::Offset<flatbuffers::String>>)
让我们找打它!

寻找 字符串指针数组 的数据起点

3.1.1 节我们得到了位置28,那么:

  • 28位置信息为 0x00000016 = 22,代表 28位置之前的22个字节 均为MNN::Net属性位置信息
  • VT_TENSORNAME = 18,即 属性位置信息 18位置开始的2个字节 存储 tensorName 的 数据位置,28 - 22 + 18 = 24 : 0x0010 = 16
  • MNN::Net指针位置加上 数据位置的值 获得 数据偏移,即:28 + 16 = 44 : 0x000008 = 8
  • 44 + 8 = 52,即我们要找的 字符串指针数组 的数据起点在 52位置

3.1.3 寻找 字符串的数据起点

3.1.1 节我们得到了位置52,并且知道,这个位置是一个 字符串的指针数组,那么

  • 52 : 0x00000003 = 3,表示数组的长度为3,所以后面3个4字节就是代表三个指针的值
  • 即: 三个指针的 位置 分别为 : 56、60、64
    对应的值 分别为 : 0x0000001c、0x00000010、0x00000004
    换算成十进制 分别为 : 28、16、4
  • 那么 三个字符串指针 分别指向 :
    56 + 28 = 84
    60 + 16 = 76
    64 + 4 = 68
    三个字符串的数据起点位置
    寻找 字符串的数据起点

3.1.4 解析字符串

字符串的 前四个字节 描述 字符串的长度

  • 我们发现三个字符串的 长度都是1
    84 :0x00000001 = 1
    76 :0x00000001 = 1
    68 :0x00000001 = 1
    那么紧跟其后的 1个字节 即为字符串的有效值
  • 即获取3个有效值:0x30、0x35、0x36
  • 查阅一下 ASCII码对照表 吧,他们就是'0', '5', '6',任务1完成

3.2 Mission2:找到Conv0 的 bias

再来个稍微复杂点的任务练练手!找到Conv0 的 bias

任务2目标

3.2.1 确认分析思路

看下MNN的数据结构,确认下任务完成思路

MNN模型数据结构

如图,我们要先找到oplists,然后找到 第二个op(第一个是Input),然后找到 Convolution2D 的数据,找到我们要的 bias

3.2.2 寻找 oplists 数据起点

oplists的数据结构是Vector<flatbuffers::Offset<Op>>,即一个Op指针的数组

  • 28 - 22 + 10 = 16 : 0x0008 = 8
  • 28 + 8 = 36 : 0x00000048 = 72
  • 36 + 72 = 108
    108位置 即为 oplists 的数据起点
找到 oplists

3.2.3 寻找 第二个Op 数据起点

第一个Op为Input,我们找第二个Op

  • 108 + 4 * 2 = 116 : 0x00000130 = 304
  • 116 + 304 = 420
    第二个Op位置在420

3.2.4 寻找 Convolution2D 数据起点

  • 420 : 0x00000010 = 16
  • 420 - 16 + 8 = 412 : 0x000C = 12
    *420 + 12 = 432 : 0x00000028 = 40
  • 432 + 40 = 472
    Convolution2D的位置在472
寻找 Op & Convolution2D

3.2.5 分析Convolution2D

  • 472 : 0x0000000A = 10
  • 472 - 10 + 8 = 474 : 0x000C = 12
  • 472 + 12 = 484 : 0x00000004 = 4
  • 484 + 4 = 488 ,即bias float数组的位置。 bias 的数据结构为:Vector<float>,即一个浮点数数组
  • 488 : 0x00000005 = 5,bias数组长度为5
    所以bias的五个值位置 分别为 : 492、496、500、504、508
    值均为 0x3f000000,是 float数据结构的二进制形式存储值

3.2.6 解析float

0x3f000000 转为二进制为:0011 1111 0000 0000 0000 0000 0000 0000
使用 Float结构拆解 为1 + 8 + 23,即 : 0 01111110 00000000000000000000000
得到:
符号位:0,正数
指数:01111110 : 126 -> 正负指数表示 -> 126 - 127 = -1,即 指数 -1
底数:00000000000000000000000,补1后为:1.0,即 底数 1.0

计算值:底数1.0 小数点 左移1位(-1) 得到:0.1,为二进制小数,转换为10进制即0.5

任务2完成!

结语

感兴趣的小伙伴也可以尝试在 2.2的二进制文件 中寻找下 2.1Json文件 的其他信息哦,或许还会有新的发现[坏笑]。
比如试试找一下:Conv1 的 weight 数据

资源
文中使用的MNN模型
MNN GitHub 地址
FlatBuffers MNN模型存储结构基础
FlatBuffers GitHub 地址

鸡汤
对任何事物追根究底的研究会找到意想不到的乐趣!
将那份复杂用最容易理解的方式讲出来!
自我学习后是 , 有效表达后为 ~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354