Skip to content

Commit

Permalink
add doc
Browse files Browse the repository at this point in the history
  • Loading branch information
tpoisonooo committed May 18, 2019
1 parent 13869ec commit 50dcb6c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
29 changes: 29 additions & 0 deletions doc/bconv_CN.md
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`和当前版本实现方式不同。
19 changes: 19 additions & 0 deletions doc/design_CN.md
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)
28 changes: 28 additions & 0 deletions doc/onnx2bnn_CN.md
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`

0 comments on commit 50dcb6c

Please sign in to comment.