上文我们已经讲了梯度下降法的概念,原理,数学解释,相信看过的读者大大对梯度下降法已经有一个大致的了解。需要阅读,可以点击大白话讲梯度下降法(一)
知道一个事物的原理,只能会了一半。我们学一样东西肯定是想知道它有什么用,可以怎么用,这就是本篇的目的,那么让我们开始吧。
梯度下降法有什么用
机器学习中本质上就是求解我们的假设函数,那么怎么判断我们的假设函数就是符合我们的业务场景的呢。换个思路思考,当我们的假设函数与我们的实际函数误差越来越小的时候,也就是越接近我们的实际函数,所以我们可以把问题转化成,使误差函数最小,即最小化误差函数,也就是最小化损失函数,也就是找到这个损失函数的最小点。
我们前文是通过下山场景来理解我们的梯度下降法的,我们需要走到山底,然后我们使用了梯度下降法来帮我们寻找到最低点,结合上下文,我们可以了解到梯度下降法可以帮助找到损失函数的最小值,从而优化我们的假设函数,使得我们的假设函数更接近实际函数,找到最优拟合函数。
怎么优化梯度下降法
在前文我们了解到梯度下降法有几个要素,如果要优化梯度下降法,我们就可以从这些要素入手,通过公式回顾一下我们的梯度下降法公式。
1、步长α:如果步长太小,会收敛得很慢。如果步长太大,可能会错过最小点。所以需要我们从小到大,慢慢,选出一个想对最优解。
2、初始值:随机选取初始值。如果损失函数是凸函数,我们找到的解可能只是局部最优解, 因此我们需要多试几个初始值,选出试验局部最优解情况中的最优解。如果是凸函数,则局部最优解,就是全局最优解了。
3、归一化:归一化可以加快梯度下降法过程中的收敛速度。
梯度下降法的分类
1、批量梯度下降法(BGD)
是梯度下降法最常用的形式,就是使用所有样本来更新我们的损失函数,然后使用梯度下降法求解这个损失函数的最小值。下面是均方误差代价函数
优点:
迭代次数少;
如果损失函数是凸函数,可以保证收敛到全局最优。如果不是凸函数,可以达到局部最优;
缺点:
训练速度慢;
需要内存大;
不能在线更新;
2、随机梯度下降法(SGD)
跟梯度下降法差不多,只是随机抽取的一个样本数来求梯度。
优点:
训练速度快;
支持在线更新;
有可能得到局部最优解;
缺点:
容易收敛到局部最优,也就是容易困在某个范围;
迭代次数多;
3、小批量梯度下降法(MBGD)
是批量梯度下降法和随机梯度下降法的折中随机抽取x个样本来求梯度,假设全部样本是m个,那么我们可以取 1<x<m个样本来求梯度。一般x可以取10。
优点
速度比BGD快;
比SGD更能保证局部最优;
可以降低过拟合的概率;
缺点
有噪音存在,所以可能会欠拟合;
代码实现
看下我们这次用来做梯度下降的数据的分布。
首先通过样本数据定义我们的损失函数
#我们这里使用批量梯度下降法,所以使用全部样本进行更新损失函数
def cost_fun(w, b, x,y):
total_cost = 0
M = len(x)
for i in range(M):
total_cost += (y[i]-w*x[i]-b) ** 2
print('total_cost')
print(total_cost)
return total_cost/M
定义我们的初始参数,学习率,初始值,迭代次数
#定义初始参数
a = 0.0001 #学习率
#定义初始值
init_w = 0
init_b = 0
iter_num = 10 #迭代次数
准备工作做完后,接下来定义我们的梯度下降方法
#梯度下降过程
def step_grad_desc(w,b,a,x,y):
sum_grad_w = 0
sum_grad_b = 0
M = len(x)
#计算出梯度公式
for i in range(M):
sum_grad_w += (w * x[i] + b -y[i]) *x[i]
sum_grad_b += (w * x[i] + b -y[i])
#计算当前梯度
grad_w = 2/M * sum_grad_w
grad_b = 2/M * sum_grad_b
#梯度下降
new_w = w - a * grad_w
new_b = b - a * grad_w
return new_w,new_b
梯度下降迭代
def grad_desc(x,y,init_w,init_b,a,iter_num):
w = init_w
b = init_b
#保存所有损失函数值,查看下降的轨迹
cost_list = []
for i in range(iter_num):
#计算每次的损失函数值
cost_list.append(cost_fun(w,b,x,y))
w,b = step_grad_desc(w,b,a,x,y)
return [w,b,cost_list]
运行梯度下降法
#运行梯度下降法
w,b,cost_list = grad_desc(x,y,init_w,init_b,a,iter_num)
print('w :', w)
print('b :', b)
cost = cost_fun(w, b, x,y)
print('cost:', cost)
来看下我们的梯度下降轨迹
plt.plot(cost_list)
plt.show()
横坐标为迭代次数,纵坐标为损失函数的值。
通过我们算出的w,b来得出我们的拟合函数,并来看看它与实际数值的
plt.scatter(x, y)
# 针对每一个x,计算出预测的值
pred_y = w * x + b
plt.plot(x, pred_y, c='r')
plt.show()
如下图,横坐标为迭代次数,纵坐标为损失函数的值
总结
自此我们的梯度下降法学习算是走完了,结合两篇文章,我们通过下山场景以及数学解释理解了梯度下降法的原理。并通过本文,我们更深入学习梯度下降法,它的作用,它的分类(BGD,SGD,MBGD),各自的优缺点,并实操应用了一把,对梯度下降法有更实际的理解。
学过线性回归的读者大大,可能有更深的体会。我们的例子就是利用梯度下降法,得出我们的线性回归的拟合函数。
梯度下降法算是机器学习中比较常用以及容易理解的优化方法,其它的还有我们之前讲过的最小二乘法。其实梯度下降法就是最小二乘法的优化。此外还有牛顿法,拟牛顿法等,有兴趣的读者大大可以过后了解下。
ps:需要完整代码可以公众号回复‘梯度下降法’得到
推荐阅读: