前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习算法优化系列十 | 二值神经网络(Binary Neural Network,BNN)

深度学习算法优化系列十 | 二值神经网络(Binary Neural Network,BNN)

作者头像
BBuf
发布2020-02-21 11:54:32
1.9K0
发布2020-02-21 11:54:32
举报
文章被收录于专栏:GiantPandaCVGiantPandaCV

前言

昨天介绍的BinaryConnect提出将浮点权重量化到1bit,提出了完整的量化权重训练/测试流程,并且从带噪声权重的角度来解释了量化权重。但这种方法还有一个缺点,即并没有对激活函数进行量化,所以Bengio大神在2016年发表了这篇Binary Neural Network,论文原文和代码链接见附录。

BNN算法

二值化的方法

二值化方法主要有两种,确定式二值化和随机式二值化。二值化将float类型权重转换为两个值,一个非常简单直接的二值化操作基于符号函数:

其中是二值化权重,是实值权重。这是一个确定式的二值化操作,另外一种方案是随机二值化,即以一定的概率更新值:

其中

第二种方法比第一种方法更合理,但在实现时,每次生成随机数会非常耗时,所以一般使用第一种方法。

梯度计算和累加

虽然BNN的参数和激活值被二值化了,但因为下面两个原因,导致梯度不得不用较高精度的实数而不是二值进行存储,原因如下:

  • 梯度的量级很小。
  • 梯度具有累加效果,即梯度都带有一定的噪音,而噪音一般认为是服从正态分布的,所以,多次累加梯度才能把噪音平均消耗掉。

另一方面,二值化相当于给权重和激活值添加了噪声,而这样的噪声具有正则化的作用,可以防止模型过拟合。因此,二值化可以被看作是Dropout的一种变形,Dropout一般是将激活值变成0,从而造成一定的稀疏性,而二值化则是将激活值变成1或者-1。

离散化梯度传播

直接对确定式的二值化函数求导的话,那么求导之后的值都是0。因此,只能采用一种折中的方法,将sign(x)进行松弛。这样函数就可以求导了。公式如下:

然后,假设损失函数为,二值化操作函数如下:

如果对的导数已经得到了,那么对的求导公式计算如下:

后面的就是Htanh函数。

在具体使用时,对于隐藏层单元,直接使用使用确定式二值化函数得到二值化的激活值。然后,对于权重,在进行参数更新时要时刻将超出[-1,1]的部分裁掉,即权重参数始终是[-1,1]之间的实数。最后,在使用参数时,要将参数二值化。

BNN的训练

前面已经解决了求导问题,二值化模型就可以直接训练了,具体过程如Algorithm1,这里用了BN层。

可以看到整个流程就是前向传播,反向传播,参数更新。

Shift Based Batch Normalization

Batch Normalization,简称BN,即批量归一化。所谓的BN是指在数据经过一层进入下一层之前,需要对数据进行归一化,使之均值为0,方差为1。这样可以使得各层的参数量级上没有太大的差别。BN有三个优点:

  • 加速训练。
  • 减小权重的值的尺度的影响。
  • 归一化带来的噪声也有模型正则化的作用。

我们来看一下BN的计算公式:

可以发现BN在训练时存在大量的矩阵乘法,导致训练比较长。因为二值化这一特点,所以这里可以对BN进行优化,我们可以在不使用乘法的情况下近似计算BN,这即是Shift Based Batch Normalization,如Algorithm2所示:

Shift Based BN

Shift Based AdaMax

同样也是为了加速二值网络的训练,改进了AdaMax优化器。具体算法如Algorithm3所示。

Shift Based AdaMax

First Layer

虽然所有层的激活值和参数都是二值的,但第一层(输入层)的值是连续的,因为是原始图片。如果要整个网络都是二值化的,只需要对输入层做一个变换即可。一般使用8位的值来表示一个像素,输入可以表达为一个的张量,而权重参数可以表达为的全向量。因此,第一层的计算操作如下:

这个函数就把像素值还原回来了,表示每个数的第位。

综上,最后BNN的计算过程如Algorithm5所示。

BNN的前向计算

测试推理阶段

如何前向推理,大致可以分为以下几种方法:

  • 使用二值化weight。
  • 使用浮点数weight。
  • 从浮点权重和随机二值化可以采样出很多二值网络,将它们的预测输出平均一下作为输出。

这篇论文使用了第3种方法,训练过程中用随机二值权重,测试时用浮点权重可以提升性能,证明了论文前面认为的带噪声的权重具有一定的正则性。

实验结果

在MNIST,CIFAR-10,SVHN上使用前向推理介绍的方法3进行测试的结果

性能分析

论文提到训练时间可以减少60%,但具体怎么计算暂时不清楚,后面了解下源码再说,暂时就理解为计时函数然后比较吧。从下面Table2和Table3的测试结果来看内存访问的耗时比计算耗时要多,相对于32bit的DNN,BNN的内存需求量为原来的1/32,使得能源使用可以减少31/32。

此外,在BNN中,所有的计算都变成了位运算,一个32bit的乘法需要损耗200单位(FPGA上)的能量,而一个位操作只损耗1个单位的能量。这在嵌入式设备上式具有非常大优势的。

能力损耗对比

总结

这篇论文是在BinaryConnect的基础上,同时将权重和激活值量化到1bit,不仅从实验角度证明了量化算法的可行,还分析针对低bit如何进行更有效的计算,整理出了同时量化权重和激活值到1bit的算法流程,且针对内部的硬件计算,给出了具体实现,例如Shift-based Batch Normalization、XNOR-Count,最终训练能减少60%的时间,32倍的存储空间。最近是先读一下理论,后面我会去做Pytorch的代码解析,自己动手训练测试二值网络,请持续关注吧。

思考

可以看到BNN在MNIST,CIFAR10,SVHN上实现了和普通DNN类似的精度,那么BNN能否在更复杂的数据集如ImageNet上也实现和DNN类似的精度并保持效果上的优势呢?另外一点是从论文的BNN需要小的学习率,并且收敛速度比DNN慢很多,这也是一个值得探索的问题。。收敛慢的问题可以从Figure1看出。

可以看到BNN收敛慢很多

附录

  • 论文原文:https://arxiv.org/pdf/1602.02830.pdf
  • 代码:https://github.com/itayhubara/BinaryNet

欢迎关注GiantPandaCV, 在这里你将看到独家的深度学习分享,坚持原创,每天分享我们学习到的新鲜知识。( • ̀ω•́ )✧

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GiantPandaCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • BNN算法
    • 二值化的方法
      • 梯度计算和累加
        • 离散化梯度传播
          • BNN的训练
            • Shift Based Batch Normalization
              • Shift Based AdaMax
                • First Layer
                • 测试推理阶段
                • 实验结果
                • 性能分析
                • 总结
                • 思考
                • 附录
                相关产品与服务
                批量计算
                批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档