Skip to content

Commit

Permalink
Update onnx2bnn_CN.md
Browse files Browse the repository at this point in the history
  • Loading branch information
daquexian committed Jun 4, 2019
1 parent bce3003 commit 749d990
Showing 1 changed file with 23 additions and 17 deletions.
40 changes: 23 additions & 17 deletions doc/onnx2bnn_CN.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
ONNX (Open Neural Network Exchange) 是一个独立于训练框架的模型格式,[众多框架和工具](http://onnx.ai/supported-tools) 支持 ONNX 格式。

#### 模型转换流程

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,训练几乎失败。目前的结论是不影响。
1. 读取所有参数和 Layer。对二值卷积的 weight 进行 bit-packing。关于 bit-packing 可以参考 [这篇文档](docs/bconv_CN.md);
1. 修改二值卷积之后的 BN 层的权重。因为 bit 只有 1 和 0 两个值,所以二值卷积中的 -1 被用 0 表示,bitcount 可以得到一个 N-bit 操作数中,值为 1 的 bit 的数量,这忽略了 -1 的存在。具体来说,设 a 为一个 N-bit 操作数,b 为一个自然数,且

> b = bitcount(a)
实际上我们应该得到的值是

> c = bitcount(a) - (N - bitcount(a)) = 2 * bitcount(a) - N = 2 * b - N
3. 其他 Layer 正常处理。
这个值可以经过一个对 b 的线性变换得到,因此我们将这个变换融合进二值卷积之后的 BN 层之中。

具体实现在 https://github.com/JDAI-CV/dabnn/blob/master/tools/onnx2bnn/OnnxConverter.cpp#L530。

1. 其他 Layer 正常处理。

#### 注意事项(必看)

由于`BNN`商业化程度不高,且`onnx`当前版本对`BNN`支持不够完善,模型转换过程中有些硬编码规则需要额外说明。
由于 BNN 商业化程度不高,且 onnx 当前版本对 BNN 支持不够完善,

`onnx2bnn` 依赖的是经过 dabnn 开发者自定义的 onnx,其中增加了多个 optimizer,用来识别二值卷积,具体实现可参考 https://github.com/daquexian/onnx/tree/optimizer_for_bnn/onnx/optimizer/passes 中的 dabnn_*.h

1. bias 参数在转换模型的过程中会被重命名为 `{name}_conv_b`,而`kernel`权重会被重命名为`{name}_conv_w`
模型转换过程中有些规则或限制需要额外说明。

2. 由于`onnx`当前版本还没有对应的名称,训练平台(如`PyTorch`)导出为`onnx`格式时,需要把`domain`字段设为`dabnn`以标记此层为二值卷积层
1. **二值卷积的输入 channel 暂时需要是 128 的倍数或 64**

3. `onnx`格式为 NCHW,而`dabnn`内置格式为 NHWC,与 `TensorFlow`/`SNPE` 一致。这么设计是为了方便后续卷积计算;
1. 目前暂时不支持 `group` 参数。

4. 二值卷积参数之和暂时需要是 64 的倍数
1. 由于 `onnx` 没有二值卷积的 operator,onnx2bnn 会把 `domain` 字段设为 `dabnn` 以标记此层为二值卷积层

5. `group` 必须要为 1,因此目前不支持分组卷积和`MobileNet`
1. `onnx` 的元素布局为 NCHW,而 `dabnn` 的元素布局为 NHWC 或 NC1HWC2。具体可以关注我们即将 publish 的 paper;

0 comments on commit 749d990

Please sign in to comment.