梯度下降算法是神经网络反向传播用到的优化算法,可以说是最重要的内容,这一节会介绍梯度下降算法以及如何改进传统的梯度下降算法。
梯度下降
- 一维梯度下降
沿梯度反方向移动自变量可以减小函数值;
x ← x − η f ′ ( x ) x \leftarrow x-\eta f^{\prime}(x) x←x−ηf′(x)
学习率 η \eta η会控制步幅;
局部最小值会出现在不是凸函数的损失函数优化过程中。 - 多维梯度下降
∇ f ( x ) = [ ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , … , ∂ f ( x ) ∂ x d ] ⊤ x ← x − η ∇ f ( x ) \nabla f(\mathbf{x})=\left[\frac{\partial f(\mathbf{x})}{\partial x_{1}}, \frac{\partial f(\mathbf{x})}{\partial x_{2}}, \ldots, \frac{\partial f(\mathbf{x})}{\partial x_{d}}\right]^{\top}\\ \mathbf{x} \leftarrow \mathbf{x}-\eta \nabla f(\mathbf{x}) ∇f(x)=[∂x1∂f(x),∂x2∂f(x),…,∂xd∂f(x)]⊤x←x−η∇f(x) - 自适应方法
总得来说,梯度下降有这样的一种趋势:刚开始离最小值远的时候应该下降的快点,这样收敛会快些;当离最小值近的时候,步子要小一点,防止跑过头了。自适应方法都是希望能做到这样的效果。
牛顿法
在 x + ϵ x+\epsilon x+ϵ处泰勒展开:
f ( x + ϵ ) = f ( x ) + ϵ ⊤ ∇ f ( x ) + 1 2 ϵ ⊤ ∇ ∇ ⊤ f ( x ) ϵ + O ( ∥ ϵ ∥ 3 ) f(\mathbf{x}+\epsilon)=f(\mathbf{x})+\epsilon^{\top} \nabla f(\mathbf{x})+\frac{1}{2} \epsilon^{\top} \nabla \nabla^{\top} f(\mathbf{x}) \epsilon+\mathcal{O}\left(\|\epsilon\|^{3}\right) f(x+ϵ)=f(x)+ϵ⊤∇f(x)+21ϵ⊤∇∇⊤f(x)ϵ+O(∥ϵ∥3)
最小值点处满足: ∇ f ( x ) = 0 \nabla f(\mathbf{x})=0 ∇f(x)=0,即我们希望 ∇ f ( x + ϵ ) = 0 \nabla f(\mathbf{x}+ \epsilon)=0 ∇f(x+ϵ)=0,对上式关于 ϵ \epsilon ϵ求导,忽略高阶无穷小,有:
∇ f ( x ) + H f ϵ = 0 and hence ϵ = − H f − 1 ∇ f ( x ) \nabla f(\mathbf{x})+\boldsymbol{H}_{f} \boldsymbol{\epsilon}=0 \text { and hence } \epsilon=-\boldsymbol{H}_{f}^{-1} \nabla f(\mathbf{x}) ∇f(x)+Hfϵ=0 and hence ϵ=−Hf−1∇f(x)
代码实现
c = 0.5
def f(x):
return np.cosh(c * x) # Objective
def gradf(x):
return c * np.sinh(c * x) # Derivative
def hessf(x):
return c**2 * np.cosh(c * x) # Hessian
# Hide learning rate for now
def newton(eta=1):
x = 10
results = [x]
for i in range(10):
x -= eta * gradf(x) / hessf(x)
results.append(x)
print('epoch 10, x:', x)
return results
show_trace(newton())
随机梯度下降
对于有
n
n
n个样本对训练数据集,设
f
i
(
x
)
f_i(x)
fi(x)是第
i
i
i个样本的损失函数,则目标函数为:
f
(
x
)
=
1
n
∑
i
=
1
n
f
i
(
x
)
f(\mathbf{x})=\frac{1}{n} \sum_{i=1}^{n} f_{i}(\mathbf{x})
f(x)=n1i=1∑nfi(x)
其梯度为:
∇
f
(
x
)
=
1
n
∑
i
=
1
n
∇
f
i
(
x
)
\nabla f(\mathbf{x})=\frac{1}{n} \sum_{i=1}^{n} \nabla f_{i}(\mathbf{x})
∇f(x)=n1i=1∑n∇fi(x)
这就是批量梯度下降算法,可以看到其每次更新要求出所有样本对应的平均梯度,这需要
O
(
n
)
O(n)
O(n)的时间复杂度,对于
n
n
n很大的时候,这会非常慢。所以,就有了随机梯度下降算法,每求出一个样本的梯度就更新,在整个训练集中也是可以随机采样一些样本进行梯度下降算法更新。
x
←
x
−
η
∇
f
i
(
x
)
\mathbf{x} \leftarrow \mathbf{x}-\eta \nabla f_{i}(\mathbf{x})
x←x−η∇fi(x)
小批量梯度下降
是批量梯度下降与随机梯度下降算法的折中,它选择每次求出一小部分样本的平均梯度进行更新参数,一轮更新完所有样本。
有些话说
一些问题:
- 批量梯度下降(Batch Gradient Descent)、随机梯度下降(Stochastic Gradient Descent,SGD)和小批量梯度下降(Mini-Batch Gradient Descent, MBGD)的区别?各自的优缺点?