梯度下降所带来的问题——迭代发散

对于梯度下降算法,我们知道α值过小时,每次下降的程度非常小,导致接近最小值的过程较长,而当α值过大时,就特别容易发散。处理时可以使用数据归一化

对于α值的设置需要十分小心。我通过拟合一元线性回归时,使用梯度下降算法不断最小化损失函数

J ( θ 0 , θ 1 ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(θ_0,θ_1)=\frac{1}{2m}\sum_{i=1}^m(h_θ(x^{(i)})−y^{(i)})^2 J(θ0,θ1)=2m1i=1m(hθ(x(i))y(i))2
其中的偏导项是
∂ J ( θ 0 , θ 1 ) ∂ θ j = 1 m ∑ i = 0 m ( h θ ( x i ) − y i ) x j i \begin{aligned} \frac{\partial J(θ_0,θ_1)}{\partial\theta_j} = \frac1m\sum_{i=0}^m(h_\theta(x^i)-y^i)x^i_j \end{aligned} θjJ(θ0,θ1)=m1i=0m(hθ(xi)yi)xji
最开始数据通过标准化方程直接求解得到的数据
Y = 0.047 x + 7.03 Y = 0.047x+7.03 Y=0.047x+7.03
之后尝试使用梯度下降算法求损失函数最小值,系数初值为0

α值设置为0.0001

所得到的最终值直接发散,函数走势如图
在这里插入图片描述

尝试减小α值为0.00001

此时并未发散,a = 0.082 b=0.17与期望值相差特别多,其走势如图
在这里插入图片描述

可见下降速度十分慢,迭代10000效果并不理想

将α值设为0.0006时结果为 a=0.078 b=0.99,走势如图
在这里插入图片描述

也许你会想,再加大一点α值,会收敛的更快,但是只加了0.00001

也就是α值为0.00007时,迭代发散了……
在这里插入图片描述

当试着减少0.000001时,也就是α值为0.000069时,迭代并没有发散,但所带来的结果仅为 a = 0.07 b=1.12 与期望值0.04与7.03相差实在太多,而最小值下降的速度实在是太慢,10000次仅下降至最小值的一半(PS:α=0.0000699 同样会发散 >_<)
在这里插入图片描述

只有将初值设置为[7,0]期望值附近时所得到的迭代速度才会更加迅速
在这里插入图片描述

尝试了多种解决方案后终于找到一个方式,将原始数据归一化

将数据归一化后得到的期望值为
Y = 4.071 X + 14.022 Y = 4.071X+14.022 Y=4.071X+14.022
而使用梯度下降算法时,最开始也是尝试比较小的α值,比如0.00006,0.00007,发现并为再次出现发散的情况,但收敛速度也是极慢,之后经过尝试直接将α值增大至0.01此时依旧没有发散,而且收敛效果非常好,结果为
Y = 4.070 X + 14.021 Y=4.070X+14.021 Y=4.070X+14.021
基本吻合期望值,函数下降趋势如图,下降效果十分明显
在这里插入图片描述

代码如下:

# coding=utf-8
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
df = pd.read_csv('adver.csv')
Y = df.iloc[:,3]
X = df.iloc[:,0]
# plt.scatter(x=X,y=Y)
# plt.show()
my = np.mean(Y)
mx = np.mean(X)
dx = (X-mx)/np.std(X)
dy=(Y-my)/np.std(Y)

ymat=np.mat(Y).T
bias= np.ones((X.size))
xmat= np.mat(dx).T
xmat=np.insert(xmat,0,values=bias,axis=1)
# 标准方程解法
xtx = xmat.T*xmat
w=[]
w=xtx.I*(xmat.T*ymat)
print(w)

# model=linear_model.LinearRegression()
# model.fit(xmat,ymat)
# print(model.coef_)
# print(model.intercept_)

def cossfun(x,y,theta):
    m = x.shape[0]
    hx = x*theta
    sqerrors = np.multiply((hx-y),(hx-y))
    J = 1/(2*m)*np.sum(sqerrors)
    return J
def gradientDescent(x,y,theta,alpha):
    m = y.shape[0]
    temp=[]
    j_his = []
    max_iters = 1000
   # epsion = 1e-6

    for i in range(max_iters):
        hx = x * theta
        # hx=x.dot(theta)
        cost = (hx-y)
        theta = theta - (alpha/m)*x.T.dot(cost)

        temp.append(theta)
        J=cossfun(x, y, theta)
        # if abs(j_his[-1:] - J) <= epsion:
        #     break
        j_his.append(J)

    return theta,j_his,temp

theta=np.mat([0,0]).T
theta, j_history, temp = gradientDescent(xmat,ymat,theta,0.01)
print(theta)

plt.plot(range(len(j_history)),j_history)
plt.show()

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
梯度下降算法是机器学习中一种广泛应用的最优化算法,其主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。梯度下降算法的原理可以从一个下山的场景开始理解。算法的基本思想是沿着目标函数梯度的方向更新参数值,以期望达到目标函数的最小值。 在机器学习中,梯度下降算法常常用于求解损失函数的最小值。在简单的线性回归中,我们可以使用最小二乘法来求解损失函数的最小值。然而,在绝大多数情况下,损失函数是非线性的且复杂。因此,梯度下降算法在机器学习领域得到了广泛的应用。实际上,许多优秀的算法都是在梯度下降算法的启发下诞生的,例如AdaGrad、RMSProp、Momentum等等。 梯度下降算法的核心思想是通过计算目标函数的梯度来确定参数更新的方向。梯度表示了函数在某一点上的变化率,沿着梯度的方向可以使函数值快速减小。因此,梯度下降算法沿着梯度的反方向更新参数值,朝着目标函数的最小值靠近。算法的迭代过程会持续更新参数值,直到收敛到最小值或达到停止条件。 在实际应用中,为了提高算法的效率和准确性,通常会对梯度下降算法进行改进和优化。例如,可以使用学习率来控制参数值的更新步长,或者采用批量梯度下降来同时计算多个样本的梯度。这些改进可以帮助算法更快地收敛并找到更好的解。 总之,梯度下降算法是一种重要的最优化算法,在机器学习中被广泛应用。其原理是通过计算目标函数的梯度来更新参数值,以期望达到最小值。通过迭代的方式,梯度下降算法可以找到目标函数的最优解或者接近最优解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值