Reimpreso de:
https
Directorio de artículos
1. Introducción
Cada vez el modelo 反向传导
calculará 可学习参数p
uno para cada uno 偏导数g_t
para 更新
el parámetro p correspondiente. Por lo general, 偏导数g_t
no se aplicará directamente al parámetro aprendible p correspondiente , pero 通过优化器做一下处理
se obtiene uno, 新的值
y el proceso de procesamiento se F
representa mediante una función (el contenido de F correspondiente a diferentes optimizadores es diferente), es decir , luego se usa en conjunto con la tasa de aprendizaje lr
para actualizar el aprendible El parámetro p, es decir .
2. Principio de Adagrad
A menudo usamos el algoritmo de descenso de gradiente para completar el entrenamiento y la optimización de la red neuronal. La velocidad de convergencia del algoritmo de descenso de gradiente será muy lenta . Para resolver este problema, han aparecido algunos algoritmos nuevos basados en el algoritmo de descenso de gradiente. Hay un algoritmo llamado , que acelera el entrenamiento de redes neuronales profundasAdagrad算法
en comparación con los algoritmos de aprendizaje de gradiente . Por lo tanto, es muy adecuado para tratar con datos escasos . AdaGrad puede mejorar en gran medida la solidez de SGD.
AdaGrad: el nombre completo Adaptive Gradient
, gradiente adaptativo, es una extensión del algoritmo de optimización de descenso de gradiente . Se Adagrad优化算法
llama para actualizar los parámetros con una tasa de aprendizaje fija para todos los parámetros , pero el gradiente de diferentes parámetros puede ser diferente, por lo que se requieren diferentes tasas de aprendizaje para un mejor entrenamiento , pero este asunto no se puede entender bien.Operación humana, por lo que Adagrad puede ayúdanos a hacer esto. El algoritmo de optimización de Adagrad es calcular el gradiente de todos los parámetros cada vez que se usa un tamaño de lote de datos para la actualización de parámetros. La idea es inicializar una variable s a 0 para cada parámetro y luego actualizar el Cuando se usa este parámetro, el La fórmula para actualizar el valor del parámetro es: , donde g_x es el valor del gradiente.自适应学习率优化算法
随机梯度下降SGD
该参数的梯度平方求和累加到这个变量 s 上
学习率就变为
x = x - g_x * new_lr(上面的公式)
Aquí ϵ
se agrega por estabilidad numérica, porque es posible que el valor de s sea 0, entonces aparece 0 en el denominador y habrá infinito, por lo general se toma ϵ 10的负10次方
, para que diferentes parámetros tengan diferentes gradientes, y su correspondiente tamaño de s It también es diferente, por lo que la tasa de aprendizaje obtenida por la fórmula anterior también es diferente, lo que da cuenta de la tasa de aprendizaje adaptativo .
Usamos una tasa de aprendizaje adaptable para ayudar al algoritmo a reducir la velocidad de aprendizaje en la dirección del parámetro con un gradiente grande y acelerar la tasa de aprendizaje en la dirección del parámetro con un gradiente pequeño, lo que lleva a la aceleración del Velocidad de entrenamiento de la red neuronal.
Implementación del código del algoritmo de Adagrad
def sgd_adagrad(parameters, sqrs, lr):
eps = 1e-10
for param, sqr in zip(parameters, sqrs):
sqr[:] = sqr + param.grad.data ** 2
div = lr / torch.sqrt(sqr + eps) * param.grad.data
param.data = param.data - div
La idea central de Adagrad es que si el gradiente de un parámetro siempre es muy grande, entonces la tasa de aprendizaje correspondiente se vuelve más pequeña para evitar choques, y el gradiente de un parámetro siempre es muy pequeño, entonces la tasa de aprendizaje de este parámetro se vuelve más grande, para que pueda actualizarse más rápido, que es el núcleo del algoritmo de Adagrad para acelerar la velocidad de entrenamiento de la red neuronal profunda.
3. Principio de RMSProp
RMSProp
El nombre completo Root Mean Square Propagation
es un inédito 自适应学习率方法
, propuesto por Geoff Hinton, que es una extensión del algoritmo de optimización de descenso de gradiente .
AdaGrad
Una limitación de es que puede dar como resultado un tamaño de paso muy pequeño (tasa de aprendizaje) por parámetro al final de la búsqueda , que puede ser grande 减慢搜索进度
y puede significar 无法找到最优值
. RMSProp
Ambos Adadelta
se desarrollan de forma independiente al mismo tiempo y se pueden considerar como extensiones de AdaGrad , ambos para resolver el problema de la tasa de aprendizaje muy reducida de AdaGrad .
RMSProp
Adoptado指数加权移动平均
(promedio móvil exponencialmente ponderado).RMSProp
RelaciónAdaGrad只多了一个超参数
, su papel类似于动量
(momentum), su valor generalmente se establece en0.9
.RMSProp
El objetivo es acelerar el proceso de optimización , por ejemplo, reduciendo el número de iteraciones necesarias para alcanzar un valor óptimo o aumentando la capacidad de un algoritmo de optimización para lograr un mejor resultado final.
Por ejemplo
Supongamos que la función de pérdida es , es decir, nuestro objetivo es aprender los valores de x e y, para que la pérdida sea lo más pequeña posible.
El siguiente es el código para dibujar la función de pérdida y los resultados dibujados. Tenga en cuenta que esta no es una ranura en forma de U, tiene un punto mínimo y los valores x e y correspondientes a este punto son los objetivos de aprendizaje.
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()
A través de la solución analítica, está claro que en ese momento , Loss alcanzó el valor mínimo. Pero aquí optimizamos los parámetros paso a paso a través del método de propagación hacia atrás de la red neuronal para reducir la pérdida. A través de este proceso, podemos ver el papel del algoritmo RMSProp.
Suponiendo que x e y son 初值
respectivamente , la función de pérdida se realiza en este momento 求导
. x和y的梯度
Obviamente , la distancia que se moverá x es menor que la distancia que se moverá y , pero de hecho x está más lejos del valor óptimo 0, la brecha es 40 , ey está más lejos del valor óptimo. El valor del mérito 0 está más cerca y la distancia es 20 . De ahí SGD
el resultado dado 并不理想
.
RMSProp算法
resolvió efectivamente el problema. Para 累计各个变量的梯度的平方r
entonces 用每个变量的梯度除以r
, la diferencia de gradiente entre las variables puede aliviarse de manera efectiva . El siguiente pseudocódigo es el proceso de cálculo:
la siguiente figura es la trayectoria de movimiento de x e y después de entrenar 10 veces, lo que 红色
corresponde a . Observe la trayectoria roja correspondiente a SGD, porque el gradiente de y es muy grande, la dirección de y se mueve demasiado y va de un lado de la pendiente al otro lado a la vez, mientras que el movimiento de x es muy lento. Pero a través de RMSProp, la fluctuación causada por la diferencia de gradiente se elimina de manera efectiva . El código del proceso de entrenamiento es el siguiente:SGD
蓝色
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)
Tres, parámetros RMSProp
A continuación, mire el optimizador RMSProp en pytorch. El prototipo de la función es el siguiente, y los últimos tres parámetros no están directamente relacionados con RMSProp.
torch.optim.RMSprop(params,
lr=0.01,
alpha=0.99,
eps=1e-08,
weight_decay=0,
momentum=0,
centered=False)
-
En el modelo params需要被更新的可学习参数
, es decir, x e y arriba. -
lr
tasa de aprendizaje. -
constante de suavizado alfa
. -
eps
ε, sumado al denominador para evitar la división por 0 -
weight_decay
La función de weight_decay es用当前可学习参数p的值修改偏导数
: , donde la derivada parcial del parámetro programable p a actualizar es .
La función de weight_decay正则化
no está directamente relacionada con RMSProp . -
El impulso
se calcula de acuerdo con la línea 8 del pseudocódigo anterior, si se calcula , continúe con los cálculos posteriores, es decir .
De lo contrario, el proceso de cálculo se convierte en , donde el valor inicial es 0, es el gradiente de x y es el cuadrado del gradiente de x acumulado anteriormente.
impulso y RMSProp no están directamente relacionados .
- centered
Si centerd es False, se calcula según el pseudocódigo anterior, es decir, el denominador es .
De lo contrario, el proceso de cálculo se convierte en , donde el valor inicial es 0 y el denominador sigue siendo el mismo , pero es diferente.
centered no está directamente relacionado con RMSProp, es para hacer que el resultado sea más estable .