梯度下降算法过程详细解读
看了很多博文,一谈到梯度下降,大多都在画图,类比“下山”。对于一开始想要了解“梯度下降”是个什么玩意儿时,这种类比法是非常有助于理解的。但是,当我大概知道了梯度下降是什么东西之后,我就好奇了,梯度下降究竟是怎样寻找到模型的最优参数的?不能一想到梯度下降,脑海中就只有“下山”的画面,“下山”不是目的,目的在于“下山”的过程中确立参数。下面就简单概述一下,梯度下降过程是如何一步一步寻找到模型的最优参数。
1.梯度下降相关概念:
- 假设函数(hypothesis function):
所谓假设函数,就是监督学习中,我们拟合样本特征映射到目标变量的函数,记为 hθ(x),θ为函数的参数。例如,一个简单的线性回归拟合函数可以表示为:hθ(x) = θ0 + θ1·x;
- 损失函数(loss function):
又称为代价函数。通常用损失函数来度量拟合的程度,从而评估模型拟合的好坏,记为 J(θ)。注意,损失函数是关于 θ 的函数!也就是说,对于损失函数来讲,θ不再是函数的参数,而是损失函数的自变量!例如,对于线性回归的损失函数可以表示为:
J(θ) = 1/(2 *n) * ∑ ( hθ(xi) − yi )2
其中 n 表示样本数量, xi 表示第 i 个样本特征,yi 表示第 i 个样本对应的目标变量的真实值, hθ(xi) 为假设函数。 当我们计算损失时,是将每个样本中的特征 xi 和对应的目标变量真实值 yi 带入损失函数,此时,损失函数中就只剩下 θ 是未知的。
例如,我们的假设函数为: hθ(x) = θ0 + θ1·x1 + θ2·x22 ,其中一个样本为 x1 = (1,2),对应的目标变量 y1 = 10。将x1 和y1 带入损失函数,则对于该样本 x1 拟合的损失表示为: θ0 + θ1 + 4*θ2 -10 ;此时,损失函数就是关于θ 的函数了。 每一个样本都会有一个拟合损失,将所有样本的损失相加,就是整个样本集的拟合损失。
- 损失函数的梯度:
损失函数的梯度即对 θi 求偏导,由于损失函数是关于 θ 的函数,因此,θ 的取值不同,得出来的的梯度向量也是不同的。借用“下山”的比喻来解释,θ 的不同取值,相当于处于山上的不同位置,每一个位置都会计算出一个梯度向量 ▽J(θ) 。
2. 梯度下降过程
(1) 学习得到损失函数 J(θ) 及样本点xi 的损失:
例如,对于线性回归模型的假设函数为: hθ(x) = θ0 + θ1·x1 + θ2·x2 ,则损失函数为:J(θ) = 1/(2 *n) * Σ(θ0 + θ1·x1 + θ2·x2 - y)2;我们为样本添加一个维度x0 ,x0 恒等于 1。则,我们可以变损失函数表示为:J(θ) = 1/(2 *n) * Σ(θ0·x0 + θ1·x1 + θ2·x2 - y)2
为了便于讲解和理解,我们先只取一个样本点进行计算。对于样本点 x1 = (x0 = 1,x1 = 1,x2 = 2),对应的目标变量 y1 = 10,的损失为:J(θ)1 = 1/2 *(θ0 + θ1+ 2*θ2 - 10)2
(2) 求出样本点 xi 损失函数的梯度向量:
根据 J(θ) ,求出模型损失函数的梯度向量表示为 : ▽J(θ) = <(θ0·x0 + θ1·x1 + θ2·x2 - y)*x0 ,(θ0·x0 + θ1·x1 + θ2·x2 - y)*x1 ,(θ0·x0 + θ1·x1 + θ2·x2 - y)*x2 >
根据 J(θ)1 ,求出样本点 x1 对应的梯度▽J(θ)1 = <(θ0+ θ1 + 2*θ2 - 10),(θ0+ θ1 + 2*θ2 - 10),(θ0+ θ1 + 2*θ2 - 10)*2 >
(3) 初始化假设函数的参数 θ ,得到相应的梯度向量:
对 θ 进行随机取值,假设θi 第一次全部取0,θ0 = < 0,0,0>;
将θ0 带入 J(θ)1 ,得到 取 θ0 时的损失为 J(θ)01 = 1/2 *(0 + 0+ 2*0 - 10)2 = 50
将θ0 带入▽J(θ)1 ,得到 θ0 处的梯度向量为 ▽J(θ)01 = < -10,-10,-20 > ;
(4) 根据梯度下降步长,进行梯度下降迭代:
设立步长 α = 0.1 ,对 θ0 进行梯度下降,得到 θ1
第一次梯度下降:
θ1 = θ0 - α * ▽J(θ)01 = < 0,0,0 > - 0.1 * < -10,-10,-20 > = < 1,1,2 >
将θ1 带入 J(θ)1 ,得到 取 θ0 时的损失为 J(θ)01 = 1/2 *(1 + 1+ 2*2 - 10)2 = 8
将θ1 带入▽J(θ)1 ,得到 θ0 处的梯度向量为 ▽J(θ)01 = < -4,-4,-8 > ;
第二次梯度下降:
θ2 = θ1 - α * ▽J(θ)01 = < 1,1,2 > - 0.1 * < -4,-4,-8 > = < 0.4,0.4,1.2 >
将θ2 带入 J(θ)1 ,得到 取 θ2 时的损失为 J(θ)01 = 1/2 *(0.4 + 0.4+ 2*1.2 - 10)2 = 23.12
此时我们发现,θ2 处的损失为23.12,大于 θ1 处的损失8,说明,我们可能步子迈的大了,跨过了最低点,我们重新设定α = 0.05,重复上述过程:
重新设立步长 α = 0.05
第一次梯度下降:
θ1 = θ0 - α * ▽J(θ)01 = < 0,0,0 > - 0.05 * < -10,-10,-20 > = < 0.5,0.5,1 >
将θ1 带入 J(θ)1 ,得到 取 θ0 时的损失为 J(θ)01 = 1/2 *(0.5 + 0.5+ 2*1 - 10)2 = 24.5
将θ1 带入▽J(θ)1 ,得到 θ0 处的梯度向量为 ▽J(θ)01 = < -7,-7,-14 > ;
第二次梯度下降:
θ2 = θ1 - α * ▽J(θ)01 = < 1,1,2 > - 0.05 * < -7,-7,-14 > = < 1.35,1.35,2.7 >
将θ2 带入 J(θ)1 ,得到 取 θ2 时的损失为 J(θ)01 = 1/2 *(1.35 + 1.35+ 2*2.7 - 10)2 = 1.805
将θ2 带入▽J(θ)1 ,得到 θ2 处的梯度向量为 ▽J(θ)01 = < -1.9,-1.9,-3.8 >
此时可以继续进行第三次、第四次。。。第n次,那么什么时候梯度下降停止?我们可以设置一个梯度下降算法终止距离值 ε,即梯度下降的距离都小于 ε 时,算法终止。假设我们设置 ε = 0.1(实际运用中,一般会设定一个更小的值,例如 1e-5),上述θ2 的梯度向量为< -1.9,-1.9,-3.8 >,梯度向量中的3个值的绝对值都大于ε ,因此继续进行梯度下降,假设经过n次迭代后的梯度向量为<-0.04,-0.04,-0.08>,三个值的绝对值都小于0.1,则算法终止。
通过上述过程可以看出,重新设置步长 α 后,第二次梯度下降过程没有跨过损失函数最低点,而是更加接近最低点。不断的梯度下降,使得损失函数损失在不断的变小:θ0 的损失为50,θ1 的损失为24.5,θ2 的损失为1.805。 初始在本文的例子中,由于是我随便写的一个损失函数,所以经过2-3次梯度下降之后就接近了损失函数最低点,实际运用中当然不可能这么轻松,梯度下降可能要经过n次迭代,才能接近损失函数的极小值点。另外,梯度下降过程中,除了损失在不断减小,梯度向量也在不断变小:θ0 的梯度为< -10,-10,-20 > ,θ1 的梯度为< -7,-7,-14 >,θ2 的梯度为< -1.9,-1.9,-3.8 >。梯度越来越小,说明”山坡“越来越平缓,不像一开始那么”陡峭“,那么可以说明,我们已经接近”山谷“了。实际上,随着不断的梯度下降,梯度向量中的每个值会越来月接近于0。
讲到这里,大家不要忘记一个事实:上述过程中,我们只选取了一个样本点 x1 进行梯度下降。这种随机选取一个样本点进行梯度下降,找到最优参数θ的方法,就叫做随机梯度下降。而如果我们利用所有的样本数据进行梯度下降,这种方法就叫做批量梯度下降。毫无疑问,批量梯度下降要消耗更多的计算内存和训练时间;而随即梯度下降虽然训练速度快,但是可能得到只是局部最优解。我们也可以折中一下,一共有n个样本,我们取m个子样本进行梯度下降(1<m<n),既提高训练速度,又在一定程度上避免算法收敛到局部最优,这种方法就叫做小批量梯度下降。
参考:https://www.cnblogs.com/pinard/p/5970503.html
https://www.jianshu.com/p/c7e642877b0e