梯度
首先,从直观的角度理解这个概念。想象你站在一座山的某个位置,这座山的地形可以用一个二元函数 z = f ( x , y ) z = f(x,y) z=f(x,y)来表示。普通的偏导数就像是你只能沿着正东方向( x x x轴)或正北方向( y y y轴)移动时,海拔的变化率。但实际上,你完全可以朝任意方向行走,比如东北方向。这时,你就需要方向导数来描述沿着这个任意方向时函数值的变化率。
数学化地说,方向导数是函数在某一点沿着特定方向的变化率。如果我们用单位向量
l
=
(
cos
α
,
sin
α
)
l = (\cos \alpha, \sin \alpha)
l=(cosα,sinα)来表示方向,那么函数
f
(
x
,
y
)
f(x,y)
f(x,y)在点
(
x
0
,
y
0
)
(x_0, y_0)
(x0,y0)沿着向量
l
l
l的方向导数可以表示为:
∂
f
∂
l
=
lim
t
→
0
f
(
x
0
+
t
cos
α
,
y
0
+
t
sin
α
)
−
f
(
x
0
,
y
0
)
t
\frac{{\partial f}}{{\partial l}}= \mathop {\lim}\limits_{t \to 0} \frac{f (x_0+t \cos \alpha,y_0+t \sin \alpha)-f(x_0,y_0)}{t}
∂l∂f=t→0limtf(x0+tcosα,y0+tsinα)−f(x0,y0)
它描述的是一个很自然的过程:我们沿着方向
l
l
l走一小段距离
t
t
t,看看函数值的变化与这段距离的比值在
t
t
t趋近于
0
0
0时的极限。
如果函数在该点可微,方向导数可以用偏导数来表示:
∂
f
∂
l
=
∂
f
∂
x
cos
α
+
∂
f
∂
l
sin
α
\frac{{\partial f}}{{\partial l}}=\frac{{\partial f}}{{\partial x}} \cos \alpha + \frac{{\partial f}}{{\partial l}} \sin \alpha
∂l∂f=∂x∂fcosα+∂l∂fsinα
即任意方向的变化率都可以由最基本的
x
x
x方向和
y
y
y方向的变化率组合而成。如果熟悉向量的点积,就会发现这实际上就是梯度向量与方向向量的点积:
∂
f
∂
l
=
∇
f
⋅
l
\frac{{\partial f}}{{\partial l}}=\nabla f \cdot l
∂l∂f=∇f⋅l
方向导数将偏导数的概念推广到了任意方向,而梯度则自然地统一了所有方向的变化率。
一. 梯度的定义
对于一个多元函数
f
(
x
1
,
x
2
,
.
.
.
,
x
n
)
f(x_1, x_2, ..., x_n)
f(x1,x2,...,xn),它在某点
P
P
P处的各个偏导数描述了函数在该点沿着各个坐标轴方向的变化率。由这些偏导数组成的向量即这个点的梯度:
∇
x
f
=
(
∂
f
∂
x
1
,
∂
f
∂
x
2
,
∂
f
∂
x
3
⋯
∂
f
∂
x
n
)
T
{\nabla _{\boldsymbol{x}}}f = {(\frac{{\partial f}}{{\partial {x_1}}},\frac{{\partial f}}{{\partial {x_2}}},\frac{{\partial f}}{{\partial {x_3}}} \cdots \frac{{\partial f}}{{\partial {x_n}}})^T}
∇xf=(∂x1∂f,∂x2∂f,∂x3∂f⋯∂xn∂f)T
- 几何意义:梯度向量的方向指向函数在该点增长最快的方向。这很像在山地上寻找最陡峭的上坡方向——如果你站在山的某处,梯度就指向你脚下最陡的上坡方向(注意这里指的上坡方向并不是说在这个点的一个切线方向,而是人要面对的方向,也就是平行于地面的一个方向)。而梯度向量的长度则表示了这个最大变化率的大小。
- 等高线(面)的关系:在二维或高维空间中,梯度向量总是与等高线(面)正交。这就解释了为什么梯度指向最陡峭的方向——因为它选择了与等高线最"不平行"的方向。
e g : eg: eg:
假设有一个函数
f
(
x
,
y
)
=
x
2
+
2
y
2
f(x,y)=x^2 + 2y^2
f(x,y)=x2+2y2
在点
(
1
,
1
)
(1,1)
(1,1)处,其梯度为
(
2
,
4
)
(2,4)
(2,4),即


这说明,在点 ( 1 , 1 ) (1,1) (1,1)处,函数沿着向量 ( 2 , 4 ) (2,4) (2,4)方向增长最快,而增长率正是这个向量的长度 2 2 + 4 2 = 2 5 \sqrt{2^2 + 4^2} = 2\sqrt{5} 22+42=25。
在机器学习中我们还会经常遇到自变量和函数值都是向量的函数,称为向量值函数。设
f
:
R
n
→
R
\boldsymbol{f}:\mathbb{R}^n \to \mathbb{R}
f:Rn→R是向量值函数,那么函数值的每一维都是一个
n
n
n 元标量函数 (即有
n
n
n个未知数):
f
(
x
)
=
(
f
1
(
x
1
,
.
.
.
,
x
n
)
,
f
2
(
x
1
,
.
.
.
,
x
n
)
,
f
n
(
x
1
,
.
.
.
,
x
n
)
)
T
\boldsymbol{f(x)}=(f_1(x_1,...,x_n),f_2(x_1,...,x_n),f_n(x_1,...,x_n))^T
f(x)=(f1(x1,...,xn),f2(x1,...,xn),fn(x1,...,xn))T
e
g
:
\textcolor{red}{eg}:
eg:
f
(
x
)
=
(
a
11
x
1
+
a
12
x
2
+
⋯
+
a
1
n
x
n
a
21
x
1
+
a
22
x
2
+
⋯
+
a
2
n
x
n
⋮
a
n
1
x
1
+
a
n
2
x
2
+
⋯
+
a
n
n
x
n
)
\boldsymbol{f(x)}=\left({\begin{aligned} & a_{11} x_1+a_{12} x_2+\cdots+a_{1 n} x_n \\ & a_{21} x_1+a_{22} x_2+\cdots+a_{2 n} x_n \\ & \vdots \\ & a_{n 1} x_1+a_{n 2} x_2+\cdots+a_{n n} x_n \end{aligned}} \right)
f(x)=
a11x1+a12x2+⋯+a1nxna21x1+a22x2+⋯+a2nxn⋮an1x1+an2x2+⋯+annxn
向量值函数求导结果为矩阵,称为雅可比矩阵(Jacobian matrix),通常用
∇
f
\boldsymbol{ \nabla f}
∇f或者
J
f
\boldsymbol{J}_f
Jf表示。设
f
:
R
n
→
R
\boldsymbol{f}:\mathbb{R}^n \to \mathbb{R}
f:Rn→R,其对自变量
x
\boldsymbol{x}
x的梯度是一个
m
×
n
m \times n
m×n维的矩阵:
∇
x
f
=
(
∇
x
T
f
1
⋮
∇
x
T
f
m
)
=
(
∂
f
1
∂
x
1
⋯
∂
f
1
∂
x
n
⋮
⋮
∂
f
m
∂
x
1
⋯
∂
f
m
∂
x
n
)
\nabla_{\boldsymbol{x}} \boldsymbol{f} = \left(\begin{array}{c} \nabla_{\boldsymbol{x}}^{\mathrm{T}} \boldsymbol{f}_1 \\ \vdots \\ \nabla_{\boldsymbol{x}}^{\mathrm{T}} \boldsymbol{f}_m \end{array}\right) = \left(\begin{array}{ccc} \frac{\partial f_1}{\partial x_1} & \cdots & \frac{\partial f_1}{\partial x_n} \\ \vdots & & \vdots \\ \frac{\partial f_m}{\partial x_1} & \cdots & \frac{\partial f_m}{\partial x_n} \end{array}\right)
∇xf=
∇xTf1⋮∇xTfm
=
∂x1∂f1⋮∂x1∂fm⋯⋯∂xn∂f1⋮∂xn∂fm
其中
∇
T
\nabla^T
∇T表示先求梯度再转置
如果对梯度
∇
f
\nabla f
∇f再求一次梯度,得到的矩阵就称为的海瑟矩阵(Hessian matrix):
H
f
=
∇
2
f
(
x
)
=
(
∂
2
f
∂
x
1
2
⋯
∂
2
f
∂
x
1
∂
x
n
⋮
⋮
∂
2
f
∂
x
n
∂
x
1
⋯
∂
2
f
∂
x
n
2
)
\boldsymbol{H}_f=\nabla^2 f(\boldsymbol{x})=\left(\begin{array}{ccc} \frac{\partial^2 f}{\partial x_1^2} & \cdots & \frac{\partial^2 f}{\partial x_1 \partial x_n} \\ \vdots & & \vdots \\ \frac{\partial^2 f}{\partial x_n \partial x_1} & \cdots & \frac{\partial^2 f}{\partial x_n^2} \end{array}\right)
Hf=∇2f(x)=
∂x12∂2f⋮∂xn∂x1∂2f⋯⋯∂x1∂xn∂2f⋮∂xn2∂2f
二. 梯度下降
2.1 梯度下降的定义
梯度下降 (Gradient Descent) 是机器学习中用于优化目标函数(通常是损失函数)的核心算法。其核心思想是通过迭代调整模型参数,沿着目标函数梯度的反方向逐步逼近最小值点。
假设目标函数为 J ( θ ) J(\theta) J(θ),其中 θ \theta θ是模型参数。梯度下降的目标是找到使得最小 J ( θ ) J(\theta) J(θ)的 θ \theta θ。通过以下步骤实现:
-
初始化参数:随机或指定初始值 θ 0 \theta_0 θ0。
-
计算梯度:找到当前参数 θ \theta θ处的梯度 ∇ J ( θ ) \nabla J(\theta) ∇J(θ)。
∇ J ( θ ) = ( ∂ f ∂ θ 1 , ∂ f ∂ θ 2 , ∂ f ∂ θ 3 ⋯ ∂ f ∂ θ n ) T \nabla J(\theta)={(\frac{{\partial f}}{{\partial {\theta_1}}},\frac{{\partial f}}{{\partial {\theta_2}}},\frac{{\partial f}}{{\partial {\theta_3}}} \cdots \frac{{\partial f}}{{\partial {\theta_n}}})^T} ∇J(θ)=(∂θ1∂f,∂θ2∂f,∂θ3∂f⋯∂θn∂f)T
- 更新参数:沿梯度反方向调整参数,即 θ n e w = θ o l d − η ∇ J ( θ ) \theta_{new}=\theta_{old}-\eta \nabla J(\theta) θnew=θold−η∇J(θ),其中 η \eta η是学习率(步长)。
- 迭代:重复步骤2-3,直到收敛(如梯度接近零或达到最大迭代次数)。
e g eg eg:线性回归的梯度推导。
模型: h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + … + θ n x n h_\theta(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \ldots + \theta_n x_n hθ(x)=θ0+θ1x1+θ2x2+…+θnxn
损失函数(MSE): J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^m \left( h_\theta(x^{(i)}) - y^{(i)} \right)^2 J(θ)=2m1∑i=1m(hθ(x(i))−y(i))2
梯度计算: ∂ J ∂ θ j = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \frac{\partial J}{\partial \theta_j} = \frac{1}{m} \sum_{i=1}^m \left( h_\theta(x^{(i)}) - y^{(i)} \right) x_j^{(i)} ∂θj∂J=m1∑i=1m(hθ(x(i))−y(i))xj(i)
对所有参数 θ j \theta_j θj计算偏导,得到梯度向量 ∇ J ( θ ) \nabla J(\theta) ∇J(θ)
2.2 梯度下降的类型
- 批量梯度下降(Batch Gradient Descent, BGD)
公式:
θ
new
=
θ
old
−
η
⋅
1
m
∑
i
=
1
m
∇
J
(
θ
old
,
x
(
i
)
,
y
(
i
)
)
\theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \frac{1}{m} \sum_{i=1}^m \nabla J(\theta_{\text{old}}, x^{(i)}, y^{(i)})
θnew=θold−η⋅m1i=1∑m∇J(θold,x(i),y(i))
特点:
- 优点:稳定收敛,适用于凸函数。
- 缺点:计算开销大(每次迭代需遍历全部数据),不适合大规模数据。
- 随机梯度下降(Stochastic Gradient Descent, SGD)
公式:
θ
new
=
θ
old
−
η
⋅
∇
J
(
θ
old
,
x
(
i
)
,
y
(
i
)
)
\theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla J(\theta_{\text{old}}, x^{(i)}, y^{(i)})
θnew=θold−η⋅∇J(θold,x(i),y(i))
每次随机选取一个样本 i i i
特点:
- 优点:计算快,适合在线学习和非凸函数。
- 缺点:更新方向波动大,收敛路径不稳定。
- 小批量梯度下降(Mini-batch Gradient Descent)
公式:
θ
new
=
θ
old
−
η
⋅
1
b
∑
i
=
1
b
∇
J
(
θ
old
,
x
(
i
)
,
y
(
i
)
)
\theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \frac{1}{b} \sum_{i=1}^b \nabla J(\theta_{\text{old}}, x^{(i)}, y^{(i)})
θnew=θold−η⋅b1i=1∑b∇J(θold,x(i),y(i))
每次选取 b b b个样本,通常 b = 32 , 64 , 128 b = 32, 64, 128 b=32,64,128
特点:
- 优点:平衡计算效率和稳定性(深度学习中的默认选择)。
- 缺点:需调参batch size。
2.3 学习率与收敛性
学习率 η \eta η的作用
过大:参数更新步幅过大,可能导致震荡甚至发散。
过小:收敛速度慢,易陷入局部极小值。
三. 梯度下降的改进算法
3.1 动量法
动量法通过在传统的梯度下降算法中引入“动量”概念来改变更新参数的方式。其核心思想是通过累积梯度的历史信息,来决定当前梯度的更新方向,从而加速收敛并避免陷入局部最优解。
想象一下正在滑雪。普通的梯度下降法就像是每一步都完全依据当前坡度来决定移动方向和距离。但实际滑雪时,你会带着之前运动产生的惯性继续前进。这就是动量法的核心思想 - 它不仅考虑当前的梯度,还会考虑之前的运动"惯性"。
从数学角度来看,动量法的更新规则是:
v t + 1 = β v t + η ∇ f ( x ) v_{t+1}=\beta v_t+ \eta \nabla f(\boldsymbol x) vt+1=βvt+η∇f(x)
θ t + 1 = θ t − v t + 1 \theta_{t+1}=\theta_t-v_{t+1} θt+1=θt−vt+1
其中:
- β \beta β是动量系数,控制“记忆”对当前更新的影响程度。一般设定为接近于1,如0.9。
-
v
t
v_t
vt是动量变量,表示上一次更新的“记忆”。
3.2 Adaptive Gradient (AdaGrad)
在传统的梯度下降中,所有参数使用相同的学习率。这就像是在登山时,无论地形如何,都用相同的步长走路。但实际上,有些参数可能需要更大的调整,有些则需要更小的调整。
AdaGrad的更新规则是:
θ
i
(
t
+
1
)
=
θ
i
(
t
)
−
η
g
i
(
t
)
+
ε
∇
θ
i
f
t
\theta_{i}(t+1)=\theta_i(t)-\frac{\eta}{\sqrt{g_i(t)+\varepsilon}}\nabla_{\theta_i}f_t
θi(t+1)=θi(t)−gi(t)+εη∇θift
其中:
-
η \eta η是全局学习率
-
∇ θ i f t \nabla_{\theta_i}f_t ∇θift是函数相对于参数 θ i \theta_i θi在 t t t时间步长的梯度。
-
g i ( t ) g_i(t) gi(t)是参数 θ i \theta_i θi的累积梯度的平方和。
g i ( 1 ) = 1 2 ( ∇ θ i f 0 2 + ∇ θ i f 1 2 ) g_i(1)=\sqrt{\frac{1}{2}(\nabla_{\theta_i}f^2_0+\nabla_{\theta_i}f^2_1)} gi(1)=21(∇θif02+∇θif12); g i ( 2 ) = 1 3 ( ∇ θ i f 0 2 + ∇ θ i f 1 2 + ∇ θ i f 2 2 ) g_i(2)=\sqrt{\frac{1}{3}(\nabla_{\theta_i}f^2_0+\nabla_{\theta_i}f^2_1+\nabla_{\theta_i}f^2_2)} gi(2)=31(∇θif02+∇θif12+∇θif22)
-
ε \varepsilon ε 是一个小常数,用于避免除零错误。
AdaGrad的优势主要体现在以下几个方面:
- 参数自适应:对于经常更新的参数,累积的梯度平方和会较大,从而降低更新步长。相反,对于不经常更新的参数,可以保持较大的更新步长。这特别适合处理稀疏数据,比如自然语言处理中的词向量学习。
- 无需手动调整学习率:算法会自动为每个参数调整合适的学习率,减少了手动调参的工作量。
AdaGrad也有一个主要的局限性,由于分母会不断累积,学习率会持续下降,可能导致在训练后期学习过慢。 Root Mean Squared propagation (RMSprop) 进行了稍微的改进,即分母不再是简单的平方和,而是对于当下梯度和累积梯度赋予不同的权重来更新参数。
3.3 Adaptive moment estimation(Adam)
在深度学习中,Adam是一种最常用的优化器。它可以看作RMSprop加上动量,其使用动量作为参数更新方向,并且能够自
适应调整学习率。
Adam算法的核心步骤包括:
- 一阶矩(均值):一阶矩表示梯度的加权平均,类似于动量法。它反映了梯度的总体方向。
- 二阶矩(方差):二阶矩表示梯度的方差(或者梯度平方的加权平均)。它有助于对每个参数的更新进行尺度调整,使得更新较小的参数得到较大的学习率,更新较大的参数得到较小的学习率。
Adam算法的更新规则
假设我们在训练过程中需要优化的目标函数为 J ( θ ) J(\theta) J(θ),其中 θ \theta θ表示参数。Adam的更新规则如下:
- 初始化:
- 设定学习率 η \eta η。
- 设置两个参数:一阶矩的初始估计 m 0 = 0 m_0 = 0 m0=0,二阶矩的初始估计 v 0 = 0 v_0 = 0 v0=0。
- 设置平滑项 ϵ \epsilon ϵ,防止除零错误,通常设置为 ϵ = 1 0 − 8 \epsilon = 10^{-8} ϵ=10−8。
- 在每次迭代 t t t时:
- 计算梯度 g t g_t gt:
g t = ∇ θ J ( θ t ) g_t=\nabla_\theta J(\theta_t) gt=∇θJ(θt)
- 更新一阶矩估计(梯度的均值):
m t = β 1 m t − 1 + ( 1 − β 1 ) g t m_t = \beta_1m_{t-1}+(1-\beta_1)g_t mt=β1mt−1+(1−β1)gt
其中 β 1 \beta_1 β1是一阶矩的衰减率(通常设置为 0.9 0.9 0.9)。
- 更新二阶矩估计(梯度的平方的均值):
v 2 = β 2 v t − 1 + ( 1 − β 2 ) g t 2 v_2 = \beta_2v_{t-1}+(1-\beta_2)g_t^2 v2=β2vt−1+(1−β2)gt2
其中 β 2 \beta_2 β2是二阶矩的衰减率(通常设置为 0.999 0.999 0.999)。
- 进行偏差校正:由于 m t m_t mt和 v t v_t vt在初期会受到偏差(因为它们在最开始时被初始化为 0 0 0),需要进行偏差校正:
m ^ t = m t 1 − β 1 t \hat{m}_t=\frac{m_t}{1-\beta_1^t} m^t=1−β1tmt
v ^ t = v t 1 − β 2 t \hat{v}_t=\frac{v_t}{1-\beta_2^t} v^t=1−β2tvt
- 更新参数:
θ t + 1 = θ t − η v ^ t + ϵ m ^ t \theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\hat{v}_t+\epsilon}}\hat{m}_t θt+1=θt−v^t+ϵηm^t
这里,更新的学习率由 m ^ t \hat{m}_t m^t和 v ^ t \hat{v}_t v^t 的比值决定,从而实现自适应的学习率调整。
本文中的部分图片引自《李宏毅深度学习教程》(LeeDL Tutorial)