原文链接:https://www.yuque.com/yahei/hey-yahei/binary_quantization
最近号称达到MobileNet水平的二值网络MeliusNet面世,趁这个机会顺便梳理一下二值量化的发展历程吧。
参考:
- 《MeliusNet: Can Binary Neural Networks Achieve MobileNet-level Accuracy? (2020.01)》的Related Work
- https://github.com/memoiry/Awesome-model-compression-and-acceleration
- https://github.com/Ewenwan/MVision/tree/master/CNN/Deep_Compression/quantization
BNN
算是开山之作,同时二值化了权重和激活,但精度挺低,只在MNIST跟CIFAR10上做了些实验。
论文:《Binarized Neural Networks(NIPS2016)》
参考:《二值神经网络(Binary Neural Network,BNN) | CSDN, 张雨石》
实现:https://github.com/itayhubara/BinaryNet.pytorch
二值化形式
BNN提出了两种二值化形式,一种是决策形式,一种是随机形式。
- 决策形式:直接根据连续值的符号,准确地二值化为+1或-1
=\left{\begin{array}{ll}
{+1} & {\text { if } x \geq 0} \
{-1} & {\text { otherwise }}
\end{array}\right.&height=45&width=247) - 随机形式:引入随机因素,概率性地二值化为+1或-1
} \
{-1} & {\text { with probability } 1-p}
\end{array}\right.&height=45&width=284)
其中为hard sigmoid函数,即=\operatorname{clip}\left(\frac{x+1}{2}, 0,1\right)&height=45&width=182)
随机形式要求软硬件生成随机数,实现上比较复杂,所以BNN更倾向于决策形式的二值化
移位实现的BN层
为参数找到最接近的近似值,把乘法运算简化为位移运算
训练细节
- 权重和激活在前传和后传都二值化,梯度则继续使用浮点数
- 训练过程中梯度往往比较小而且需要累积,别说二值化了,即使普通的int8量化甚至是用半精度浮点数都会带来训练效果的损失;所幸在梯度上使用浮点数只是增加了训练的时间,预测阶段的速度不受影响
- 权重和激活值的量化引入了噪声,相当于引入正则化,反而还有利于模型的训练
- 二值化函数的梯度处处为0,显然没法直接用反向传播算法来进行训练
为了解决这一问题,作者使用了梯度直通评估器(straight-through estimator, STE),相当于用一个可导的hard tanh函数去近似sign函数
 = clip(x, -1, 1) \approx sign(x)\
g_r = \begin{cases}
1, & 0 \leq x \leq 1 \
0, & otherwise
\end{cases}&height=67&width=724)
### 优点
- 速度快,减小内存占用和访存
- 简化计算结构,通常来说32bit乘法需要占用200倍于位运算的计算资源
- 由于权重只有+1和-1,那么卷积核存在的可能组合是相当有限的,相同/相反的输出通道都可以直接剪裁,相似的通道也有一定的裁剪空间
XNOR-Net
与BNN相似,加入了额外的缩放因子,问题讨论也比BNN更加详尽。
论文:《XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks (ECCV2016)》
参考:《XNOR-Net算法详解 | CSDN, AI之路》
实现:https://github.com/jiecaoyu/XNOR-Net-PyTorch
(据说~58x的加速比有问题)