改进版梯度下降

改进版梯度下降

发展历史

img

标准梯度下降法的缺陷

img

如果学习率选的不恰当会出现以上情况

因此有一些自动调学习率的方法。一般来说,随着迭代次数的增加,学习率应该越来越小,因为迭代次数增加后,得到的解应该比较靠近最优解,所以要缩小步长η,那么有什么公式吗?比如:img,但是这样做后,所有参数更新时仍都采用同一个学习率,即学习率不能适应所有的参数更新。

解决方案是:给不同的参数不同的学习率

Adagrad法

假设N元函数f(x),针对一个自变量研究Adagrad梯度下降的迭代过程,

img

可以看出,Adagrad算法中有自适应调整梯度的意味(adaptive gradient),学习率需要除以一个东西,这个东西就是前n次迭代过程中偏导数的平方和再加一个常量最后开根号

举例:使用Adagrad算法求y = x2的最小值点

导函数为g(x) = 2x

初始化x(0) = 4,学习率η=0.25,ε=0.1

第①次迭代:

img

第②次迭代:

img

第③次迭代:

img

求解的过程如下图所示

 

img

对应代码为:

from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
x = np.arange(-4, 4, 0.025)
plt.plot(x,x**2)
plt.title("y = x^2")
def f(x):
    return x**2
def h(x):
    return 2*x
η = 0.25
ε = 0.1
x = 4
iters = 0
sum_square_grad = 0
X = []
Y = []
while iters<12:
    iters+=1
    X.append(x)
    Y.append(f(x))
    sum_square_grad += h(x)**2
    x = x - η/np.sqrt(sum_square_grad+ε)*h(x)
    print(iters,x)
plt.plot(X,Y,"ro")
ax = plt.subplot()
for i in range(len(X)):
    ax.text(X[i], (X[i])**2, "({:.3f},{:.3f})".format(X[i], (X[i])**2), color='red')
plt.show()

缺点:由于分母是累加梯度的平方,到后面累加的比较大时,会导致梯度更新缓慢

RMSprop法

AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。为了解决这一问题,RMSprop算法对Adagrad算法做了一点小小的修改,RMSprop使用了加权平均的方法,由累积平方梯度变成平均平方梯度,解决了后期学习率太小的缺点.(类似于动量梯度下降)

假设N元函数f(x),针对一个自变量研究RMSprop梯度下降的迭代过程,

可以看出分母不再是一味的增加,它会重点考虑距离他较近的梯度(指数衰减的效果),也就不会出现Adagrad到后期收敛缓慢的问题

举例:使用RMSprop算法求y = x2的最小值点

导函数为h(x) = 2x

初始化g(0) = 1,x(0) = 4,ρ=0.9,η=0.01,ε=10-10

第①次迭代:

img

第②次迭代:

img

求解的过程如下图所示

img

对应代码为:

 

from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
x = np.arange(-4, 4, 0.025)
plt.plot(x,x**2)
plt.title("y = x^2")
def f(x):
    return x**2
def h(x):
    return 2*x
g = 1
x = 4
ρ = 0.9
η = 0.01
ε = 10e-10
iters = 0
X = []
Y = []
while iters<12:
    iters+=1
    X.append(x)
    Y.append(f(x))
    g = ρ*g+(1-ρ)*h(x)**2
    x = x - η/np.sqrt(g+ε)*h(x)
    print(iters,x)
plt.plot(X,Y,"ro")
ax = plt.subplot()
for i in range(len(X)):
    ax.text(X[i], (X[i])**2, "({:.3f},{:.3f})".format(X[i], (X[i])**2), color='red')
plt.show()

Momentum法

Momentum是动量的意思,想象一下,一个小车从高坡上冲下来,他不会停在最低点,因为他还有一个动量,还会向前冲,甚至可以冲过一些小的山丘,如果面对的是较大的坡,他可能爬不上去,最终又会倒车回来,折叠几次,停在谷底。

img

如果使用的是没有动量的梯度下降法,则可能会停到第一个次优解

img

最直观的理解就是,若当前的梯度方向与累积的历史梯度方向一致,则当前的梯度会被加强,从而这一步下降的幅度更大。若当前的梯度方向与累积的梯度方向不一致,则会减弱当前下降的梯度幅度。

img

从这幅图可以看出来,当小球到达A点处,负梯度方向的红箭头朝着x轴负向,但是动量方向(绿箭头)朝着x轴的正向并且长度大于红箭头,因此小球在A处还会朝着x轴正向移动。

下面正式介绍Momentum法

假设N元函数f(x),针对一个自变量研究Momentum梯度下降的迭代过程,

img

v表示动量,初始v=0

α是一个接近于1的数,一般设置为0.9,也就是把之前的动量缩减到0.9倍

η是学习率

下面通过一个例子演示一下,求y = 2*x^4-x^3-x^2的极小值点

img

可以看出从-0.8开始迭代,依靠动量成功越过第一个次优解,发现无法越过最优解,折叠回来,最终收敛到最优解。对应代码如下:

from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure()
x = np.arange(-0.8, 1.2, 0.025)
plt.plot(x,-x**3-x**2+2*x**4)
plt.title("y = 2*x^4-x^3-x^2")
def f(x):
    return 2*x**4-x**3-x**2
def h(x):
    return 8*x**3 - 3*x**2 - 2*x
η = 0.05
α = 0.9
v = 0
x = -0.8
iters = 0
X = []
Y = []
while iters<12:
    iters+=1
    X.append(x)
    Y.append(f(x))
    v = α*v - η*h(x)
    x = x + v
    print(iters,x)
plt.plot(X,Y)
plt.show()

Adam法

Adam实际上是把momentum和RMSprop结合起来的一种算法

假设N元函数f(x),针对一个自变量研究Adam梯度下降的迭代过程,

下面依次解释这五个式子:

 

 

在①式中,注意m(n)是反向的动量与梯度的和(而在Momentum中是正向动量与负梯度的和,因此⑤式对应的是减号)

在②式中,借鉴的是RMSprop的指数衰减

③和④式目的是纠正偏差

⑤式进行梯度更新

举例:使用Adagrad算法求y = x2的最小值点

导函数为h(x) = 2x

初始化x(0) = 4,m(0) = 0,v(0) = 0,β1=0.9,β2=0.999,ε=10-8,η = 0.001

第①次迭代:

img

第②次迭代:

img

求解的过程如下图所示:

img

对应代码为:

from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
x = np.arange(-4, 4, 0.025)
plt.plot(x,x**2)
plt.title("y = x^2")
def f(x):
    return x**2
def h(x):
    return 2*x
x = 4
m = 0
v = 0
β1 = 0.9
β2 = 0.999
η = 0.001
ε = 10e-8
iters = 0
X = []
Y = []
while iters<12:
    iters+=1
    X.append(x)
    Y.append(f(x))
    m = β1*m + (1-β1)*h(x)
    v = β2*v + (1-β2)*h(x)**2
    m_het = m/(1-β1**iters)
    v_het = v/(1-β2**iters)
    x = x - η/np.sqrt(v_het+ε)*m_het
    print(iters,x)
plt.plot(X,Y,"ro")
ax = plt.subplot()
for i in range(len(X)):
    ax.text(X[i], (X[i])**2, "({:.3f},{:.3f})".format(X[i], (X[i])**2), color='red')
plt.show()

 

 

 

转载于:https://www.cnblogs.com/TimVerion/p/11495327.html

### 梯度下降算法的实现原理 梯度下降是一种用于优化目标函数的数值方法,广泛应用于机器学习和深度学习中的参数优化过程。其核心思想是通过计算目标函数相对于模型参数的梯度(偏导数),并沿着负梯度方向逐步调整参数值,从而使得目标函数逐渐接近最小值。 #### 1. 数学基础 假设有一个可微分的目标函数 \( J(\theta) \),其中 \( \theta \) 是待优化的参数向量。梯度下降的核心在于利用该函数的一阶导数来指导参数更新的方向。每次迭代中,参数按照以下公式进行更新: \[ \theta := \theta - \eta \nabla_\theta J(\theta) \] 这里: - \( \eta \) 表示学习率 (learning rate),控制每一步更新的步长大小; - \( \nabla_\theta J(\theta) \) 表示目标函数 \( J(\theta) \) 对于参数 \( \theta \) 的梯度[^2]。 #### 2. 不同类型的梯度下降算法 根据数据处理方式的不同,梯度下降可以分为以下几种主要形式: ##### a. 全梯度下降 (Full Gradient Descent, FG) 全梯度下降使用整个训练集的数据来计算每一次迭代中的梯度。这种方法的优点是可以精确估计梯度,但由于需要遍历所有样本,当数据规模较大时效率较低[^1]。 ##### b. 随机梯度下降 (Stochastic Gradient Descent, SGD) 随机梯度下降在每次迭代中仅选取单个样本来估算梯度。这种方式显著减少了计算开销,但也可能导致更新过程中存在较大的噪声[^1]。 ##### c. 小批量梯度下降 (Mini-Batch Gradient Descent) 小批量梯度下降综合了 FG 和 SGD 的优点,在每次迭代中采用一小部分样本构成的小批次 (mini-batch) 来近似梯度。这种折衷方案既提高了收敛速度又降低了噪音影响[^1]。 #### 3. 学习率的选择与动态调整 选择适当的学习率是一个重要的挑战。过低的学习率会导致收敛缓慢;而过高则可能引起震荡甚至发散。为了应对这一问题,研究者提出了多种自适应学习率的方法,例如退火技术、基于条件触发的衰减机制以及更先进的优化器如 Adam 或 RMSProp 等[^3]。 #### 4. 改进版梯度下降算法 针对原始梯度下降存在的缺陷,后续发展出了许多改进版本,旨在加速收敛、减少振荡或提高鲁棒性。这些变体通常引入额外的状态变量或者修改更新规则以更好地适配不同场景下的需求[^3]。 ```python import numpy as np def gradient_descent(X, y, theta_init, learning_rate=0.01, iterations=1000): m = len(y) theta = theta_init for _ in range(iterations): predictions = X.dot(theta) errors = predictions - y gradients = X.T.dot(errors) / m theta -= learning_rate * gradients return theta ``` 上面展示了一个简单的线性回归情境下应用梯度下降的过程实例代码片段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值