一、剪枝
1、机器学习算法决策树中的剪枝处理
剪枝(pruning)是决策树学习算法对付“过拟合”的主要手段,基本策略有“预剪枝”(prepruning)和“后剪枝”(postpruning)。
(1)预剪枝
在决策树生成过程中,对每个结点在划分前进行评估,若当前的结点划分不能带来决策树泛化性能的提升,则停止划分并将当前结点标记为叶节点。
预剪枝使得决策树的很多分支都没有“展开”,降低“过拟合”风险的同时,显著减少了决策树的训练时间和测试时间开销。
有些分支虽然在当前的划分不能提升泛化能力,但是在其基础上进行的后续划分却有可能导致性能显著提升,预剪枝基于“贪心”本质禁止这些分支展开,给预剪枝决策树带来了“欠拟合”的风险。
(2)后剪枝
先从训练集生成一颗完整的决策树,然后自底向上地对非叶节点进行评估,若将该节点对应的子树替换为叶节点能带来决策树泛化能力的提升,则将该子树替换为叶节点。
一般情况下,后剪枝往往比预剪枝保留更多的分支,后剪枝决策树的欠拟合风险更小,泛化性能往往优于预剪枝决策树。
但是,后剪枝过程是在生成完全决策树之后进行的,然后自底向上对决策树中所有的非叶节点进行逐一评估,因此其训练时间开销比未剪枝决策树和预剪枝决策树都要大得多。
常见泛化性能评估方法:留出法、交叉验证法、自助法。在研究对比不同算法的泛化性能时,通常用测试集上的判别效果来估计模型在实际使用时的泛化能力,而把训练数据另外划分为训练集和验证集(validation set),基于测试集上的性能来进行模型选择和调参。
2、神经网络模型中的剪枝处理
剪枝的总体思想为:首先评估模型中参数的重要性:一般情况下,权重越接近0的参数越不重要。然后将不重要的参数去掉,即将该参数的权重设为0,并通过稀疏矩阵进行存储。其次,在训练集上进行微调并验证模型大小和进行性能度量,如果未达到预期则不断进行迭代。
按照剪枝粒度可分为:突触剪枝、神经元剪枝、权重矩阵剪枝。
(1)突触剪枝
按照权重数值大小对参数进行排序,将权重大小排名最后参数的 k % k\% k%置为0, k % k\% k%称为压缩率。
如:剪枝后的权重矩阵:
[
0
0.4
0
0
0
0
0.4
0.7
0
0
0
0.5
0.6
0.9
0.8
0
]
\begin{bmatrix} 0 & 0.4 & 0 &0\\ 0 & 0 & 0.4 & 0.7\\ 0 & 0 & 0 & 0.5\\ 0.6 & 0.9 & 0.8 & 0 \end{bmatrix}
⎣⎢⎢⎡0000.60.4000.900.400.800.70.50⎦⎥⎥⎤
(2)神经元剪枝
神经元剪枝直接将某个结点直接去掉。对应于权重矩阵,相当于某一行和某一列置0。
一般地,计算神经元对应的一行和一列参数的权重的平方和的根,对神经元进行重要性排序,将大小排名最后的 k % k\% k%置0。
如:剪枝前权重矩阵:
[
0.3
0.4
0.2
0.01
0.01
0.02
0.4
0.7
0.2
0.3
0.1
0.5
0.6
0.9
0.8
0.01
]
\begin{bmatrix} 0.3 & 0.4 & 0.2 &0.01\\ 0.01 & 0.02 & 0.4 & 0.7\\ 0.2 & 0.3 & 0.1 & 0.5\\ 0.6 & 0.9 & 0.8 & 0.01 \end{bmatrix}
⎣⎢⎢⎡0.30.010.20.60.40.020.30.90.20.40.10.80.010.70.50.01⎦⎥⎥⎤
剪枝后权重矩阵:
[
0.3
0.4
0.2
0
0
0
0
0
0.2
0.3
0.1
0
0.6
0.9
0.8
0
]
\begin{bmatrix} 0.3 & 0.4 & 0.2 &0\\ 0 & 0 & 0 & 0\\ 0.2 & 0.3 & 0.1 & 0\\ 0.6 & 0.9 & 0.8 & 0 \end{bmatrix}
⎣⎢⎢⎡0.300.20.60.400.30.90.200.10.80000⎦⎥⎥⎤
(3)权重矩阵剪枝
突触剪枝将权重矩阵中的某些零散参数权重置为零,神经元剪枝将权重矩阵的整行和整列置为零。而权重矩阵剪枝则是把整个权重矩阵去掉。
例如:论文Are Sixteen Heads Really Better than One?(NeurIPS 2019)
作者指出Multi-Head Attention是最近最先进的自然语言处理模型的重要组成部分,如:基于Transformer的MT模型、BERT模型等。这些模型并行采用多个注意力机制,每个注意力“Head”关注输入的不同部分,使模型表达复杂的功能成为可能。
但是,事实上,深入分析Multi-Head Attention中的每个“Head”的作用,发现去掉大部分的“Head”,对整体性能影响不大。
推荐阅读:Attention Is All You Need (A groundbreaking 2017 paper)了解Attention相关知识(包括:Scaled Dot-Product Attention、Multi-Head Attention)
论文具体实现方法为:
为进行消融实验分析“Head”的重要性,修改原
M
H
A
t
t
MHAtt
MHAtt公式为:
M
H
A
t
t
(
x
,
q
)
=
∑
h
=
1
N
h
ξ
h
A
t
t
W
k
h
,
W
q
h
,
W
v
h
,
W
o
h
(
x
,
q
)
MHAtt(\mathbf{x},q)=\sum_{h=1}^{N_h}{\color{red}\xi_h}Att_{W_k^h,W_q^h,W_v^h,W_o^h}(\mathbf{x},q)
MHAtt(x,q)=h=1∑NhξhAttWkh,Wqh,Wvh,Woh(x,q)
其中,
ξ
h
\xi_h
ξh是掩码变量,其值为
{
0
,
1
}
\{0,1\}
{0,1}。当
ξ
h
=
1
\xi_h=1
ξh=1时,相当于原
M
H
A
t
t
MHAtt
MHAtt。为了掩盖“Head”,只需令
ξ
h
=
0
\xi_h=0
ξh=0。
作者首先分析单独去掉每层每个”Head“,分析BLEU的变化。可以发现去掉大多数的”Head“,对整体影响不大。
然后分析每层只保留一个最重要的“Head”,结果证明对整体性能影响不大。
二、量化
(1)伪量化
伪量化指存储时利用低精度进行量化,推理时还原为正常高精度。因为框架层有些算子只支持浮点运算,同时高精度推理准确率相对较高一些,所以,推理时需要还原为正常高精度。
**伪量化可以实现模型压缩,但对模型加速没有显著效果。**即在一定程度上可以减小空间复杂度,但对时间复杂度的减小没有多大效果。
深度神经网络模型的参数通常为32bit浮点数,伪量化在保存模型每一层时,利用低精度来保存每一个网络参数,即将32bit浮点数压缩到16bit或者8bit,甚至为1bit来进行存储。同时保存拉伸比例(scale)和零值对应的浮点数(zero_point)。在推理阶段,利用下列公式来将网络参数还原为32bit浮点数:
Q
(
x
,
s
c
a
l
e
,
z
e
r
o
_
p
o
i
n
t
)
=
r
o
u
n
d
(
x
s
c
a
l
e
+
z
e
r
o
_
p
o
i
n
t
)
Q(x,scale,zero\_point) = round(\frac{x}{scale}+zero\_point)
Q(x,scale,zero_point)=round(scalex+zero_point)
此处
r
o
u
n
d
(
)
round()
round()函数返回一个数值,该数值是按照指定的小数位数进行四舍五入运算的结果。
通常利用聚类算法,如K-means、高斯混合聚类等,来实现“伪量化”。
- 将大小相近的参数聚为一类。
- 每一类计算参数的平均值作为量化后对应的值。
- 存储每一类参数的聚类索引。索引和真实值(即类内平均值)保存在另外一张表中。
- 推理时,利用索引和映射表,恢复真实值。
一般地,当聚类数为 N N N时,压缩量为 l o g ( N ) 32 \frac{log(N)}{32} 32log(N)。
(2)定点化
定点化与伪量化相比不同点主要在于,在推理时,不需要还原为浮点数。这需要框架层实现算子的定点化运算支持。
三、知识蒸馏
知识蒸馏的大致思路:
- 训练教师网络:利用完整数据集对高度复杂的教师网络进行训练。需要高性能计算,需要在高性能GPU上训练,只能离线进行。如:利用高度复杂和超大深度的GoogleNet作为教师网络。
- 构建对应关系:设计合适的学生网络,建立起学生网络的中间输出与教师网络的对应关系,可以直接使教师网络中某一层的输出信息(或先进行数据增强)传递给学生网络。
- 通过教师网络前向传播:教师网络前向传播数据已获得所有中间输出,然后对其应用数据进行增强。
- 通过学生网络反向传播:利用教师网络的输出和学生网络中反向传播的误差关系,使学生网络能够学会复制教师网络的行为。
知识蒸馏可以引入多名教师,即将集成网络转换为单一网络;或引入助教(教师网络先教助教网络,助教网络再教学生网络。
推荐阅读:Distilling the Knowledge in a Neural Network( A groundbreaking 2015 paper)。
例如:论文Distilling Portable Generative Adversarial Networks for Image Translation(AAAI 2020)
推荐视频:https://live.yanxishe.com/room/759
目前,GANs被广泛应用在图像转化任务,但是由于其巨大的计算与存储消耗,使GANs很难被应用在移动设备上。
由于GANs独特的神经网络结构,现有的神经网络模型无法直接应用于压缩GANs。主要原因有:(1)与传统分类模型相比,因为生成网络输出维度较高,生成网络的冗余较少。(2)GANs中生成模型通常没有准确的ground-truth来评价输出结果。传统的卷积方法很难预测在GANs中复杂的权重和滤波器。(3)GANs通常包含一个生成器(generator)和判别器(discriminator),并且两个网络的训练过程类似于零和博弈,与普通的深度神经网络的分类训练有着本质的区别。
基于以上困难,本文提出一种通过知识蒸馏来学习便携式生成网络的新颖框架。教师生成器被用作最小化学生和教师网络生成的图像之间的像素和感知差异。然后,通过学习教师网络和学生网络中真实样本和生成样本之间的关系,优化学生GAN中的判别器。通过最小化优化,学生GAN可以充分继承教师GAN中的知识。
首先,让学生网络生成的图像和教师网络相同:
直接使用
L
1
L1
L1距离容易造成生成图像丢失细节语义信息,所以本文提出了基于特征的损失:
进而得出学生生成网络的蒸馏损失:
ℓ
K
D
G
(
G
S
)
=
ℓ
L
1
(
G
S
)
+
γ
ℓ
p
e
r
c
(
G
S
)
\ell_{KD}^G(G_S)=\ell_{L1}(G_S)+\gamma\ell_{perc}(G_S)
ℓKDG(GS)=ℓL1(GS)+γℓperc(GS)
对于判别网络,通常认为教师网络生成的图片质量很高,学生判别网络也将其识别为真实图片:
ℓ
G
T
(
G
S
)
=
1
n
∑
i
=
1
n
D
S
(
G
T
(
x
i
)
,
T
r
u
e
)
\ell_{G_T}(G_S)=\frac{1}{n}\sum_{i=1}^{n}D_S(G_T(x_i),\boldsymbol{True})
ℓGT(GS)=n1i=1∑nDS(GT(xi),True)
此外,还采用triplet loss在特征层上增强判别网络的判别能力:
算法过程如下:
量化实验结果:
将马生成斑马结果如下:
四、结构优化(设计高效网络结构)
1、矩阵分解
将 M × N M\times N M×N的矩阵分解为 M × K + K × N M\times K+K\times N M×K+K×N(满足 K ≪ M , K ≪ N K\ll M,K\ll N K≪M,K≪N)可以大大降低模型体积。
2、权值共享
N层共用一套参数,使参数量降低到原来的 1 N \frac{1}{N} N1。
权值共享对于模型压缩作用特别大(有效减少空间复杂度),但并不会带来计算量的减少(对时间复杂度收效甚微)。
3、低秩分解
利用奇异值分解和PQ分解,将原始张量分解为低秩的若干张量,以减少卷积运算,提升训练速度。
五、轻量化模型设计
1、AdderNet
加法在不同bit的能耗明显小于乘法:
例如:论文AdderNet: Do We Really Need Multiplications in Deep Learning?(CVPR 2020)
作者提出了一种加法神经网络(AdderNet)来替代大量的乘法运算来达到减少能耗,加快神经网络训练的目的。
卷积是CNN中最基础的结构,神经网络中绝大多数的乘法来自自卷积。卷积计算是计算特征和卷积核之间的互相关,即卷积与输入之间的互相关。而互相关本质上是一种相似性度量。本文提出利用一种新的相似性度量使其代替卷积操作,只包含计算复杂性极低的加法操作,即利用
ℓ
1
\ell_1
ℓ1距离来代替卷积运算中的互相关,利用
ℓ
1
\ell_1
ℓ1距离修改后的相似性度量如下:
Y
(
m
,
n
,
t
)
=
−
∑
i
=
0
d
∑
j
=
0
d
∑
k
=
0
c
i
n
∣
X
(
m
+
i
,
n
+
j
,
k
)
−
F
(
i
,
j
,
k
,
t
)
∣
Y(m,n,t)=-\sum_{i=0}^d\sum_{j=0}^d\sum_{k=0}^{c_{in}}|X(m+i,n+j,k)-F(i,j,k,t)|
Y(m,n,t)=−i=0∑dj=0∑dk=0∑cin∣X(m+i,n+j,k)−F(i,j,k,t)∣
其中,
F
∈
R
d
×
d
×
c
i
n
×
c
o
u
t
F\in R^{d\times d\times c_{in}\times c_{out}}
F∈Rd×d×cin×cout为卷积核,卷积核的核大小为
d
d
d,
c
i
n
c_{in}
cin为输入通道,
c
o
u
t
c_{out}
cout为输出通道,
X
∈
R
H
×
W
×
c
i
n
X\in R^{H\times W\times c_{in}}
X∈RH×W×cin为输入特征,
H
H
H和
W
W
W分别为特征的高度和宽度,
Y
∈
R
H
′
×
W
′
×
c
i
n
Y\in R^{H'\times W'\times c_{in}}
Y∈RH′×W′×cin为输出特征。
因为,加法神经网络的输出全为负数,所以需要进行批归一化,而批归一化层存在少量的乘法。相比卷积的时间复杂度 O ( d 2 c i n c o u t H W ) O(d^2c_{in}c_{out}HW) O(d2cincoutHW),批归一化层的时间复杂度只有 O ( c o u t H ′ W ′ ) O(c_{out}H'W') O(coutH′W′),相比卷积层,批归一化层的时间复杂度非常小,可忽略不计。
神经网络利用反向传播算法来计算卷积核的梯度并且利用随机梯度下降来更新参数。不同于卷积层,利用
s
g
n
(
)
sgn()
sgn()函数来定义AdderNet的梯度更新规则 :
∂
Y
(
m
,
n
,
t
)
∂
F
(
i
,
j
,
k
,
t
)
=
s
g
n
(
X
(
m
+
i
,
n
+
j
,
k
)
−
F
(
i
,
j
,
k
,
t
)
)
\frac{\partial Y(m,n,t)}{\partial F(i,j,k,t)}=sgn(X(m+i,n+j,k)-F(i,j,k,t))
∂F(i,j,k,t)∂Y(m,n,t)=sgn(X(m+i,n+j,k)−F(i,j,k,t))
因为上式不适合优化含有大量参数的深度神经网络,不利于梯度的有效更新,有绝对值函数倒数联想到
ℓ
2
\ell_2
ℓ2范数的导数:
∂
Y
(
m
,
n
,
t
)
∂
F
(
i
,
j
,
k
,
t
)
=
X
(
m
+
i
,
n
+
j
,
k
)
−
F
(
i
,
j
,
k
,
t
)
\frac{\partial Y(m,n,t)}{\partial F(i,j,k,t)}=X(m+i,n+j,k)-F(i,j,k,t)
∂F(i,j,k,t)∂Y(m,n,t)=X(m+i,n+j,k)−F(i,j,k,t)
而上式在AdderNet中可能存在梯度爆炸现象,所以在AdderNet中参数的更新定义如下:
∂
Y
(
m
,
n
,
t
)
∂
X
(
m
+
i
,
n
+
j
,
k
)
=
H
T
(
F
(
i
,
j
,
k
,
t
)
−
X
(
m
+
i
,
n
+
j
,
k
)
)
\frac{\partial Y(m,n,t)}{\partial X(m+i,n+j,k)}=HT(F(i,j,k,t)-X(m+i,n+j,k))
∂X(m+i,n+j,k)∂Y(m,n,t)=HT(F(i,j,k,t)−X(m+i,n+j,k))
其中,
H
T
(
x
)
=
{
x
−
1
<
x
<
1
,
1
x
>
1
,
−
1
x
<
−
1.
HT(x)= \begin{cases} x & -1<x<1,\\ 1 & x>1,\\ -1 & x<-1. \end{cases}
HT(x)=⎩⎪⎨⎪⎧x1−1−1<x<1,x>1,x<−1.
在传统CNN中,假设权值和输入特征是独立的,服从正态分布,而对于AdderNet则有所不同,输出的方差可以近似为:
V
a
r
[
Y
A
d
d
e
r
N
e
t
]
=
∑
i
=
0
d
∑
j
=
0
d
∑
k
=
0
c
i
n
V
a
r
[
∣
X
−
F
∣
]
=
π
2
d
2
c
i
n
(
V
a
r
[
X
]
+
V
a
r
[
F
]
)
Var[Y_{AdderNet}]=\sum_{i=0}^d\sum_{j=0}^d\sum_{k=0}^{c_{in}}Var[|X-F|]=\sqrt{\frac{\pi}{2}}d^2c_{in}(Var[X]+Var[F])
Var[YAdderNet]=i=0∑dj=0∑dk=0∑cinVar[∣X−F∣]=2πd2cin(Var[X]+Var[F])
AdderNet的输出具有较大的方差,利用常规的链式法则更新会导致梯度很小,进而导致参数更新过慢,引入基于归一化的自适应学习率调整参数的学习率组成,其参数更新量如下定义:
△
F
l
=
γ
×
α
l
×
△
L
(
F
l
)
\triangle F_l=\gamma\times\alpha _l \times \triangle L(F_l)
△Fl=γ×αl×△L(Fl)
其中,
γ
\gamma
γ为全局学习率,
α
l
=
η
k
∣
∣
△
L
(
F
l
)
∣
∣
2
\alpha _l =\frac{\eta \sqrt{k}}{||\triangle L(F_l)||_2}
αl=∣∣△L(Fl)∣∣2ηk为
l
l
l层学习率,
△
L
(
F
l
)
\triangle L(F_l)
△L(Fl)为
l
l
l层梯度。
实验结果:
推荐论文阅读:BinaryConnect: Training Deep Neural Networks with binary weights during propagations
二值神经网络要比加法神经网络更加轻量化,但是其实验结果要比加法神经网络差一点。
为快速了解CNN,推荐博客:https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53
2、MobileNet
(1)MobileNet V1:
MobileNetv1将常规卷积替换为深度可分离卷积,包含深度卷积和点态卷积。
(2)MobileNet V2:
应用 I n v e r e d R e s i d u a l B l o c k Invered\ Residual\ Block Invered Residual Block,通道数两边窄中间宽,引入DepthwiseConv,去掉最后的ReLU函数,因为ReLU会使一些神经元失活,而高维的ReLU可以保留低维特征的完整信息,同时不失非线性,采用中间宽加ReLU方式来保留低维输入信息。
(3)MobileNet V3:
MobileNetv3采用网络结构搜索(NAS)搭建一个高效的网络结构。
推荐论文:
1、MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
2、MobileNetV2: Inverted Residuals and Linear Bottlenecks
3、Searching for MobileNetV3
3、ShuffleNet
推荐论文阅读:
1、ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices
2、ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
4、Xception
核心思想为深度分离卷积。
推荐论文阅读:Xception: Deep Learning with Depthwise Separable Convolutions
5、GhostNet
利用Ghost模块构建高效的神经网络结构。Ghost模块将原始卷积层分为两部分,首先利用较少的卷积核来生成原始特征图,然后进一步使用廉价变换操作以高效生产更多的幻影特征图,该模块可以实现即插即用。
推荐论文阅读:GhostNet: More Features from Cheap Operations(CVPR 2020)
6、SandGlass
作者发现通过引入逆残差学习和线性瓶颈层来对经典的残差瓶颈模块进行优化存在信息损失和梯度混淆的缺点。本论文提出对该结构进行镜像并提出一种新颖的瓶颈模块 S a n d G l a s s B l o c k SandGlass \ Block SandGlass Block,其在高维进行恒等映射与空间变换,可以有效缓解信息损失与梯度混淆。
实验证明:
在ImageNet分类任务中,采用 S a n d G l a s s B l o c k SandGlass \ Block SandGlass Block替换MobileNetv2中的 I n v e r e d R e s i d u a l B l o c k Invered\ Residual\ Block Invered Residual Block,可以获得1.7%的性能提升,并且不会导致额外的参数量和计算量提升。将 S a n d G l a s s B l o c k SandGlass \ Block SandGlass Block嵌入到网络结构搜索(NAS)中,可以获得0.13%的性能提升且参数量降低25%。
推荐论文阅读:Rethinking Bottleneck Structure for Efficient Mobile Network Design
参考博客网址:
[1]https://zhuanlan.zhihu.com/p/141313526
[2]https://my.oschina.net/u/1416903/blog/4532261
[3]https://zhuanlan.zhihu.com/p/357348544
参考文献:
周志华.机器学习[M].北京:清华大学出版社.2019:79-83