前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >二值网络,围绕STE的那些事儿

二值网络,围绕STE的那些事儿

作者头像
SIGAI学习与实践平台
发布于 2019-07-10 10:46:14
发布于 2019-07-10 10:46:14
2.9K0
举报

SIGAI特约作者

卓哥哥 博士

研究方向:计算机视觉

什么是二值网络?

二值网络,是指在一个神经网络中,参数的值限定在{-1,+1}或者{0,1}。而更为彻底的二值网络是让网络在进行计算时得到的激活值(activation)也被二值化。当然,最为彻底的,是在网络的训练过程中,对梯度也进行二值化。我们今天讨论的,就不涉及对梯度二值化了,只考虑前面的两种情况。

二值网络有什么好处?

二值网络从直观上来讲有明显的两个好处:第一,相对于普通网络,参数从32-bit的浮点型数变成了只占1-bit的数,直接将模型大小减小成原来的1/32;第二,在进行卷积运算时,由于参数范围为{-1,+1},因此原来的乘法运算变成了加减运算。而如果我们再将激活值也限定成{-1,+1},那么连加减运算都不需要,直接变成了位运算,十分高效。由于以上两个优点,二值网络能更加方便地转移到一些资源有限的设备,比如移动设备等。

为了得到性能较好的二值网络,需要战胜哪些困难?

一种粗暴的方式是直接将训练好的浮点型网络的参数二值化处理。但是这样得到的二值网络是非常不理想的,从以往经验来看会使性能明显下降。

所以摆在我们面前的难点,在于二值网络的训练。网络在前向传播的过程中,一个通常的做法是对浮点型的参数取符号来进行二值化处理,也就是sign函数:

但是这个sign函数基本上在定义域范围内导数都是0,从而无法用梯度下降算法来训练二值网络。这个时候,一个叫“Straight-Through-Estimator”(简称STE)的东西就能派上用场了。

什么是STE?

根据史料记载[1],STE是由三巨头之一的Hinton在2012年的一个lecture上介绍的。STE,顾名思义,就是直接把二值参数的梯度作为对应的浮点型参数的梯度。接着上面的公式讲,就是:

如果非要用个图来阐释一下,这个图可以是(引自[5]):

有了这个STE,训练过程可以是这样:模型中每个参数其实都是一个浮点型的数,每次迭代其实都是在更新这个浮点型数。但是,在前向传播的过程中,先用sign函数对浮点型参数二值化处理然后再参与到运算,而此时并没有把这个浮点型数值抛弃掉,而是暂时在内存中保存起来。前向传播完之后,网络得到一个输出,就可以接着通过反向传播算出二值参数的梯度,再直接用这个梯度来更新对应的浮点型参数。这样,前向反向就跑通了。等训练的差不多了,就最后对模型的这些浮点型参数做一次二值化处理形成最终的二值网络,此时浮点型的参数就完成了任务,可以被抛弃掉了。用古圣先贤的话讲,就是飞鸟尽,良弓藏,狡兔死,走狗烹。方法虽然简单粗暴,但是效果却非常的好(具体可见后文带Vanilla STE字样的表格)。我们把刚刚的这个过程称为算法1。

那STE为什么会好?有哪些缺点?围绕它有些什么改进?诞生出了一些什么方法来训练二值网络?

为了回答以上问题,接下来,我们来拆读一下围绕STE展开的几篇论文,对二值网络好好赏析一波。

●BinaryConnect: Training Deep Neural Networks with binary weights during propagations [2]

这是Bengio参与的一篇关于网络量化的开山鼻祖之作,将神经网络中的参数二值化,在MNIST,CIFAR-10,SVHN数据集上达到state-of-art级别的性能。这篇文章对量化网络的可行性是这么进行解释的:

1. 对参数进行量化其实是对参数引入了一定程度的噪音,这些噪音在模型训练的过程中通过积累,逐渐被平均掉了(is averaged out)。这个原理就相当于以前老师讲的多次实验取平均值能够减小实验误差是一样的。而这个噪音积累的过程与SGD(随机梯度下降)非常的像,因为在SGD中,也是通过对参数进行梯度的积累,使得随机过程带来的噪音会在迭代的过程中通过积累慢慢消失,最后训练出有效的网络。所以说,为了完成噪音的积累,每个参数必须配置一个全精度的浮点型数作为二值参数的代理,只有在网络训练完之后才把代理处理成二值。

2. 类似于Dropout或者DropConnect,参数引入一定成分的噪音(这里指对参数做二值化处理)意味着给网络加入了某种正则成分,从而能提高网络的泛化性能。

这里他们还提出了两种参数二值化的方式:分别是确定型和随机型。确定型就是用前面讲的sign函数,随机型的方式如下:

其中,

就是说当参数值比-1小,就一定量化成-1,参数值比+1大,就一定量化成+1,参数值间于中间,就以一定概率量化成-1或+1。

不管是用以上哪种方式量化,都可以用STE来计算浮点型参数的梯度,也就是直接把二值参数的梯度作为对应的浮点型参数的梯度来更新浮点型参数。训练过程基本上等同于上述讲的算法1,唯一的不同是当浮点型参数进行更新后如果超过[-1,+1]的范围,就截断成[-1,+1]。比如,如果大于+1,就变成+1。具体算法为:

至于为什么要在参数每一次更新之后就截断一下,就是为了防止参数数值无限增长,那样的话数值改变一点点也不会对二值化的结果有任何的影响。

网络训练好之后,有以下三种可能的方式把它运用到实际测试上来:

1. 用确定型方式将参数二值化得到二值网络来inference。

2. 用浮点型参数来inference,此时二值化的作用就是提高了训练的速度。

3. 用随机型方式将参数二值化,这样可以得到多个二值网络。然后平均这些二值网络的输出,达到集成学习的效果。

下表是用前两种方式(分别用det,stoch标出,No regularizer就是普通的浮点型网络训练)的实验结果,表中的数据为test error rate,本文的方法用BinaryConnect表示。

这里stoch的结果可以说明量化给网络带来了正则化的效果,验证了上面的解释。

●Binarized Neural Networks: Training Neural Networks withWeights and Activations Constrained to +1 or -1 [1]

这是继上文之后Bengio参与的改进之作。二值化方式和上文的一致,也是确定型和随机型。和上文不同的地方有:

1. 除了对参数二值化,也对得到的浮点型激活值二值化变成二值激活值。

2. 对STE加了限制。具体来讲,在计算浮点型激活值的梯度时,如果该激活值在[-1,+1]范围里面,则按照STE,可以直接等于对应的二值激活值的梯度;如果在范围外,则梯度为0。用公式来讲,就是

这样,其实等效于在前向传播中,用了sign函数,而在后向传播中,用了hard tanh函数,也就是(我们暂且把它叫做饱和STE):

同样的,饱和STE可以用下图阐释(注意与前面标准STE的区别是反向传播时曲线被截断了):

饱和STE实现了梯度截断,也就是当值超过某个范围时,取消对它的梯度传递(梯度传递是指将二值的梯度传递给对应的浮点值,也就是公式中q的梯度传递给r,记住我们要更新的是浮点型的r,而q的梯度是可以在反向传播中通过链式法则算出来的)。

算法其余部分和BinaryConnect一致,同样是对浮点型参数更新后将其截断成[-1,+1]的范围,这样其实也间接实现了梯度截断,因为参数的值始终被限制在[-1,+1],那么参数的梯度也就始终能被传递。

接下来依旧是展现一波实验结果(本文的方法用BNN表示,数据为test error rate)

●XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks [3]

本文是在上面两篇文章的基础上,提出了两种网络。第一种只对参数二值化,第二种对参数和激活值二值化。总体来说,方法可谓简单粗暴,却颇有成效。

第一种网络(BWN),对每一层的每一个输出通道对应的卷积核进行二值化时,多引入了一个缩放参数,使得:

为了最小化重构误差,得到

这样,计算出了最佳缩放因子,同样利用饱和STE,参数的前向传播和后向传播分别为:

第二种网络(XNOR-Net),在二值化参数和激活值时都引入对应的缩放参数,使得

其中X为激活值,这里指卷积层的输入。同样的,缩放因子的计算公式为

前向传播和后向传播的原理同上。与之前方法不同的是,对于这两种网络,文中并没有提到要将更新之后的参数进行截断。

另一个值得注意的地方是对于XNOR-Net,由于卷积操作的结果为{-1,+1},如果紧接一个pool层,如maxpool,那么pool后面的值将大部分变为1,因此作者调整了一下pool的位置,如图:

在ImageNet上的结果为

●Towards Accurate Binary Convolutional Neural Network [4]

继续XNOR-Net简单粗暴的方式,在二值化网络时除了引入缩放因子,还多加了几个二值卷积基。看到这里读者朋友们大概会一脸懵逼,什么是二值卷积基?看一下公式就知道了:

当n=1时,就非常接近上文中的第一种网络BWN,只不过这里是该层所有通道的卷积核共享同样的缩放因子,而BWN是每个输出通道的卷积核有一个缩放因子。

所以,为了向BWN看齐,作者进一步提出了channel-wise的方法,也就是说:

这样,当n=1时,就跟BWN一模一样了,是不是很神奇。而这里,每一个Bi都是一个二值卷积基。二值卷积基是人为定义的,不需要学,而每个基的系数可以通过最小化重构误差算出来,也可以作为网络参数的一部分学出来的。网络进行训练时,反向传播同样运用了STE。

前向:

反向:

紧接着,作者开始对激活值以同样的方式进行二值化处理,也是用了好多基~ 对于每一个基,用不同的阈值对其进行二值化,并且也会带有一个系数(见下面网络结构图中的beta):

对激活值进行梯度传导时,则用了饱和STE:

最后的网络结构就变成了这样(ABC-Net,下图卷积层基的个数为3,激活层基的个数也为3):

其中,对于每一个BinConv,由于参数和激活值都是二值,所以能够用位运算快速计算。原来某一个卷积层的运算则被近似成下面的公式(M为卷积核基的个数,N为激活层基的个数):

以下是在ImageNet上的实验结果:

●AN EMPIRICAL STUDY OF BINARY NEURAL NETWORKS’ OPTIMISATION [5]

这是今年ICLR的一篇论文,对以上各种二值网络及其他的二值网络做了一个全面的分析,并且提出了更为有效的二值网络训练方法。

首先,文章对以往二值网络的训练过程中的截断方式做了一个总结。截断方式分为对参数截断(weights clipping)和对梯度截断(gradients clipping)。参数截断是指参数在更新完之后将其截断成一定范围,比如[-1,+1];梯度截断是指在计算某个值的梯度时,如果这个值在某个范围,那么就将这个值对应的二值的梯度作为这个值的梯度,否则这个值的梯度就为0,也就是上面提到的饱和STE。

为了搞清楚具体的过程,我特地把该文章公布的代码中(https://github.com/mi-lad/studying-binary-neural-networks)相应的部分扣了下来,以下是参数截断:

在weight的构造函数中会传入这个_weight_constraint,使得weight每次更新后都会调用一下这个_weight_constraint。

以下是标准STE:

意思就是说,在反向传播过程中,会将Sign映射成Identity,因此二值的梯度会直接赋给对应的浮点值的梯度。

以下是饱和STE:

这里的input_op就是weight,也就是说在计算weight的梯度时,如果weight在[-1,1]范围内,那么梯度能正常传播,否则梯度就是0。

但是窃以为,对于weights来讲,weights clipping会包含gradients clipping,因为既然weights被限制在了[-1,1],那么按照上面的定义,无论做不做gradients clipping,二值化参数的梯度总能够被传递过来。

接下来文章分析了各种因素对二值网络训练的影响。

第一是发现了ADAM是最有用的:

接着发现了以上的clipping确实是有用的:

然后研究了一下Batch Normalization的Momentum参数对网络结果的影响:

最后再分析了一波卷积层中各个结构,如pool层,激活层等的相对位置以及学习率对网络的影响。

总之,最后的结论就是Clipping虽然能帮助提高performance,但是影响了训练初期收敛的速度,所以在训练的前半段可以用标准STE(即不用clipping),在后半段把clipping再加上来,这样同时保证了速度和准确率。另一种方式是用pre-train好的网络对二值网络进行初始化,然后在用STE加clipping的方式对网络进行训练,同样能达到满意的速度和效果:

全文总结

写到这里可以暂时告一段落了。本文只是介绍了几种比较有代表性的运用STE的二值网络训练方法,希望能使读者有所感悟和启发。但归根到底,STE始终是一种近似的梯度计算方法,且需要用到浮点型代理,未来的工作可能是弥补这方面的不足,能够直接训练一个二值网络而不需要额外的浮点型参数。希望这点能在不久的将来实现,让我们拭目以待~ 另外,欢迎访问我的个人博客:https://zhuogege1943.com,建立初期,请多关照。

[1] Courbariaux, Matthieu, et al. "Binarized neural networks: Training deep neural networks with weights and activations constrained to+ 1 or-1." arXiv preprint arXiv:1602.02830(2016).

[2] Courbariaux, Matthieu, Yoshua Bengio, and Jean-Pierre David. "Binaryconnect: Training deep neural networks with binary weights during propagations." Advances in neural information processing systems. 2015.

[3] Rastegari, Mohammad, et al. "Xnor-net: Imagenet classification using binary convolutional neural networks." European Conference on Computer Vision. Springer, Cham, 2016.

[4] Lin, Xiaofan, Cong Zhao, and Wei Pan. "Towards accurate binary convolutional neural network." Advances in Neural Information Processing Systems. 2017.

[5] Milad Alizadeh, Javier Fernández-Marqués, Nicholas D. Lane, Yarin Gal. “An Empirical study of Binary Neural Networks' Optimisation.” ICLR 2019.

本文为SIGAI原创

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【开源合规】开源许可证风险场景详细解读
接上篇文章所讲,使用开源组件,忽略开源许可证问题是存在合规风险的,但是关于什么场景下真实存在风险,以及什么样的风险?很多文章也没有讲的很明白,这些内容大部分都隐藏在晦涩难懂的许可证原文里面。通过一段时间的接触,包括收集资料、翻译许可证原文等学习,特此整理了一部分……
没事就要多学习
2024/07/20
8060
【开源合规】开源许可证风险场景详细解读
【开源合规】开源许可证基础知识与风险场景引入
逛Github时经常看到项目README旁边,有个License tab,不知道大家是不是跟我一样,撇了一眼就过去了,不太清楚这个license具体作用,有点法律意识的朋友可能会意识到这个可能是版权声明,不过难免还是会有其他疑问:既然都开源了,怎么还有各种条件限制?除了GPL还有Apache、MIT等,这些"License"又有哪些区别呢? 很多朋友可能像之前的我一样,二开项目或者使用第三方组件时直接拿来就用了,没有考虑过其背后的"风险"……
没事就要多学习
2024/07/18
1120
【开源合规】开源许可证基础知识与风险场景引入
如何为自己的开源项目选择合适的开源许可证?
之前我们介绍过很多款开源软件/项目,在文章的最后面总有代码仓库的License:MIT/Apache/GPL:
埃兰德欧神
2024/07/15
4820
如何为自己的开源项目选择合适的开源许可证?
开源许可证教程
作为一个开发者,如果你打算开源自己的代码,千万不要忘记,选择一种开源许可证(license)。 许多开发者对开源许可证了解很少,不清楚有哪些许可证,应该怎么选择。本文介绍开源许可证的基本知识,主要参考
ruanyf
2018/04/12
1K0
开源许可证教程
开源运动发展史与开源许可证(BSD、GPL、Apache、MIT、木兰(中国))的那些事儿
2022年1月份,Apache SkyWalking社区在其blog上实锤字节跳动的火山引擎里面违反Apache 2.0许可证,重新发布了Apache SkyWalking开源软件。
Flowlet
2022/08/18
1.4K0
开源运动发展史与开源许可证(BSD、GPL、Apache、MIT、木兰(中国))的那些事儿
【开源合规】开源许可证风险场景详细解读
接上篇文章所讲,使用开源组件,忽略开源许可证问题是存在合规风险的,但是关于什么场景下真实存在风险,以及什么样的风险?很多文章也没有讲的很明白,这些内容大部分都隐藏在晦涩难懂的许可证原文里面。通过一段时间的接触,包括收集资料、翻译许可证原文等学习,特此整理了一部分……
没事就要多学习
2024/07/18
2310
【开源合规】开源许可证风险场景详细解读
2018-09-07 几种开源协议的比较(BSD,Apache,GPL,LGPL,AGPL,MIT) – 整理几种开源协议的比较(BSD,Apache,GPL,LGPL,AGPL,MIT) – 整理
http://ewen0930.github.io/2016/11/open-source-licenses/
Albert陈凯
2018/09/20
2.4K0
2018-09-07 几种开源协议的比较(BSD,Apache,GPL,LGPL,AGPL,MIT) – 整理几种开源协议的比较(BSD,Apache,GPL,LGPL,AGPL,MIT) – 整理
常见开源许可证及其风险等级指南
开发人员经常在软件中引入开源的代码片段、函数、方法和操作代码。因此,软件代码中经常会包含各种声明不同许可证的子组件。这些子组件的许可证条款和条件与项目整体主许可证的条款和条件冲突时,就会产生许可证合规风险。
OpenSCA社区
2023/09/18
1.5K0
常见开源许可证及其风险等级指南
开源许可证保姆级入门手册
开源许可证是个相当庞杂的范畴,仅OSI (Open Source Initiative, 开放源代码促进会)批准的许可证就有80多种;此外,还有数百种在开源生态中流传的其他许可证。
OpenSCA社区
2023/07/07
6060
开源许可证保姆级入门手册
担心制品合规风险?做好这些就够了
今年来,开源的热度持续快速上升。开源给各大企业、组织带来了诸如迭代更快、成本更低、质量更高的收益;然而,企业在合规使用开源软件的过程中,也会面临一系列知识产权风险,这些风险主要源于开源许可证的传染性特征、不同开源许可之间可能存在的不兼容性,以及开源软件使用规则中所蕴含的不确定性等因素。
嘉为蓝鲸
2024/12/12
1550
担心制品合规风险?做好这些就够了
深入理解开源许可证(Apache,MIT,GPL,BSD,CC)
如果说有什么东西正在为开源世界保驾护航,那就一定不能不提到开源许可证(Open Source License),正是因为这些各不相同的开源许可证的共同支持下,才有了现在这么繁荣的开源软件社区。
HikariLan贺兰星辰
2022/10/27
3.8K0
对开源的认知
没有开源软件,现在的互联网根本无法存在,开源的历史可以追溯到ARPANET建立。开源在今天已经不再是一个时髦的词了,对于互联网的开发者来说,它现在就像空气和水一样,就在我们的生活中。
半吊子全栈工匠
2019/01/23
9850
深入探讨各种开源协议:选择合适的许可证为你的项目保驾护航
在软件开发的世界中,开源项目已经成为推动技术创新的重要力量。无论是个人开发者还是企业,选择合适的开源许可证都至关重要。不同的许可证对代码的使用、修改、分发等方面有不同的要求,了解这些细节可以帮助开发者更好地保护自己的权益,并促进项目的广泛应用。本文将深入探讨各种常见的开源协议,包括GPL、MIT、Apache、BSD、MPL、CC、EPL、AGPL、LGPL以及中国本土的木兰许可协议,帮助你在复杂的开源生态中找到最合适的许可证。
繁依Fanyi
2024/08/20
4270
如何选择合适的开源许可证?
选择正确的开源许可证是确保软件分发和使用的关键。本文详细探讨了如何根据项目需求、目标受众和期望的控制权选择合适的开源许可证。
猫头虎
2024/04/09
2440
如何选择合适的开源许可证?
趣谈自由软件与开源软件(五):自由与开源许可证
对于国内习惯了使用开源软件或框架,类库的程序员群体来说,最熟悉的License应该是开源许可证,也就是Open Source License。在开源许可证中,接触最多的可能是Apache License以及MIT这两个应用较为普遍的许可证了。
御剑
2022/03/09
8830
版本升级 | v1.0.12发布,许可证风险早知道
开源软件一般都有对应的开源许可证(Open Source License)对软件的使用、复制、修改和再发布等进行限制。许可证即授权条款,开源许可证就是保证开源软件这些限制的法律文件,目的在于规范受著作权保护的软件的使用或者分发行为。开源许可证是开源软件生态系统的基础,可以促进软件的协同开发。
OpenSCA社区
2023/07/14
2680
版本升级 | v1.0.12发布,许可证风险早知道
一文看懂开源许可证丨开源知识科普
在很多人眼中,「开源」是一个时髦且有情怀的词汇,始终伴随有理想主义色彩,因此不少公司开始给自己贴上“开源”标签。但一个优秀的开源项目远远不止是简单的公开源代码,而是需要将其当作公司战略进行贯彻,才能架设起牢不可破的信任桥梁。
PingCAP
2021/10/21
2.1K0
开源许可证的变迁:从Elastic两次变更开源协议说开去
开源从开始到现在已经有几十年历史,开源许可证在开源运动的发展中起到了基石作用,不管是从文化还是法律的角度,都较好地推动了开源的发展。
深度学习与Python
2022/06/13
1K0
开源许可证的变迁:从Elastic两次变更开源协议说开去
开源许可证协议
最近新闻中的00后被指抄袭Github开源项目,新闻链接:http://money.163.com/17/0905/17/CTJBUNNV002580S6.html 被抄袭墨镜猫作者博客:http://blog.csdn.net/rain_butterfly/article/details/77847643 墨镜猫的开源项目遵循的协议是Apache v2.0,允许商用,但随后,墨镜猫就于9月5日上午将协议修改成了 GNU GPL v3.0。一直以来,GPL是Linux软件及各种开源项目中比较受欢迎的项目协议
233333
2018/03/07
1.5K0
开源许可证协议
2020 年开源许可证最新趋势:67% 为宽松许可证
开放源码许可证通常被开发人员视为是法律顾问在他们忙于创建软件产品时,必须处理的“枯燥”合规性问题。随着各行各业使用开源代码,一些开源项目已成为“大生意”,这使得关于开放源码许可证的再次成为争论的焦点。
程序猿DD
2020/05/20
1.6K0
推荐阅读
相关推荐
【开源合规】开源许可证风险场景详细解读
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档