-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
13869ec
commit 50dcb6c
Showing
3 changed files
with
76 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#### 二值卷积实现 | ||
##### 定点化输入 | ||
在执行二值卷积之前,网络需要手动插入一层`Binarize`。顾名思义就是把 float 输入调整为二进制格式。详见 | ||
``` | ||
dabnn/bitpack.h#pack_mat_64 | ||
``` | ||
|
||
注意此处转换时,使用的公式是: | ||
``` | ||
bin_val = 0 if float_val > 0.0f else 1 | ||
``` | ||
数值反过来,是为了后续方便实现。原本是`xnor`操作,调整输入后即为`xor`操作,某些步骤不需要再取反。 | ||
|
||
|
||
卷积实现有很多种办法,dabnn在项目早期提供了两种优化实现。 | ||
##### 展开 | ||
以汇编方式直接跑卷积。俗话说“有多少人工,就有多少智能”,这些代码就是最好的注解: | ||
``` | ||
dabnn/bconv.h | ||
``` | ||
|
||
##### im2col | ||
这个方法最早来自`Caffe`,原本是想先用`im2col`重排输入,用连续的输入提高 Cache 命中率,然后用研究了很多年的`gemm`方法一波带走。 | ||
``` | ||
dabnn/bgemm.h | ||
``` | ||
|
||
##### 注意事项 | ||
第一版`Binarize`和当前版本实现方式不同。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#### 背景和发展方向 | ||
二值网络比较年轻,较有名的文献来自 2016 年的 [XNOR-Net](https://arxiv.org/abs/1603.05279v4)。初版精度不高,因此 [Bi-Real Net](https://arxiv.org/abs/1808.00278v5) 提出了一些精度提升方法。今年(2019)[BENN](https://arxiv.org/abs/1806.07550v2) 用机器学习方法进一步提升了 BNN 在分类任务上的表现,结果甚至超过单精度浮点模型。论文同时表明 BNN 由于天生泛化性差导致了在鲁棒性和稳定性上的缺陷。 | ||
|
||
但是从移动端工程应用的角度来看,定点网络可以节省数十倍的内存、提升数倍推理速度,同时降低十倍以上能耗。这意味着原本设备充电一次只能用一个小时,现在理论上可以用十小时以上。能耗相关可参见[相关测试](https://camo.githubusercontent.com/e725038be60ce4bb698b22480603b636a92beeaf/687474703a2f2f66696c652e656c656366616e732e636f6d2f776562312f4d30302f35352f37392f7049594241467373565f5341504f63534141435742546f6d6531633033392e706e67)。 | ||
|
||
综合算法和工程来看,部分二值网络实用意义和竞争优势可能在以下两点: | ||
|
||
1. 与已量产设备融合。嵌入式设备在设计过程中,为了节约成本往往会做成“刚好够用”的状态。二值卷积在计算过程中既不需要大量的 SIMD 乘法操作,内存需求也远低于 8bit 模型,对原有系统干扰极小; | ||
2. 在分类任务中以混合精度的方式替换已有方法。 | ||
|
||
卷积曾出现过很多变种,但是其中大部分已被历史淘汰。BNN 要想避免此命运,最简单的方法莫过于尽快落在某个产品或项目上,证明自己的价值。 | ||
|
||
|
||
#### 软件架构 | ||
在使用流程和软件结构方面,dabnn 和已开源的推理库(如 [ncnn](https://github.com/Tencent/ncnn)、[Tengine](https://github.com/OAID/Tengine)、[FeatherCNN](https://github.com/Tencent/FeatherCNN) 等)差距不大: | ||
|
||
1. 模型训练可使用 [bmxnet](),也可用[修改过的 PyTorch]() ,最终导出为[修改后的的 onnx 格式]()。onnx 主要增加了一些图优化方法,具体可查询相关项目; | ||
2. 由于 protobuf-lite 静态库远大于 flatbuffers,为节省内存并减小 SDK 和模型体积,推理时需要把 onnx 格式转换成 dabnn 内部格式,流程和**注意事项**可参照 [onnx2bnn_CN.md](onnx2bnn_CN.md); | ||
3. 二值卷积实现请查阅 [bconv_CN.md](bconv_CN.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#### 模型转换流程 | ||
|
||
1. 请先阅读开源版本的 [onnx 格式说明](https://github.com/onnx/onnx/blob/master/docs/IR.md); | ||
2. 读取所有参数和 Layer。对于二值卷积,把参数转为二进制格式。 | ||
``` | ||
bin_val = 1 if float_val > 0.0f else 0 | ||
``` | ||
此处实现和 `bmxnet` 相比,在`0.0f`的处理上有差异。`bmxnet`的转换函数为: | ||
``` | ||
bin_val = 1 if float_val >= 0.0f else 0 | ||
``` | ||
此处和一些同学讨论过,有的认为权重刚好是 0.0f 的情况几乎不存在;也有的说如果权重是 0.0f,训练几乎失败。目前的结论是不影响。 | ||
|
||
3. 其他 Layer 正常处理。 | ||
|
||
#### 注意事项(必看) | ||
|
||
由于`BNN`商业化程度不高,且`onnx`当前版本对`BNN`支持不够完善,模型转换过程中有些硬编码规则需要额外说明。 | ||
|
||
1. bias 参数在转换模型的过程中会被重命名为 `{name}_conv_b`,而`kernel`权重会被重命名为`{name}_conv_w`; | ||
|
||
2. 由于`onnx`当前版本还没有对应的名称,训练平台(如`PyTorch`)导出为`onnx`格式时,需要把`domain`字段设为`dabnn`以标记此层为二值卷积层; | ||
|
||
3. `onnx`格式为 NCHW,而`dabnn`内置格式为 NHWC,与 `TensorFlow`/`SNPE` 一致。这么设计是为了方便后续卷积计算; | ||
|
||
4. 二值卷积参数之和暂时需要是 64 的倍数; | ||
|
||
5. `group` 必须要为 1,因此目前不支持分组卷积和`MobileNet`。 |