梯度下降的实现细节
前面我们讲解了回归的基本概念和初介绍了梯度下降,这次我们来讲一下梯度下降过程中的实现流程和一些细节。
repeat until convergence
θ
j
:
=
θ
j
−
α
∂
∂
θ
j
J
(
θ
0
,
θ
1
)
(
for
j
=
0
and
j
=
1
)
\theta_{j}:=\theta_{j}-\alpha \frac{\partial}{\partial \theta_{j}} J\left(\theta_{0}, \theta_{1}\right) \quad(\text { for } j=0 \text { and } j=1)
θj:=θj−α∂θj∂J(θ0,θ1)( for j=0 and j=1)
根据上文提到的更新公式,我们可知梯度下降的更新是与其导数相关,是根据导数来进行公式更新,通过“-”操作使其往梯度下降的方向移动。如下图代价J随
θ
\theta
θ变化曲线中的红点,这点的导数求出来显而易见是正数,那么当我们执行上述公式的时候,
θ
\theta
θ的值是向左移,而
θ
\theta
θ左移的时候J就会随之减小,这就是这个公式的意义。
当梯度下降到代价函数的最低点(局部最小值或者全局最小值)时,结果是局部最优点的导数将等于零,因为它是那条切线的斜率。这意味着你已经在局部最优点,它使得 θ 1 \theta_1 θ1不再改变,也就是新的 θ 1 \theta_1 θ1等于原来的 θ 1 \theta_1 θ1。那这时候就代表梯度下降收敛,我们就可以去试一下这时候拟合的模型效果。
这里再一次讲一下学习率
α
\alpha
α的重要性。如果α太小了,结果就是只能像蜗牛一样移动,这样就需要很多步才能到达最低点,大大增加训练时间。但是相反的,如果a太大,那么梯度下降法可能不小心一下子会越过最低点,甚至可能无法收敛。下一次迭代又移动了一大步,越过一次,又越过一次,一次次越过最低点,直到你发现实际上离最低点越来远。所以选择一个恰当的学习率对模型训练来说时十分重要的。
暂定我们的假设函数还是
h
θ
(
x
)
=
θ
0
+
θ
1
x
h_{\theta}(x)=\theta_{0}+\theta_{1} x
hθ(x)=θ0+θ1x,那么每次迭代的时候,对应的
θ
0
\theta_0
θ0和
θ
1
\theta_1
θ1会进行下面的更新。值得注意的是,每次更新
θ
\theta
θ都是应同时进行更新的,而不是先更新某个
θ
i
\theta_i
θi后再根据这个
θ
i
\theta_i
θi去更新前面的
θ
i
−
1
\theta_{i-1}
θi−1。即先算出temp0和temp1后再去同时更新赋值给
θ
0
\theta_0
θ0和
θ
1
\theta_1
θ1。然后根据设定的训练次数重复这个过程,不断更新参数的数值,直至收敛。
Correct:Simultaneous update
temp 0 : = θ 0 − α ∂ ∂ θ 0 J ( θ 0 , θ 1 ) temp 1 : = θ 1 − α ∂ ∂ θ 1 J ( θ 0 , θ 1 ) θ 0 : = temp0 θ 1 : = temp1 \begin{array}{l} \operatorname{temp} 0:=\theta_{0}-\alpha \frac{\partial}{\partial \theta_{0}} J\left(\theta_{0}, \theta_{1}\right) \\ \operatorname{temp} 1:=\theta_{1}-\alpha \frac{\partial}{\partial \theta_{1}} J\left(\theta_{0}, \theta_{1}\right) \\ \theta_{0}:=\operatorname{temp0} \\ \theta_{1}:=\text { temp1 } \end{array} temp0:=θ0−α∂θ0∂J(θ0,θ1)temp1:=θ1−α∂θ1∂J(θ0,θ1)θ0:=temp0θ1:= temp1
当然还有个重要的问题,公式中的
∂
∂
θ
0
J
(
θ
0
,
θ
1
)
\frac{\partial}{\partial \theta_{0}} J\left(\theta_{0}, \theta_{1}\right)
∂θ0∂J(θ0,θ1)是什么,这就是求在当前点处,对某个参数
θ
i
\theta_i
θi的偏导数。根据我们先前定义的代价函数
∂
∂
θ
j
J
(
θ
0
,
θ
1
)
=
∂
∂
θ
j
1
2
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
\frac{\partial}{\partial \theta_{j}} J\left(\theta_{0}, \theta_{1}\right)=\frac{\partial}{\partial \theta_{j}} \frac{1}{2 m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2}
∂θj∂J(θ0,θ1)=∂θj∂2m1i=1∑m(hθ(x(i))−y(i))2
其对应的偏导数求解为:
j
=
0
时
:
∂
∂
θ
0
J
(
θ
0
,
θ
1
)
=
1
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
j
=
1
时
:
∂
∂
θ
1
J
(
θ
0
,
θ
1
)
=
1
m
∑
i
=
1
m
(
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
⋅
x
(
i
)
)
\begin{array}{l} j=0 \text { 时 }: \frac{\partial}{\partial \theta_{0}} J\left(\theta_{0}, \theta_{1}\right)=\frac{1}{m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) \\ j=1 \text { 时 }: \frac{\partial}{\partial \theta_{1}} J\left(\theta_{0}, \theta_{1}\right)=\frac{1}{m} \sum_{i=1}^{m}\left(\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) \cdot x^{(i)}\right) \end{array}
j=0 时 :∂θ0∂J(θ0,θ1)=m1∑i=1m(hθ(x(i))−y(i))j=1 时 :∂θ1∂J(θ0,θ1)=m1∑i=1m((hθ(x(i))−y(i))⋅x(i))
之所以
j
=
0
j=0
j=0时没有再多乘一个
x
i
x^i
xi的原因是
j
=
0
j=0
j=0对应的是偏置单元
θ
0
\theta_0
θ0,它是一个常数,常数的导数为它本身。下面给出这个偏导的通用推导公式。
∂
∂
θ
j
J
(
θ
)
=
∂
∂
θ
j
1
2
(
h
θ
(
x
)
−
y
)
2
=
2
⋅
1
2
(
h
θ
(
x
)
−
y
)
⋅
∂
∂
θ
j
(
h
θ
(
x
)
−
y
)
=
(
h
θ
(
x
)
−
y
)
∂
∂
θ
j
(
∑
i
=
1
n
θ
i
x
i
−
y
)
=
(
h
θ
(
x
)
−
y
)
x
j
\begin{aligned} \frac{\partial}{\partial \theta_{j}} J(\theta) &=\frac{\partial}{\partial \theta_{j}} \frac{1}{2}\left(h_{\theta}(x)-y\right)^{2} \\ &=2 \cdot \frac{1}{2}\left(h_{\theta}(x)-y\right) \cdot \frac{\partial}{\partial \theta_{j}}\left(h_{\theta}(x)-y\right) \\ &=\left(h_{\theta}(x)-y\right) \frac{\partial}{\partial \theta_{j}}\left(\sum_{i=1}^{n} \theta_{i} x_{i}-y\right) \\ &=\left(h_{\theta}(x)-y\right) x_{j} \end{aligned}
∂θj∂J(θ)=∂θj∂21(hθ(x)−y)2=2⋅21(hθ(x)−y)⋅∂θj∂(hθ(x)−y)=(hθ(x)−y)∂θj∂(i=1∑nθixi−y)=(hθ(x)−y)xj
根据上述公式,我们可以将一开始的
θ
\theta
θ更新公式优化为:
repeat{
θ 0 : = θ 0 − a 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) θ 1 : = θ 1 − a 1 m ∑ i = 1 m ( ( h θ ( x ( i ) ) − y ( i ) ) ⋅ x ( i ) ) \begin{array}{l} \theta_{0}:=\theta_{0}-a \frac{1}{m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) \\ \theta_{1}:=\theta_{1}-a \frac{1}{m} \sum_{i=1}^{m}\left(\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) \cdot x^{(i)}\right) \end{array} θ0:=θ0−am1∑i=1m(hθ(x(i))−y(i))θ1:=θ1−am1∑i=1m((hθ(x(i))−y(i))⋅x(i))
}
整个大体流程我们已经确定完了,首先是根据数据集定义假设函数,然后定义代价函数衡量误差,并通过梯度下降的方式,求取各点的导数,并代入参数更新公式,重复步骤迭代直至参数收敛。整个过程的算法我们一般称之为批量梯度下降。
这个名称说明了我们需要考虑所有这一"批"训练样本。它更侧重指的是在梯度下降的每一步中,我们都用到了所有的训练样本,在梯度下降中,在计算微分求导项时,我们需要进行求和运算。在每一个单独的梯度下降中,我们最终都要计算对所有m个训练样本求和。
各种“函数”概念理解
这里是对跟机器学习相关的一些函数概念介绍,很多初学者常常会对这些概念混淆。代价函数最重要的目标就是用于找到最优解的目的函数。与之相关的有:
损失函数(Loss Function):是定义在单个样本上的,算的是一个样本的误差。
代价函数(Cost Function):是定义在整个训练集上的,是所有样本误差的平均,也就是损失函数的平均。
目标函数(Object Function):最终需要优化的函数。等于经验风险+结构风险(也就是Cost Function + 正则化项)。
这些函数都是我们定义的,所以肯定不只有一种。除了文章中介绍的我们最常用的平方和损失函数,还有其他一些我们可能会用到的。我们后面会根据不同的情况选用不同的损失函数,大家可以先做个了解。
平方和损失函数
J
(
θ
)
=
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
绝对值损失函数
J
(
θ
)
=
∑
i
=
1
m
∣
h
θ
(
x
(
i
)
)
−
y
(
i
)
∣
对数损失函数
J
(
θ
)
=
∑
i
=
1
m
(
y
(
i
)
log
h
θ
(
x
(
i
)
)
)
)
\begin{array}{l} \text { 平方和损失函数 } \quad J(\theta)=\sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2} \\ \text { 绝对值损失函数 } \quad J(\theta)=\sum_{i=1}^{m}\left|h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right| \\ \text { 对数损失函数 }\left.\quad J(\theta)=\sum_{i=1}^{m}\left(y^{(i)} \log h_{\theta}\left(x^{(i)}\right)\right)\right) \end{array}
平方和损失函数 J(θ)=∑i=1m(hθ(x(i))−y(i))2 绝对值损失函数 J(θ)=∑i=1m∣∣hθ(x(i))−y(i)∣∣ 对数损失函数 J(θ)=∑i=1m(y(i)loghθ(x(i))))