梯度下降法

一 梯度下降法原理

梯度下降(Gradient Descent, GD),是一种基于搜索的最优化方法。梯度下降(Gradient Descent, GD)优化算法,其作用是用来对原始模型的损失函数进行优化,以便寻找到最优的参数,使得损失函数的值最小。
机器学习就是需找一种函数f(x)并进行优化, 且这种函数能够做预测、分类、生成等工作。而梯度下降是目前机器学习、深度学习解决最优化问题的算法中,最核心、应用最广的方法。说白了,梯度就是向量,是多元函数的导数,梯度指向误差值增加最快的方向,导数为0(梯度为0向量)的点,就是优化问题的解。
梯度下降法,从理论上来讲,只能得到局部最优解,而不能得到全局最优解,可以尝试用过以下方法解决即:首先随机产生多个初始参数集,即多组参数集合;然后分别对每个初始参数集使用梯度下降法,直到函数值收敛于某个值;最后从这些值中找出最小值,这个找到的最小值被当作函数的最小值。当然这种方式不一定能找到全局最优解,但是起码能找到较好的。

对多元线性回归的损失函数进行求导,在真实数据中效果比较差,这是因为数据的规模不一样,因此在梯度下降之前需要使用归一化。
数据归一化


from sklearn.preprocessing import StandardScaler

standardScaler = StandardScaler()
standardScaler.fit(X_train)
X_train_std = standardScaler.transform(X_train)
lin_reg3 = LinearRegression()
lin_reg3.fit_gd(X_train_std, y_train)
X_test_std = standardScaler.transform(X_test)
lin_reg2.score(X_test, y_test)

二 代码实现

python中有两种常见求导的方法,一种是使用Scipy库中的derivative方法,另一种就Sympy库中的diff方法。


import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import derivative

def lossFunction(x):
    return (x-2.5)**2-1


import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import derivative

def lossFunction(x):
    return (x-2.5)**2-1

# 在-1到6的范围内构建140个点
plot_x = np.linspace(-1,6,141)

# plot_y 是对应的损失函数值
plot_y = lossFunction(plot_x)

plt.plot(plot_x,plot_y)
plt.show()
算法:计算损失函数J在当前点的对应导数
输入:当前数据点theta
输出:点在损失函数上的导数

def dLF(theta):
    return derivative(lossFunction, theta, dx=1e-6)
   
 theta = 0.0
eta = 0.1
epsilon = 1e-6
while True:
    # 每一轮循环后,要求当前这个点的梯度是多少
    gradient = dLF(theta)
    last_theta = theta
     # 移动点,沿梯度的反方向移动步长eta
    theta = theta - eta * gradient
    # 判断theta是否达到最小值
    # 因为梯度在不断下降,因此新theta的损失函数在不断减小
    # 看差值是否达到了要求
    if(abs(lossFunction(theta) - lossFunction(last_theta)) < epsilon):
        break
print(theta)
print(lossFunction(theta))

创建一个用于存放所有点位置的列表,然后将其在图上绘制出

def gradient_descent(initial_theta, eta, epsilon=1e-6):
    theta = initial_theta
    theta_history.append(theta)
    while True:
        # 每一轮循环后,要求当前这个点的梯度是多少
        gradient = dLF(theta)
        last_theta = theta
        # 移动点,沿梯度的反方向移动步长eta
        theta = theta - eta * gradient
        theta_history.append(theta)
        # 判断theta是否达到损失函数最小值的位置
        if(abs(lossFunction(theta) - lossFunction(last_theta)) < epsilon):
            break
def plot_theta_history():
    plt.plot(plot_x,plot_y)
    plt.plot(np.array(theta_history), lossFunction(np.array(theta_history)), color='red', marker='o')
    plt.show()

调整学习率

eta=0.1
theta_history = []
gradient_descent(0., eta)
plot_theta_history()
print("梯度下降查找次数:",len(theta_history))

在这里插入图片描述
在刚开始时移动比较大,因为学习率是一定的,再乘上梯度本身数值大(比较陡),后来梯度数值小(平缓)所以移动的比较小。且经历了34次查找。
使用使用学习率0.01/0.9进行观察

学习率过小,收敛学习速度变慢,使得算法的效率降低;学习率过大又会导致不收敛

参考:https://mp.weixin.qq.com/s/nI9IBa4ccfg0xqyn0tbRPA
https://mp.weixin.qq.com/s/nI9IBa4ccfg0xqyn0tbRPA

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值