2025年pytorch优化器详解:RMSProp

pytorch优化器详解:RMSProp说明 模型每次反向传导都会给各个可学习参数 p 计算出一个偏导数 用于更新对应的参数 p 通常偏导数 不会直接作用到对应的可学习参数 p 上 而是通过优化器 做一下处理 得到一个新的值 处理过程用函数 F 表示 不同的优化器对应的 F 的内容不同 即 然后和学习率 lr

大家好,我是讯享网,很高兴认识大家。

说明

模型每次反向传导都会给各个可学习参数p计算出一个偏导数g_t
讯享网
,用于更新对应的参数p。通常偏导数g_t不会直接作用到对应的可学习参数p上,而是通过优化器做一下处理,得到一个新的\widehat{g}_t,处理过程用函数F表示(不同的优化器对应的F的内容不同),即\widehat{g}_t=F(g_t),然后和学习率lr一起用于更新可学习参数p,即p=p-\widehat{g}_t*lr

RMSProp原理

假设损失函数是Loss=x^2+10y^2,即我们的目标是学习x和y的值,让Loss尽可能小。如下是绘制损失函数的代码以及绘制出的结果。注意这并不是一个U型槽,它有最小值点,这个点对应的x和y值就是学习的目标。

import numpy as np from matplotlib import pyplot as plt from mpl_toolkits.mplot3d import Axes3D def func(x, y): return x * x + 10 * y * y def paint_loss_func(): x = np.linspace(-50, 50, 100) #x的绘制范围是-50到50,从改区间均匀取100个数 y = np.linspace(-50, 50, 100) #y的绘制范围是-50到50,从改区间均匀取100个数 X, Y = np.meshgrid(x, y) Z = func(X, Y) fig = plt.figure()#figsize=(10, 10)) ax = Axes3D(fig) plt.xlabel('x') plt.ylabel('y') ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow') plt.show() paint_loss_func()

讯享网

通过解析求解,显然当x=0,y=0时,Loss取得最小值。但这里我们通过神经网络反向传播求导的的方式,一步步优化参数,让Loss变小。通过这个过程,可以看出RMSProp算法的作用

假设x和y的初值分别为x=40,y=20,此时对Loss函数进行求导,x和y的梯度分别是g_x=2x=2*40=80,g_y=20y=400,显然x将要移动的距离小于y将要移动的距离,但是实际上x离最优值0更远,差距是40,y离最优值0近一些,距离是20。因此SGD给出的结果并不理想。

RMSProp算法有效解决了这个问题。通过累计各个变量的梯度的平方r,然后用每个变量的梯度除以r,即可有效缓解变量间的梯度差异。如下伪代码是计算过程。

  1. 初始:x,y(这里只有两个可学习参数)
  2. 初始:学习率 lr
  3. 初始:平滑常数(或者叫做衰减速率) \alpha=0.9
  4. 初始:\epsilon =0.000001,加在分母上防止除0
  5. 初始:梯度的平方 r_x=0,r_y=0(有几个参数就有几个r)
  6. while 没有停止训练 do
  7.         计算梯度:g_x,g_y
  8.         累计梯度的平方:r_x=\alpha r_x+(1-\alpha )(g_x)^2r_y也是一样的)
  9.         更新可学习参数:x=x-\frac{g_x}{\sqrt{r_x}+\epsilon }lr(y的更新也是一样的)
  10. end while

下图是训练10次,x和y的移动轨迹,其中红色对应SGD,蓝色对应RMSProp。观察SGD对应的红色轨迹,由于y的梯度很大,y方向移动过多,一下从坡一边跑到了另一边,而x的移动却十分缓慢。但是通过RMSProp,有效消除了梯度差异导致的抖动。

训练过程的代码如下。

讯享网def grad(x, y): #根据上述代码,可知x和y的梯度分别为2x和20y return 2 * x, 20 * y def train_SGD(): cur_x = 40 cur_y = 20 lr = 0.096 track_x = [cur_x] #记录x每次的值 track_y = [cur_y] #记录y每次的值 for i in range(10): #作为demo,这里只训练10次 grad_x, grad_y = grad(cur_x, cur_y) #等效于神经网络的反向传播,求取各参数的梯度 cur_x -= lr * grad_x cur_y -= lr * grad_y track_x.append(cur_x) track_y.append(cur_y) #print(track_x) #print(track_y) return track_x, track_y def train_RMSProp(): cur_x = 40 cur_y = 20 lr = 3 r_x, r_y = 0, 0 #伪代码中的r alpha = 0.9 eps = 1e-06 track_x = [cur_x] track_y = [cur_y] for i in range(10): grad_x, grad_y = grad(cur_x, cur_y) r_x = alpha * r_x + (1 - alpha) * (grad_x * grad_x) r_y = alpha * r_y + (1 - alpha) * (grad_y * grad_y) cur_x -= (grad_x / (np.sqrt(r_x) + eps)) * lr cur_y -= (grad_y / (np.sqrt(r_y) + eps)) * lr track_x.append(cur_x) track_y.append(cur_y) #print(track_x) #print(track_y) return track_x, track_y def paint_tracks(track_x1, track_y1, track_x2, track_y2): x = np.linspace(-50, 50, 100) y = np.linspace(-50, 50, 100) X, Y = np.meshgrid(x, y) Z = func(X, Y) fig = plt.figure(figsize=(10, 10)) ax = Axes3D(fig) plt.xlabel('x') plt.ylabel('y') #ax.plot(track_x, track_y, func(np.array(track_x), np.array(track_y)), 'r--') tx1, ty1 = track_x1[0], track_y1[0] for i in range(1, len(track_x1)): tx2, ty2 = track_x1[i], track_y1[i] tx = np.linspace(tx1, tx2, 100) ty = np.linspace(ty1, ty2, 100) ax.plot(tx, ty, func(tx, ty), 'r-') tx1, ty1 = tx2, ty2 ax.scatter(track_x1, track_y1, func(np.array(track_x1), np.array(track_y1)), s=50, c='r') tx1, ty1 = track_x2[0], track_y2[0] for i in range(1, len(track_x2)): tx2, ty2 = track_x2[i], track_y2[i] tx = np.linspace(tx1, tx2, 100) ty = np.linspace(ty1, ty2, 100) ax.plot(tx, ty, func(tx, ty), 'b-') tx1, ty1 = tx2, ty2 ax.scatter(track_x2, track_y2, func(np.array(track_x2), np.array(track_y2)), s=50, c='b') #ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow') plt.show() track_x_sgd, track_y_sgd = train_SGD() #paint_track(track_x_sgd, track_y_sgd) track_x_rms, track_y_rms = train_RMSProp() paint_tracks(track_x_sgd, track_y_sgd, track_x_rms, track_y_rms)

pytorch RMSProp参数

接下来看下pytorch中的RMSProp优化器,函数原型如下,其中最后三个参数和RMSProp并无直接关系。

torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)

params

模型里需要被更新的可学习参数,即上文的x和y。

lr

学习率。

alpha

平滑常数\alpha

eps

\epsilon,加在分母上防止除0

weight_decay

weight_decay的作用是用当前可学习参数p的值修改偏导数,即:g_t=g_t+(p*weight\_decay),这里待更新的可学习参数p的偏导数就是g_t

weight_decay的作用是正则化,和RMSProp并无直接关系。

momentum

根据上文伪代码第8行,计算出r_x,r_y后,如果momentum=0,则继续后面的计算,即x=x-\frac{g_x}{\sqrt{r_x}+\epsilon }lr

否则计算过程变成\bar{r_x}=\bar{r_x}*momentum+\frac{g_x}{\sqrt{r_x}+\epsilon} ,x=x-\bar{r_x}*lr,其中\bar{r_x}初始为0,g_x是x的梯度,r_x是上述累计的x的梯度的平方。

momentum和RMSProp并无直接关系。

centered

如果centerd为False,则按照上述伪代码计算,即分母是\sqrt{r_x}+\epsilon

否则计算过程变成\bar{g_x}=\alpha \bar{g_x}+(1-\alpha)g_x,r_x=r_x-(\bar{g_x})^2,这里\bar{g_x}初始为0,然后分母依然是\sqrt{r_x}+\epsilon,但是r_x不一样了。

centered和RMSProp并无直接关系,是为了让结果更平稳。

小讯
上一篇 2025-01-17 19:12
下一篇 2025-03-22 09:54

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/44683.html