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

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

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

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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档