机器学习金典算法(二)–梯度下降法(1)
本文旨在深刻总结梯度下降法的思想和原理,本人也再次学习总结相关知识;关于梯度下降法法博文和资料已经有很多,但个人觉得没有一篇讲得非常到位的(有点大言不惭哈),本人计划将用2篇博文来总结梯度下降法,本文重在其思想和原理,下篇重在几种不同梯度下降算法的总结。当然本人能力也有限,不足之处,望方家指点。
1 什么是梯度下降法
在我第一篇**最小二乘法博文中,已经提到过,最小二乘法和梯度下降法都是求解函数(机器学习中重点为目标函数(Loss Function))最优解的一种方法。但它们采用的方式不同,例如上篇博文中的直线拟合**,前者采用直接解方程组求得最优解;而梯度下降法则采用步进迭代的方法来逼近最优解。那就有人问了,什么是步进迭代呢?
我们还是拿直线拟合例子来解释
例子:
有直线模型
y
=
a
x
+
b
y = ax+b
y=ax+b,已知
当x=1时,y=5;
当x=2时,y=7;
当x=3时,y=9;
问当x=4时,y=?
有童鞋肯定会说,这个太简单了,我小学就会,但我们这里是机器学习思想,所有收起小学思想;当然我们清楚知道最优解(a=2,b=3),但我们就是要采用机器学习方法这求取这个最优解
1.1 最小二乘解法
直接将已知数据带入下面公式,详细步骤见上篇最小二乘法博文
{
b
=
∑
i
=
1
n
x
i
2
∑
i
=
1
n
y
^
i
−
∑
i
=
1
n
x
i
∑
i
=
1
n
x
i
y
^
i
n
∑
i
=
1
n
x
i
2
−
(
∑
i
=
1
n
x
i
)
2
a
=
n
∑
i
=
1
n
x
i
y
^
i
−
∑
i
=
1
n
x
i
∑
i
=
1
n
y
^
i
n
∑
i
=
1
n
x
i
2
−
(
∑
i
=
1
n
x
i
)
2
\left \{ \begin{array}{c} b = \dfrac{\displaystyle \sum _{i=1}^nx_i^2 \displaystyle \sum _{i=1}^n \hat y_i - \displaystyle \sum _{i=1}^nx_i \displaystyle \sum _{i=1}^n x_i\hat y_i}{n\displaystyle \sum _{i=1}^nx_i^2 - (\displaystyle \sum _{i=1}^nx_i)^2} \\ a= \dfrac{n\displaystyle \sum _{i=1}^n x_i\hat y_i - \displaystyle \sum _{i=1}^nx_i \displaystyle \sum _{i=1}^n\hat y_i}{n\displaystyle \sum _{i=1}^nx_i^2 - (\displaystyle \sum _{i=1}^nx_i)^2}\\ \end{array} \right.
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧b=ni=1∑nxi2−(i=1∑nxi)2i=1∑nxi2i=1∑ny^i−i=1∑nxii=1∑nxiy^ia=ni=1∑nxi2−(i=1∑nxi)2ni=1∑nxiy^i−i=1∑nxii=1∑ny^i
即得
a
=
2
,
b
=
3
a=2,b=3
a=2,b=3
1.2 步进迭代
我们换个思路,将上式变化下形式,如下图
这种形式就是我们常常提到的机器学习模型,X表示样本输入,Y表示前向输出,框中就是要学习的算法,如BP神经网络,CNN网络等,只不过这里是一个简单的直线算法,方便我们解释,但它们的学习原理是一样的。
具体步骤
(这也是学习思想,我们经常说机器学习,深度学习,那么这个学习就如下面所说)
第1步:随机初始化参数
参数随机初始化是一个很重要的课题,学术界对这方面的研究也是很多的,如卷积核参数的初始化,当然今天不说它。
我们这里就假定有某种初始化方法,初始化参数 a = 0.1 , b = 0.2 a=0.1,b=0.2 a=0.1,b=0.2,当然实际机器学习中会根据具体类型参数选择不同初始化方法。
第2步:前向计算、误差计算(前向)
即带入1个样本数据,前向计算得到y值,并根据目标函数计算误差
例如单个样本(x=1,y=5),目标函数设为
Q
=
∑
i
=
1
n
(
y
^
i
−
y
i
)
2
Q=\sum_{i=1}^n(\hat y_i-y_i)^2
Q=∑i=1n(y^i−yi)2,实际应用中,不同任务会选择不同目标函数,目标函数也是机器学习的一个重要模块
前向计算:
y
1
=
0.1
∗
1
+
0.2
=
0.3
y_1 = 0.1*1+0.2 = 0.3
y1=0.1∗1+0.2=0.3
误差计算:
Q
=
(
y
^
1
−
y
1
)
=
(
5
−
0.3
)
2
=
22.09
Q =(\hat y_1 - y_1)= (5-0.3)^2 = 22.09
Q=(y^1−y1)=(5−0.3)2=22.09
第3步:变化量计算(反向)
这里就该梯度下降法登场了,因为我现在只是在讨论梯度思想,还没有涉及具体原理;梯度计算呢?就是利用误差函数,误差值,框内算法,参数现有值等计算出每个参数需要改变的量,它不是胡乱计算出的改变量,而是在有利于降低误差的大方向上计算得到。
这里我们就假定经过梯度下降算法计算得到 δ a = − 0.3 , δ b = − 0.5 \delta a = -0.3, \delta b = -0.5 δa=−0.3,δb=−0.5,具体怎么计算我们后面再讲。
第4步:更新参数(反向)
根据参数变化量来更新参数,这里还牵扯到学习率
η
\eta
η,它也是机器学习里非常重要的一个参数,它表示着你本次迭代前进的步长,它很重要,后面在讲,这里假定
η
=
0.8
\eta=0.8
η=0.8
更新a:
a
=
a
−
η
∗
δ
a
=
0.1
−
0.8
∗
(
−
0.3
)
=
0.34
a = a -\eta*\delta a = 0.1 - 0.8*(-0.3) = 0.34
a=a−η∗δa=0.1−0.8∗(−0.3)=0.34
更新b:
b
=
b
−
η
∗
δ
b
=
0.2
−
0.8
∗
(
−
0.5
)
=
0.6
b = b -\eta*\delta b = 0.2 - 0.8*(-0.5) = 0.6
b=b−η∗δb=0.2−0.8∗(−0.5)=0.6
第5步:不断循环2,3,4步骤
换一个样本,重复2,3,4步,每循环一次,则改变一次参数,当然同一个样本可多次参与训练,就这样不断更新参数,也就是不断迭代逼近最优参数。
第6步:终止迭代
我们不能一直迭代下去吧,得有终止条件,也就是什么时候结束循环呢?
1)设定迭代次数
就是当迭代多少次就结束迭代,我们在深度学习时,经常看到的最大迭代次数,就是这个
2)设定误差阈值
就是当误差小于我们设定的某个阈值时,结束训练,BP神经网络训练常常用到
3)设定参数改变量阈值
就是当我们的参数变化量小于我们设定的某个阈值时,也就是我们的参数已经趋于不变了,再学也没有意义了,结束训练,BP神经网络训练常常用到
这里假定我们迭代100次,效果很好了,如下图
这 a = 2.002 , b = 2.9999 a = 2.002,b = 2.9999 a=2.002,b=2.9999可能与我们最优解 a = 2 , b = 3 a=2,b=3 a=2,b=3,差那么一点点,但这点误差在实际情况中是允许的。
1.3 比较
有人可能会问,梯度下降法比最小二乘法复杂,结果还有误差,为啥还要用这种方法???
因为在实际机器学习中,像这种线性问题只是冰山一角,而当问题复杂:
A)目标函数不是线性的,最小二乘这种直接解方程组的方式就用不了
B)当模型更复杂,如CNN,上千万个参数,甚至上亿,而我们的样本却没有那么多,解方程就傻眼了
C)梯度下降法看似复杂,但其中循环是重复性的计算,而这种重复性的劳动,计算机是最擅长的,相反,像解方程组这种逻辑问题,计算机是不会的(目前)
1.4 总结
A)从上面就可以看出,机器学习的学习包含:前向计算与反向传播;前向是由算法本身结构模型、数据、参数(包括初始化)、目标函数决定;而反向传播中,梯度则起主要作用
B)从上面可以看出,梯度下降法在整个机器学习算法中的位置非常重要,因为它决定了参数更新方向和大小,控制着参数向最优方向更新
C)机器学习组件
a)网络结构:里面的参数就是需要学习得到最优值,这就是我们最终要用来测试用的算法,需要根据不同任务而设计
b)目标函数:总方向,决定了该算法的功能,根据不同任务不同而定不同目标函数
c)优化方法:如梯度下降法,如何求得最优解
d)超参数:控制一些节奏,如学习率
η
\eta
η
e)参数初始化:有好的基础参数,学习起来更容易,就好比某个人天生智商高,那么他要学某种技能就特别快
2 梯度下降法原理
2.1 梯度定义
导数定义:
f
′
(
x
0
)
=
lim
Δ
x
→
0
Δ
y
Δ
x
=
lim
Δ
x
→
0
f
(
x
0
+
Δ
x
)
−
f
(
x
0
)
Δ
x
f'(x_0) =\displaystyle \lim_{\Delta x \to 0} \frac {\Delta y}{\Delta x} = \displaystyle \lim_{\Delta x \to 0} \frac {f(x_0+\Delta x) - f(x_0)}{\Delta x}
f′(x0)=Δx→0limΔxΔy=Δx→0limΔxf(x0+Δx)−f(x0)
一元函数
y
=
f
(
x
)
y=f(x)
y=f(x)在点
x
0
x_0
x0处的梯度:
(
f
′
(
x
0
)
)
(f'(x_0))
(f′(x0))
二元函数
z
=
f
(
x
,
y
)
z = f(x,y)
z=f(x,y)在点
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0)处的梯度:
(
∂
f
(
x
,
y
)
∂
x
∣
(
x
0
,
y
0
)
,
(
∂
f
(
x
,
y
)
∂
y
∣
(
x
0
,
y
0
)
)
(\left.\frac{\partial f(x,y)}{\partial x}\right|_{(x_0,y_0)}, (\left.\frac{\partial f(x,y)}{\partial y}\right|_{(x_0,y_0)})
(∂x∂f(x,y)∣∣∣∣(x0,y0),(∂y∂f(x,y)∣∣∣∣(x0,y0))
简而言之,对多元函数的各个自变量求偏导数,并把求得的这些偏导数写成向量的形式,就是梯度。我们常把函数
f
f
f的梯度简记为:
g
r
a
d
f
grad f
gradf或者
∇
f
\nabla f
∇f
2.2 几何意义
如上图,图片来自参考文献3,横坐标表示参数 θ \theta θ,为了简便,这里只有一个参数,因为多个参数,就不是二维图了,实际中 θ \theta θ是向量或矩阵,纵坐标表示目标函数,可以理解为误差;
图中红色箭头处对应点,假定
θ
0
\theta _0
θ0,就好比我我们初始化参数,它的误差很大;而极小值处
θ
^
\hat \theta
θ^则对应最优解,误差最小;这时就明白了,我们只要改变参数
θ
0
\theta_0
θ0,使得它逐渐接近
θ
^
\hat \theta
θ^不就可以了吗!但问题来了,
1)初始化参数时随机的,如图,
θ
0
\theta _0
θ0可能在左,也可能在右,如何控制它无论什么情况都像
θ
^
\hat \theta
θ^靠近呢?
这个时候梯度就跳出来了;如图极小值左边,根据导数定义,可以计算出左边点处的梯度为负,即向左,右边相反;这时我们只要选取负梯度方向就可以使得,
θ
0
\theta _0
θ0无论在左,在右,它都能像
θ
^
\hat \theta
θ^靠近
2)为啥是梯度方向?而不是其他方向
因为函数在梯度方向上上升是最快的,相反负梯度方向下降最快;好比一个人在山顶要最快到山谷(最低点),他每次选择当前位置最陡方向(负梯度)跳下,会比走盘型山路(其他方向)要快,当然这个例子并不严谨,有那么点意思。
3)如何变化?
4)逐渐靠近,总得有个步伐,不能乱跳吧?
后面两个问题见下面
2.3 梯度下降法
如图中,蓝色的点,就像这样一步一步地,从初始位置迭代到极小值处。迭代方向为当前位置负梯度方向,步伐则有学习率 η \eta η控制,不能太快,也不能太慢,要实际应用决定 η \eta η值的大小,或是根据训练情况实时调整都是可能的。
2.4 具体化
因为梯度下降法与最小二乘法一样,它们都是一种思想,要结合具体算法,才能具体到每个细节,本文主要是理解梯度下降法思想,它在机器学习中的位置,具体实例参见我后面要总结的BP神经网络,待更新。
3 参考文献
【1】梯度下降法:https://blog.csdn.net/qq_42379006/article/details/80675704
【2】机器学习03-代价函数与梯度下降算法(二):https://blog.csdn.net/xinzhi8/article/details/64948465
【3】深入梯度下降(Gradient Descent)算法:https://www.cnblogs.com/ooon/p/4947688.html