大白话讲梯度下降法(二)

上文我们已经讲了梯度下降法的概念,原理,数学解释,相信看过的读者大大对梯度下降法已经有一个大致的了解。需要阅读,可以点击大白话讲梯度下降法(一)

知道一个事物的原理,只能会了一半。我们学一样东西肯定是想知道它有什么用,可以怎么用,这就是本篇的目的,那么让我们开始吧。

梯度下降法有什么用

机器学习中本质上就是求解我们的假设函数,那么怎么判断我们的假设函数就是符合我们的业务场景的呢。换个思路思考,当我们的假设函数与我们的实际函数误差越来越小的时候,也就是越接近我们的实际函数,所以我们可以把问题转化成,使误差函数最小,即最小化误差函数,也就是最小化损失函数,也就是找到这个损失函数的最小点。

我们前文是通过下山场景来理解我们的梯度下降法的,我们需要走到山底,然后我们使用了梯度下降法来帮我们寻找到最低点,结合上下文,我们可以了解到梯度下降法可以帮助找到损失函数的最小值,从而优化我们的假设函数,使得我们的假设函数更接近实际函数,找到最优拟合函数。

怎么优化梯度下降法

在前文我们了解到梯度下降法有几个要素,如果要优化梯度下降法,我们就可以从这些要素入手,通过公式回顾一下我们的梯度下降法公式。

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:需要完整代码可以公众号回复‘梯度下降法’得到

推荐阅读:

大白话讲梯度下降法(一)

深入浅出Apriori关联分析算法(一)

深入浅出Apriori关联分析算法(二)

发布了76 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jiangzhali1623/article/details/103077857
今日推荐