量化网络有两个动机,一是缩小尺寸,这是通过存储每层的最大和最小值,然后把每一个浮点值压缩成 8-bit 整数来表示。二是降低资源需求,这需要整个计算都用 8-bit 输入和输出来实现。量化压缩是存在风险的,目前的版本似乎还不是很成熟,Github 上面有很多开发人员认为利用这种方法量化后的模型效率较低。 2016 年 3 月,Mohammad Rastegari 等人在论文 (XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks) 中首次提出了 XNOR-Net 的概念。这篇论文旨在利用二值化操作寻找到最优的简化网络,并分别介绍了两种有效的网络:Binary-Weight-Networks 和 XNOR-Networks。Binary-Weight-Networks 是对 CNN 中所有的权重做近似二值化,可以节省 32 倍的存储空间。而且,由于权重被二值化,卷积过程只剩加减算法,不再包括乘法运算,可以提高约两倍的运算速度,这促使 CNN 可以在不牺牲准确率的情况下在小存储设备上使用,包括便携式设备。Binary-Weight-Networks 区别于 BinaryNet 的地方在于它进行二值化的方法和网络结构。 XNOR-Networks 算法则是对 CNN 中所有的权重和输入同时做近似二值化,如果卷积运算中的所有操作数都是二进制的,那么两个二进制向量的点乘就可以等同于同或运算和位运算。作者在这篇文章里主要有两个贡献:一是引入比例因子,大幅度提升精度;二是对典型常规的 CNN 构成进行改动。 XNOR-Net 算法的基本思路如下: Step1:定义一个 L 层的 CNN 结构,使用三个元素 I,W,* 来表示,I 表示卷积输入,W 表示滤波器,*表示卷积算子;利用比例因子α帮助二值化滤波器去近似全精度滤波器权重,利用比例因子β帮助二值化的输入去近似全精度输入值。这有点类似于批规范化(Batch Normalization)中的仿射参数(Affine Parameters),但不同的是,这里不是通过为网络学习获得的,而是通过计算平均值得到的。在探索计算比例因子β的时候,要对每一次卷积产生的子张量都计算一个β,这一步骤会产生很多冗余的计算。为了降低计算量,作者把输入的所有 channels 计算一个绝对值的平均值矩阵 A,然后通过一个二维的滤波器 k 和 A 的卷积生成 K,那么 K 就包含了针对输入 I 在所有子张量上的比例因子。通过这样一系列数学推导,输入 I 与权重 W 的二值化卷积可以被近似为: 具体过程如下图:
图 1:XNOR-Net 近似二值化卷积过程(Mohammad Rastegari et al.) Step2:一个典型的 CNN 具有卷积、批规范化、激活、池化这样的四层结构,其中,池化层可以对输入运用任何种类的池化方式。但在二值化的输入(-1,1)进入到池化过程时,会产生大量的信息丢失。例如,对二值化输入进行 max-pooling 时,会导致大部分输入只剩+1,使得消息消减,精度降低。为了解决这个问题,作者改善了网络结构,改变这几层的顺序,首先实行批规范化,保证 0 均值,然后进行二值化激活,使数据都是+1 和-1,再做二值化卷积,此时由于比例因子的作用输出的不再是-1 和+1,这会相对减少信息丢失。在这里,作者建议在二值化卷积后加一个非二值化激活步骤(如 ReLU),这可以帮助训练比较复杂的网络。 具体过程如下图:
图 2:典型的 CNN 与 XNOR-Net 结构(Mohammad Rastegari et al.) XNOR-Net 团队在自主搭建的轻型神经网络框架 DarkNet 中实现了在 CPU 上 58 倍速度的提升,这意味着 XNOR-Net 可以在小内存设备上完成实时任务。事实上,在 2016 计算机视觉大会上,XNOR-Net 团队把 yolo object detection 算法的 xnor 版本在 iphone 上面做到了实时探测就成了一大亮点。XNOR-Net 的出现弥补了 BinaryNet 文章的缺失,首次让二值神经网络在 ImageNet 上面完了实验。 有趣的是,XNOR-Net 团队曾在 Github 上公开代码,甚至包括让其名声大噪的 Yolo network,但在公开发表的论文中却并没有公开 C/C++源代码而只是做了 Torch 的版本公开,曾经发布在 Github 的版本也昙花一下,不久便被撤回了。现在看来,这些举动都无疑都是为之后 XNOR-Net 的商业化做准备。 (责任编辑:本港台直播) |