梯度下降法

目录

 

梯度下降原理

梯度下降法公式:

梯度下降算法的过程

了解:

非凸函数和凸函数

补充


梯度下降原理

  • 在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
  • 在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向

代价函数,初始化,想要改变,使得代价函数达到一个全局最小值(局部最小值),其实是一个迭代的过程。

    下图,给定一个初始值,不断地迭代求梯度,找到当前梯度变化最大的方向走一步,不断地迭代求梯度直到找到一个代价函数值最小的地方,确定了

问题:如果初始值不一样,那么结果就会不一样,如果取的初始值是旁边的那个点呢?最终求得的是最小值没错,但他只是局部的最小值,而不是全局的最小值,这就是梯度下降法本身的一个弊端。

梯度下降法公式:

j可以取0或1,α是学习率,也就是步长意味着我们可以通过α来控制每一步走的距离,公式的意思就是:为初始值,减去学习率(自己定义的)乘以对代价函数求微分,然后将结果赋值给,相当于完成了一次参数的更新。对于梯度下降来说应该采用同步更新,完成一次更新就相当于上图往下走了一步。,不同步的做法不是我们说的梯度下降的算法,是另一种算法,更自然的算法是同步更新的,不同步更新也可能达到最小值但不推荐,我们说的梯度下降就是用的同步更新。

梯度下降法理解:

横坐标为,纵坐标为代价函数值,当取左边第一个点的时候,求他的梯度,显然是个负值,根据公式,减去一个负值就相当于变大了,就到了第二个点的位置,在第二个点的时候梯度(斜率)仍然为负数,仍会变大,就到了第三个点的未位置,这时候第三个点的梯度变成了正值说明计算过后会变小,越接近最小值,斜率(梯度)越小,\small \theta_1的变化越来越小,如此往复,是逐渐逼近代价函数的全局最小值。

学习率的选取

学习率意义上面说了是每次迭代更新后走的步长,不能过大也不能过小,过大会导致错过最小点,出现在一个范围内震荡,永远得不到最小值,如果学习率太大会导致无法收敛甚至发散,过小可能太阳下山了,还没找到最小点,所以可以多次尝试调节,找到适合的学习率(需要一定的经验)。

梯度下降算法的过程

左边为梯度下降优化公式,右边为线性回归模型和代价函数。

计算过程就是对代价函数对求导,即:

了解:

线性回归的代价函数是凸函数

对于凸函数,无论初始值选取如何,最后都会到达全局最小值。

在二维可以用等高图表示,横纵轴分别是\small \theta_0,\theta_1高度为代价函数J,越靠里越逼近真实值:

非凸函数和凸函数

左边为非凸函数,右边为凸函数,对于非凸函数梯度下降法可能会得到局部最小值,而对于凸函数,最后一定会得到以较为接近全局最小值的结果。

补充

对于训练的结果过拟合就类似于左边的图,造成过拟合的原因有很多:

1. 训练集的数量级和模型的复杂度不匹配。训练集的数量级要小于模型的复杂度;

2. 训练集和测试集特征分布不一致;

3. 样本里的噪音数据干扰过大,大到模型过分记住了噪音特征,反而忽略了真实的输入输出间的关 系;

4. 权值学习迭代次数足够多(Overtraining),拟合了训练数据中的噪声和训练样例中没有代表性的特征。

对于合适的训练结果最后应该是一个平滑的曲线,如右图,过拟合会导致最后模型得到的是局部最小值,而不是全局最小值,得到的结果不是预期的结果或有较大偏差。

相对于过拟合就会有欠拟合,例子:

比如要描述一个西瓜的模型,西瓜的属性有:形状、瓜皮,瓜瓤,瓜籽等

过拟合:就会描述的太多了,掺杂了一些没有特征的东西,比如,绿色的瓜皮,瓜皮有条纹,黑色的瓜籽,瓜瓤的纹理,圆的形状等等,拟合了过多的没有代表性的特征,导致最后结果不准确,比如冬瓜的瓜籽也是黑色的,也有瓜瓤,也是圆形的,就会导致最后结果的错误。

欠拟合:就是拟合了过少的特征,比如只拟合了,有瓜皮瓜瓤瓜籽,最后也判断不出正确的结果。

代码实现:

import os
import numpy as np
import matplotlib.pyplot as plt

current_path = os.path.dirname(__file__)
print(current_path)
data = np.genfromtxt(current_path+"/data.csv",delimiter=",")
x_data = data[:,0]
y_data = data[:,1]
plt.scatter(x_data, y_data)
plt.show()


lr=0.0001
#数据
b=0
k=0
#最大迭代次数
epochs=100

#最小二乘法
def compute_error(b,k,x_data,y_data):
    total_error=0
    for i in range(0,len(x_data)):
        total_error+=(y_data[i]-(k*x_data[i]+b))**2
    return total_error/float(len(x_data))/2.0
def gradient_descent_runner(x_data,y_data,b,k,lr,epochs):
    #计算总数据
    m=float(len(x_data))
    #循环epochs次
    for i in range(epochs):
        b_grad=0
        k_grad=0
        #计算梯度(求导)的总和再求平均值
        for j in range(0,len(x_data)):
            b_grad+=(1/m)*((k*x_data[j]+b)-y_data[j])
            k_grad+=(1/m)*x_data[j]*((k*x_data[j]+b)-y_data[j])
        #更新b和k
        b=b-lr*b_grad
        k=k-lr*k_grad
        #每迭代五次输出一次图像
        # if i%5==0:
        #     print("epochs:",i)
        #     plt.plot(x_data,y_data,"b.")
        #     plt.plot(x_data,k*x_data+b,"r")
        #     plt.show()
    return b,k;

print("Starting b={0} k={1} error={2}".format(b,k,compute_error(b,k,x_data,y_data)))
print("Running...")
b,k=gradient_descent_runner(x_data,y_data,b,k,lr,epochs)
print("After {0} iterations b={1} k={2} error={3}".format(epochs,b,k,compute_error(b,k,x_data,y_data)))

plt.plot(x_data,y_data,"b.")
plt.plot(x_data,k*x_data+b,"r")
plt.show()

运行结果:

Starting b=0 k=0 error=1574.2411447744369
Running...
After 100 iterations b=0.02597367274813811 k=0.9753969522590787 error=48.95893439033855

第5次迭代:
 

第10次迭代:

第15次迭代:

............

第100次迭代:

经过100次迭代错误率(代价函数损失值)在减少。

代码二(sklearn):

#encoding=utf-8
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

data = np.genfromtxt("test.csv",delimiter=",")
x_data = data[:,0]
y_data = data[:,1]
plt.scatter(x_data, y_data)
plt.show()
print(x_data.shape)

x_data=data[:,0,np.newaxis]
y_data=data[:,1,np.newaxis]
#创建并拟合模型
model=LinearRegression()
model.fit(x_data,y_data)

plt.plot(x_data,y_data,"b.")
plt.plot(x_data,model.predict(x_data),"r")
plt.show()

结果:

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值