梯度下降法(Gradient Descent,GD)是机器学习中常见的一种迭代优化算法,它根据目标函数
f
f
f在某点
x
i
x_i
xi的偏导数
∂
f
∂
x
i
\frac{\partial f}{\partial x_i}
∂xi∂f的正负决定“爬坡”或“下山”,最终迭代求得目标函数的极值(很多情况下是局部最优)。
下面先介绍一下GD的算法框架:
M表示样本数,
α
\alpha
α表示迭代步长,
1
M
∑
i
=
1
M
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
\frac{1}{M}\sum_{i=1}^Mf(x_i,\theta_1,...,\theta_s)
M1∑i=1Mf(xi,θ1,...,θs)表示损失函数,
x
i
x_i
xi表示第
i
i
i个样本,
θ
i
\theta_i
θi表示损失函数第
i
i
i个参数,
k
k
k表示迭代的轮次,
ϵ
\epsilon
ϵ表示阈值。
1)初始化参数
θ
i
,
i
=
1
,
.
.
.
,
s
\theta_i,i=1,...,s
θi,i=1,...,s
1)for
i
t
e
r
iter
iter in 1-k: #迭代轮次
2-1)for
i
i
i in 1-M: #迭代样本
3)for
j
j
j in 1-s:#迭代计算参数
4-1)计算
f
f
f在样本
x
i
x_i
xi时关于
θ
j
\theta_j^{}
θj的梯度
∂
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
∂
θ
j
\frac{\partial f(x_i,\theta_1,...,\theta_s)}{\partial \theta_j}
∂θj∂f(xi,θ1,...,θs);
4-2)用步长
α
\alpha
α乘上该梯度,得到当前位置下降的距离
α
∂
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
∂
θ
j
\alpha\frac{\partial f(x_i,\theta_1,...,\theta_s)}{\partial \theta_j}
α∂θj∂f(xi,θ1,...,θs).
2-2)for
j
j
j in 1-s: #迭代更新参数
3-1)
t
e
m
p
j
=
θ
j
temp_j=\theta_j
tempj=θj;
3-2)更新参数
θ
j
\theta_j
θj,
θ
j
=
θ
j
−
α
1
M
∑
i
=
1
M
∂
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
∂
θ
j
\theta_j=\theta_j - \alpha\frac{1}{M}\sum_{i=1}^M\frac{\partial f(x_i,\theta_1,...,\theta_s)}{\partial \theta_j}
θj=θj−αM1∑i=1M∂θj∂f(xi,θ1,...,θs);
3-3)计算相邻轮次参数之差
d
i
f
f
e
r
j
=
θ
j
−
t
e
m
p
j
differ_j=\theta_j - temp_j
differj=θj−tempj.
2-3)for
i
i
i in 1-s: #迭代比较参数
3)if all
d
i
f
f
e
r
j
<
ϵ
differ_j < \epsilon
differj<ϵ: #比较相邻轮次参数之差
4-1)输出参数
θ
j
,
i
=
1
,
.
.
.
,
s
\theta_j,i=1,...,s
θj,i=1,...,s;
4-2)break.
从上面的分析可以看到,GD在每次迭代中都遍历了所有的样本,这在计算大规模数据优化问题式会带来很大的计算负担。这在实际操作中基本不可行,那该怎么办呢?
为了解决该问题,就有了随机梯度下降法(Stochastic Gradient Descent,SGD)。不同于GD采用所有的样本训练参数
θ
\theta
θ,SGD只采用单个样本来训练参数,下面对比一下差别。
在GD中,损失函数为
1
M
∑
i
=
1
M
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
\frac{1}{M}\sum_{i=1}^Mf(x_i,\theta_1,...,\theta_s)
M1∑i=1Mf(xi,θ1,...,θs),均方误差是
(1)
Δ
f
(
θ
1
,
.
.
.
,
θ
s
)
=
1
M
∑
i
=
1
M
Δ
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
\Delta f(\theta_1,...,\theta_s) =\frac{1}{M}\sum_{i=1}^M\Delta f(x_i,\theta_1,...,\theta_s) \tag{1}
Δf(θ1,...,θs)=M1i=1∑MΔf(xi,θ1,...,θs)(1)
所以可以看出GD每次对参数进行更新时,需要遍历所有的训练样本。
在SGD中,损失函数为
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
f(x_i,\theta_1,...,\theta_s)
f(xi,θ1,...,θs),均方误差是
(2)
Δ
f
(
θ
1
,
.
.
.
,
θ
s
)
=
Δ
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
\Delta f(\theta_1,...,\theta_s) =\Delta f(x_i,\theta_1,...,\theta_s) \tag{2}
Δf(θ1,...,θs)=Δf(xi,θ1,...,θs)(2)
SGD只用单个训练样本就能更新一次参数,这大大加快了训练速度。SGD是GD的简化,虽然速度快了,但是由于在选到不同的样本时结果会有差距,所以显然是不稳定的。为了让算法更加稳定,可以引入折中的方法,即选择m个样本来训练参数,这就是小批量随机梯度下降法(Mini_Batch Stochastic Gradient Descent,MBSGD)。
在MBSGD中,损失函数为
1
m
∑
i
=
1
m
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
\frac{1}{m}\sum_{i=1}^mf(x_i,\theta_1,...,\theta_s)
m1∑i=1mf(xi,θ1,...,θs),均方误差是
(3)
Δ
f
(
θ
1
,
.
.
.
,
θ
s
)
=
1
m
∑
i
=
1
m
Δ
f
(
x
i
,
θ
1
,
.
.
.
,
θ
s
)
\Delta f(\theta_1,...,\theta_s) =\frac{1}{m}\sum_{i=1}^m\Delta f(x_i,\theta_1,...,\theta_s) \tag{3}
Δf(θ1,...,θs)=m1i=1∑mΔf(xi,θ1,...,θs)(3)
MBSGD采用m个训练样本来更新一次参数,相对GD加快了速度,相对SGD增加了稳定性,是目前实际操作中经常采用的方法。其中参数
m
,
θ
~m,\theta~
m,θ 是需要调参的。在采用MBSGD时,要注意这三个问题:
1、样本数m的确定:这没有普世的答案,但通常会选择
m
=
2
k
~m=2^k
m=2k,因为这样能充分利用矩阵运算操作;
2、m个训练样本的选择:从M个训练样本中随机选择;
3、迭代步长α的选取:考虑到收敛速度和求解精度,通常会采用“衰减取值”策略,即算法初期采用较大步长,当误差曲线逐渐平缓之后,这时候逐渐减小步长,直到找到满足条件的参数
θ
\theta
θ。
注:实际例子可以参见博客 https://blog.csdn.net/kwame211/article/details/80364079