本文正在参加「金石计划 . 瓜分6万现金大奖」
前言
在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent) 是最常采用的方法之一,另一种常用的方法是最小二乘法。
在 【AI】浅谈梯度下降算法(理论篇) 这篇博文中,我们已经学习了梯度下降算法的一些基本概念以及理论推导,接下来,我们将通过结合代码进行实战,理论与实践相结合,加深对知识点的理解;
大家族
尽管说是梯度下降,但其实它还是个庞大的家族,就类似于编程语言有 C、Java、Python 等之分,梯度下降算法也被分为了几大类,主要的有 BGD、SGD、MBGD:
批量梯度下降法(Batch Gradient Descent)
: 梯度下降法最常用的形式,具体做法也就是在更新参数时使用所有的样本来进行更新;
θi=θi−α∑j=0m(hθ(x0(j),x1(j),…,xn(j))−yj)xi(j)θ_i=θ_i−α∑_{j=0}^m(h_θ(x^{(j)}_0,x^{(j)}_1,…,x^{(j)}_n)−y_j)x_i^{(j)}θi=θi−αj=0∑m(hθ(x0(j),x1(j),…,xn(j))−yj)xi(j)
优点:全局最优解,易于并行实现;
缺点:计算代价大,数据量大时,训练过程慢;
随机梯度下降法(Stochastic Gradient Descent)
: 和批量梯度下降法原理类似,区别在于求梯度时,没有用所有的 mmm 个样本的数据,而是仅仅选取一个样本 jjj 来求梯度;
θi=θi−α(hθ(x0(j),x1(j),…,xn(j))−yj)xi(j)θ_i=θ_i−α(h_θ(x^{(j)}_0,x^{(j)}_1,…,x^{(j)}_n)−y_j)x_i^{(j)}θi=θi−α(hθ(x0(j),x1(j),…,xn(j))−yj)xi(j)
优点:训练速度快;
缺点:准确度下降,并不是全局最优,不易于并行实现;
小批量梯度下降法(Mini-batch Gradient Descent)
: 小批量梯度下降法是批量梯度下降法和随机梯度下降法的折中,也就是对于 mmm 个样本,我们采用 xxx 个样本来迭代,1<x<m1<x<m1<x<m。一般可以取 x=10x=10x=10,当然根据样本的数据量,可以调整这个 xxx 的值;
θi=θi−α∑j=tt+x−1(hθ(x0(j),x1(j),…,xn(j))−yj)xi(j)θ_i=θ_i−α∑_{j=t}^{t+x-1}(h_θ(x^{(j)}_0,x^{(j)}_1,…,x^{(j)}_n)−y_j)x_i^{(j)}θi=θi−αj=t∑t+x−1(hθ(x0(j),x1(j),…,xn(j))−yj)xi(j)
前两种方法的性能折中;
一维问题
例1:求 f(x)=x2+1f(x) = x^2 + 1f(x)=x2+1 的最小值
f(x)=x2+1f(x) = x^2 + 1f(x)=x2+1
使用梯度下降法求 f(x)=x2+1(−10≤x≤10)f(x) = x^2 + 1 \quad (-10 \leq x \leq 10)f(x)=x2+1(−10≤x≤10) 的最小值
因为 f(x)=x2+1f(x) = x^2 + 1f(x)=x2+1 是凸函数,从图中也可以一眼看出,其最小值就在 x=0x=0x=0 处;
接下来就使用梯度下降法进行求解:
1、目标函数,即 f(x)=x2+1f(x) = x^2 + 1f(x)=x2+1 :
1 | py复制代码def func_target(x): |
2、求解梯度,即 f(x)′=2xf(x)^{‘} = 2xf(x)′=2x :
1 | py复制代码def func_gradient(x): |
3、梯度下降算法,需要注意几个参数的意义:
x
: 当前 x 的值,可以通过参数提供初始值;learn_rate
: 学习率,相当于设置的步长;precision
: 收敛精度;max_iters
: 最大迭代次数;
1 | py复制代码def SGD(x=1, learn_rate=0.1, precision=1e-5, max_iters=10000): |
例2:求 12[(x1+x2−4)2+(2x1+3x2−7)2]\frac{1}{2}[(x_1+x_2-4)^2 + (2x_1+3x_2-7)^2]21[(x1+x2−4)2+(2x1+3x2−7)2] 的极值
通过梯度下降的方法成功求得了 的最小值之后是不是信心大增呢,接下来让我们逐步加深难度:使用梯度下降法求多项式 12[(x1+x2−4)2+(2x1+3x2−7)2]\frac{1}{2}[(x_1+x_2-4)^2 + (2x_1+3x_2-7)^2]21[(x1+x2−4)2+(2x1+3x2−7)2] 的极值;
在使用梯度下降求解这道题的过程中,就不得不注意到一个问题:梯度下降可能在局部最小的点收敛;
1、目标函数,即 12[(x1+x2−4)2+(2x1+3x2−7)2\frac{1}{2}[(x_1+x_2-4)^2 + (2x_1+3x_2-7)^221[(x1+x2−4)2+(2x1+3x2−7)2 :
1 | py复制代码def func_target(x1, x2): |
2、求解梯度,即 ∂f∂x1=(x1+x2−4)+2(2x1+3x2−7)\frac{∂f}{∂x_1} = (x_1+x_2-4)+2(2x_1+3x_2-7)∂x1∂f=(x1+x2−4)+2(2x1+3x2−7) 和 ∂f∂x2=(x1+x2−4)+3(2x1+3x2−7)\frac{∂f}{∂x_2} = (x_1+x_2-4)+3(2x_1+3x_2-7)∂x2∂f=(x1+x2−4)+3(2x1+3x2−7):
1 | py复制代码def func_gradient(x1, x2): |
3、梯度下降算法:
1 | py复制代码def SGD(x1=0, x2=0, learn_rate=0.01, precision=1e-6, max_iters=10000): |
中间的迭代过程就省略了;
二维问题
当你通过自己的努力完成前两个例子之后,你是不是已经不满足于一维问题了呢,那么接下来我们进入二维问题:使用梯度下降法求 f(x,y)=−e−(x2+y2)f(x,y) = -e^{-(x^2+y^2)}f(x,y)=−e−(x2+y2) 在 [0,0][0,0][0,0] 处有最小值;
f(x,y)=−e−(x2+y2)f(x,y) = -e^{-(x^2+y^2)}f(x,y)=−e−(x2+y2)
通过这个例子,我们会发现梯度下降的局限性,先在这里留个悬念;
1、目标函数,即 f(x,y)=−e−(x2+y2)f(x,y) = -e^{-(x^2+y^2)}f(x,y)=−e−(x2+y2) :
1 | py复制代码def func_target(cell): |
2、求解梯度,即 ∂f∂x=2xe−(x2+y2)\frac{∂f}{∂x} = 2xe^{-(x^2+y^2)}∂x∂f=2xe−(x2+y2) 和 ∂f∂y=2ye−(x2+y2)\frac{∂f}{∂y} = 2ye^{-(x^2+y^2)}∂y∂f=2ye−(x2+y2):
1 | py复制代码def func_gradient(cell): |
3、梯度下降算法:
1 | py复制代码def SGD(x=np.array([0.1, 0.1]), learn_rate=0.1, precision=1e-6, max_iters=10000): |
4、当 x0x0x0 的初始值设为 [1,−1][1,−1][1,−1] 时,一切都显得很正常:
5、但当我们把 x0x0x0 的初始值设为 [3,−3][3,−3][3,−3] 时,结果是出乎意料的:
梯度下降法没有找到真正的极小值点!
局限性
继续讲述上面的非预期结果:
如果仔细观察目标函数的图像,以及梯度下降法的算法原理,你就很容易发现问题所在了。在 [3,−3][3,−3][3,−3] 处的梯度就几乎为 0 了!
由于“梯度过小”,梯度下降法可能无法确定前进的方向了。即使人为增加收敛条件中的精度,也会由于梯度过小,导致迭代中前进的步长距离过小,循环时间过长。
梯度下降法实现简单,原理也易于理解,但它有自身的局限性,因此有了后面很多算法对它的改进。
对于梯度过小的情况,梯度下降法可能难以求解。
此外,梯度下降法适合求解只有一个局部最优解的目标函数,对于存在多个局部最优解的目标函数,一般情况下梯度下降法不保证得到全局最优解(由于凸函数有个性质是只存在一个局部最优解,所有也有文献的提法是:当目标函数是凸函数时,梯度下降法的解才是全局最优解)。
由于泰勒公式的展开是近似公式,要求迭代步长要足够小,因此梯度下降法的收敛速度并非很快的。
后记
上述就是本篇博文的所有内容了,通过实战对梯度下降知识点进行巩固和加深印象,并且层层收入,希望读者能有所收获!
对于理论还不是很清楚的读者,可以回看上篇博文:【AI】浅谈梯度下降算法(理论篇);
参考:
📝 上篇精讲:【AI】浅谈梯度下降算法(理论篇)
💖 我是 𝓼𝓲𝓭𝓲𝓸𝓽,期待你的关注;
👍 创作不易,请多多支持;
🔥 系列专栏:AI
本文转载自: 掘金