前言
本人在研究网络剪枝的时候遇到了一些问题,例如:
- 剪枝的论文里经常出现的Hessian矩阵是用来干嘛的?
- 都说Hessian矩阵计算和存储消耗大,那目前的研究都在如何优化Hessian矩阵?
本文将从一些基本概念开始,梳理一下Hessian矩阵的来龙去脉。
什么是神经网络?
神经网络是启发于人脑中神经元的连接和交互方式而设计出的一种人工智能模型。
神经网络本质就是一个复杂函数的映射:
Y ^ = F ( X ) = w 1 x 1 + w 2 x 2 . . . w n x n = [ w 1 w 2 ⋯ w n ] [ x 1 x 2 ⋯ x n ] \widehat{Y} = F(X)=w_1x_1+w_2x_2...w_nx_n=\begin{bmatrix} w_1 w_2 \cdots w_n \end{bmatrix}\begin{bmatrix} x_1 \\ x_2 \\ \cdots \\ x_n \end{bmatrix} Y =F(X)=w1x1+w2x2...wnxn=[w1w2⋯wn] x1x2⋯xn
模型的预测值与实际值之间的差异叫做“损失(Loss)”,这个损失也可以写成函数形式: L o s s ( Y ^ , Y ) Loss(\widehat{Y}, Y) Loss(Y ,Y)
损失函数有很多种,常见的有:
①均方差损失 (Mean Squared Error Loss, MSE),或称L2 Loss损失:
L o s s M S E ( Y ^ , Y ) = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 Loss_{MSE}(\widehat{Y}, Y)=\frac{1}{\mathrm{~n}} \sum_{\mathrm{i}=1}^{\mathrm{n}}\left(\mathrm{y}_{\mathrm{i}}-\hat{\mathrm{y}}_{\mathrm{i}}\right)^{2} LossMSE(Y ,Y)= n1∑i=1n(yi−y^i)2
②交叉熵损失函数(Cross-entropy loss function,CE):
L o s s C E ( Y ^ , Y ) = − 1 n ∑ i n [ y i log y ^ i + ( 1 − y i ) log ( 1 − y ^ i ) ] Loss_{CE}(\widehat{Y}, Y)=-\frac{1}{\mathrm{~n}} \sum_{\mathrm{i}}^{\mathrm{n}}\left[\mathrm{y}_{\mathrm{i}} \log \hat{y}_{i}+\left(1-\mathrm{y}_{\mathrm{i}}\right) \log \left(1-\hat{y}_{i}\right)\right] LossCE(Y ,Y)=− n1∑in[yilogy^i+(1−yi)log(1−y^i)]
为什么梯度下降法使得神经网络具有学习能力
所谓的学习能力就是模仿能力。在机器学习中,叫做“拟合(Fitting)”。在数学上,叫做“逼近(Approximation)”。
在机器学习中,学习的过程就是权重更新的过程,可以表示为: w t + 1 = w t + Δ w w_{t+1}=w_t +\Delta{w} wt+1=wt+Δw
对于权重 w i w_i wi,其梯度为损失函数的一阶导数: Δ w i = − η ∂ L o s s ∂ w i \Delta w_{i}=-\eta \frac{\partial Loss}{\partial w_{i}} Δwi=−η∂wi∂Loss
假设模型复杂一点,有两层: Y ^ = G ( F ( X ) ) \widehat{Y} = G(F(X)) Y =G(F(X))
则通过链式法可得到每层权重的更新值: ∂ L o s s ∂ w i = ∂ L o s s ∂ G ⋅ ∂ G ∂ F ⋅ ∂ F ∂ w i \frac{\partial Loss}{\partial w_i}=\frac{\partial Loss}{\partial G} \cdot \frac{\partial G}{\partial F}\cdot \frac{\partial F}{\partial w_i} ∂wi∂Loss=∂G∂Loss⋅∂F∂G⋅∂wi∂F
注意:对于模型的映射函数来说,模型的输入 X X X为自变量。对于损失函数来说,模型的权重 W W W才是自变量。我们是要求损失函数的最小值不是模型映射的最小值,这里容易混淆。
以上均是教材中的说法,下面有个更加通俗易懂的说法。
①想象你在一个三维的地形中,这个地形代表了损失函数的图像。你的任务是找到这个地形的最低点,最低点就是损失函数的最小值。地形上的每个点都对应着一个解,解就对应着神经网络的权重。这个地形是无穷尽的,地形上的所有点也叫做解空间。整个地形的最低点对应的权重就是神经网络训练好后的权重。对于服从同一分布的数据,其解空间也是同一的。因此对于一个数据集来说,其解空间中的最优解是唯一的。
② 一开始,你随机掉落在这个地形的某个位置,也就是初始化权重。想要到达最低点,如果没有任何工具你只能乱走。你需要一只指南针,这个指南针就是梯度。梯度方向就是函数图像的切线方向,梯度的正负号表示函数的增减,梯度的值表示函数的增长速率。切向方向表示函数上某点向上的最陡峭的方向,那么其相反方向则为最快向下方向。
③现在你知道下山的方向了,还需要知道每一步要走多远。前面更新权重中有一个变量 η \eta η,叫做学习率,用于控制步长。假设没有学习率,也就是当 η = 1 \eta=1 η=1时。就意味着每次下山,你都朝着最陡的方向迈最大的步子。这就可能导致你永远也到达不了山底,而是在山间反复横跳。想要到达山底就需要动态调整步子,越接近山底步子就越小,也就是衰减学习率。
一阶导数的理解
一阶导数描述了函数值随自变量的变化速度。
一阶导数也可以描述函数在某点的局部行为,比如它是在上升还是在下降。
如果函数上某点的一阶导数为零,那么这个点可能是函数的极值点。
二阶导数的理解
二阶导数描述了变化速率的变化速率。
二阶导数可以判断函数曲线是向上弯曲(凸)还是向下弯曲(凹)。
当函数上某点的二阶导数为零时,也称为拐点,在这一点上函数的凹凸性发生变化。
对于一个多变量函数 f ( x i , x j ) f(x_i, x_j) f(xi,xj),二阶导数指的是函数相对于其变量的二阶偏导数。
保持另一变量不变,对自身求两次偏导: ∂ 2 f ∂ x i 2 \frac{\partial^{2} f}{\partial x_{i}^{2}} ∂xi2∂2f、 ∂ 2 f ∂ x j 2 \frac{\partial^{2} f}{\partial x_{j}^{2}} ∂xj2∂2f
在自变量之间,还要求混合偏导,根据顺序有: ∂ 2 f ∂ x i ∂ x j \frac{\partial^{2} f}{\partial x_{i}\partial x_{j}} ∂xi∂xj∂2f、 ∂ 2 f ∂ x j ∂ x i \frac{\partial^{2} f}{\partial x_{j}\partial x_{i}} ∂xj∂xi∂2f
二阶信息的理解
本文的主题来了!
Hessian矩阵是上述所有二阶偏导数的集合,它是一个方形矩阵。大小为
n
×
n
n\times n
n×n
H
=
[
∂
2
f
∂
x
1
2
∂
2
f
∂
x
1
∂
x
2
⋯
∂
2
f
∂
x
1
∂
x
n
∂
2
f
∂
x
2
∂
x
1
∂
2
f
∂
x
2
2
⋯
∂
2
f
∂
x
2
∂
x
n
⋮
⋮
⋱
⋮
∂
2
f
∂
x
n
∂
x
1
∂
2
f
∂
x
n
∂
x
2
⋯
∂
2
f
∂
x
n
2
]
H = \begin{bmatrix} \frac{\partial^2 f}{\partial x_1^2} & \frac{\partial^2 f}{\partial x_1 \partial x_2} & \cdots & \frac{\partial^2 f}{\partial x_1 \partial x_n} \\ \frac{\partial^2 f}{\partial x_2 \partial x_1} & \frac{\partial^2 f}{\partial x_2^2} & \cdots & \frac{\partial^2 f}{\partial x_2 \partial x_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial^2 f}{\partial x_n \partial x_1} & \frac{\partial^2 f}{\partial x_n \partial x_2} & \cdots & \frac{\partial^2 f}{\partial x_n^2} \end{bmatrix}
H=
∂x12∂2f∂x2∂x1∂2f⋮∂xn∂x1∂2f∂x1∂x2∂2f∂x22∂2f⋮∂xn∂x2∂2f⋯⋯⋱⋯∂x1∂xn∂2f∂x2∂xn∂2f⋮∂xn2∂2f
- Hessian矩阵中的每个元素 H i j H_{ij} Hij都是对应变量对函数曲率的贡献。
- 矩阵的特征值:
- 如果存在一个标量 λ \lambda λ使得 H v = λ v Hv=\lambda v Hv=λv,则称 λ \lambda λ是Hessian矩阵的一个特征值,而 v v v是对应的特征向量。通过特征方程可以求出矩阵的所有特征值。一个 n × n n\times n n×n的矩阵最多有 n n n个特征值。
- 特征向量 v v v 表示函数在参数空间中变化最快的方向,而特征值 λ \lambda λ 表示了在这个方向上的曲率。
- 特征值描述了线性变换下,向量在特定方向上的伸缩因子。
- 在优化问题中,特征值用于确定最优解的方向。例如,在主成分分析(PCA)中,数据协方差矩阵的最大特征值对应的特征向量指向数据方差最大的方向。
- 对于任一矩阵(方阵)都可以求特征值,但是Hessian矩阵的特征值有特殊意义。
- Hessian矩阵的特征值(即矩阵的对角化结果中的系数)告诉我们函数在各个方向上的凹凸性。如果所有特征值都是正的,那么函数在当前点是局部凸的;如果都是负的,则是局部凹的。
- Hessian矩阵的特征值可以告诉我们函数在不同方向上的曲率。特征值较大的方向对应于函数曲率较大的方向,而特征值较小的方向对应于曲率较小的方向。
- 简单理解,凹凸性描述了这个地形上可能有窝,曲率描述了这个窝的深浅。在优化问题中,我们尽可能朝着一个很深的窝往下走。
- 在损失函数中,Hessian矩阵的特征向量描述了函数变化速度最快的方向,这与之前说一阶导数是函数变化最快的方向有矛盾吗?
- 一阶导数是函数相对于其变量的第一反应,梯度描述了函数在特定点沿各个自变量方向的变化率大小。梯度只提供了一阶局部线性近似的信息,它不考虑更高阶的曲率信息。
- Hessian矩阵的特征向量和特征值描述了函数在其二阶泰勒展开中的局部曲率特性。特征向量表示了函数曲率最大的方向,而特征值表示了在这些方向上的曲率大小。
- 在之前的三维地形中,一阶信息表示最陡峭的方向,二阶信息表示这个方向是否稳定,如果曲率是正的,那么这个方向是一个稳定的下降方向。
还有哪些优化方法?
前面说的梯度下降法只是优化算法中的一种,因其原理直观、易于实现、计算与存储消耗少,被广泛使用。
梯度下降法: W t + 1 = W t − η ∇ L o s s W_{t+1}=W_t-\eta \nabla Loss Wt+1=Wt−η∇Loss
还有一种基于二阶信息的优化算法
牛顿法: W t + 1 = W t − H − 1 ∇ L o s s W_{t+1}=W_t- H^{-1}\nabla Loss Wt+1=Wt−H−1∇Loss
牛顿法收敛速度快,但其需要计算Hessian矩阵及其逆,计算存储成本高,且计算逆的过程不稳定,因此在大规模优化问题上牛顿法不是首选优化算法。
为了避免直接计算Hessian矩阵及其逆,可通过更简单、更高效的方式来近似Hessian矩阵或其逆,称为拟牛顿法。
拟牛顿法: W t + 1 = W t − η H − 1 ^ ∇ L o s s W_{t+1}=W_t- \eta \widehat{H^{-1}}\nabla Loss Wt+1=Wt−ηH−1 ∇Loss
H − 1 ^ \widehat{H^{-1}} H−1 为 H − 1 H^{-1} H−1的近似,常见方法有BFGS 和 DFP 方法
二阶信息的作用
前面说了,Hessian矩阵可以用于权重的更新,例如牛顿法。
- Hessian矩阵是一个完整的二阶导数矩阵,但在某些场景下,我们用不到一个完整的Hessian矩阵。我们只需要知道其某些主要方向上的信息即可,基于Hessian矩阵计算出的信息统称为二阶信息。
- 在网络剪枝领域,通过分析Hessian矩阵的特征值可以判断权重的对损失函数的贡献。大的特征值对应的权重对损失函数的变化更加敏感,该权重对网络的输出更为重要。根据Hessian矩阵的特征值和剪枝比例可以确定剪枝权重的阈值。
- 在结构化剪枝中,每个通道或层的 Hessian 矩阵的迹(trace),迹可以视为Hessian 矩阵所有对角元素的和,迹代表了该通道或层的整体敏感度。
- 在动态剪枝方法中,在训练过程中定期计算 Hessian 矩阵,并据此调整剪枝策略,有助于实现更高效的模型压缩。
更高阶的信息的理解
前面说了一阶、二阶信息。那么三阶信息以及更高阶信息又如何理解?有哪些应用?
三阶导数描述了函数曲率的变化率,以此类推更高阶的导数就是描述变化率的变化率的变化率…
对于简单的问题(如线性回归、逻辑回归),一阶信息足以高效地求解。
对于稍微复杂的问题(如非线性模型的训练,非凸的或者存在多个局部极值点),需要二阶信息来确保算法的稳定性和收敛速度,在非凸问题中,函数可能有多个局部极值点。一阶信息可能不足以区分这些极值点,而二阶信息可以帮助确定哪个极值点是全局最优的。二阶优化算法(如牛顿法)在理论上可以提供比一阶算法更快的收敛速度,尤其是在接近最优解时。
在机器学习领域,一般用到二阶信息就足够了,更高阶意味着更高的计算量,神经网络的特点就是参数量大,层数多。目前计算二阶信息都快吃不消了。
对于更复杂的问题(如非线性、多变量相互作用、动态变化或者高度的不确定性),可能需要更高阶的信息来描述系统的复杂行为。在非线性动力学系统领域,通过分析系统的高阶导数,可以揭示系统的稳定性、分岔行为和混沌特性。在量子力学领域,高阶导数在量子力学中用于分析系统的能级变化和量子态的演化。
参考资料
[1] 周志华.机器学习[M].清华大学出版社,2016.
[2] https://kimi.moonshot.cn/