python - mac - Tensorflow: confusión sobre el optimizador de adam
no matching distribution found for tensorflow (2)
Estoy confundido con respecto a cómo el optimizador de Adam realmente funciona en tensorflow.
La forma en que leo los documentos , dice que la tasa de aprendizaje cambia cada iteración de descenso de gradiente.
Pero cuando llamo a la función, le doy una tasa de aprendizaje. Y no llamo a la función para decir, haga una época (llamando implícitamente a # iteraciones para pasar por mi entrenamiento de datos). Llamo explícitamente a la función para cada lote
for epoch in epochs
for batch in data
sess.run(train_adam_step, feed_dict={eta:1e-3})
Entonces mi eta no puede estar cambiando. Y no estoy pasando una variable de tiempo. ¿O es esto una especie de tipo de generador en el que tras la creación de la sesión t
se incrementa cada vez que llamo al optimizador?
Suponiendo que se trata de algo del tipo de generador y la tasa de aprendizaje se reduce de forma invisible: ¿cómo podría ejecutar el optimizador de Adam sin disminuir la velocidad de aprendizaje? Me parece que RMSProp es básicamente el mismo, lo único que tendría que hacer para que sea igual (la tasa de aprendizaje no se tiene en cuenta) es cambiar el momentum
y la decay
los hiperparámetros para que coincidan con beta1
y beta2
respectivamente. ¿Es eso correcto?
Encuentro la documentación bastante clara, pegaré aquí el algoritmo en pseudo-código:
Tus parámetros :
-
learning_rate
: entre 1e-4 y 1e-2 es estándar -
beta1
: 0.9 por defecto -
beta2
: 0.999 por defecto -
epsilon
: 1e-08 por defectoEl valor predeterminado de 1e-8 para epsilon podría no ser un buen valor predeterminado en general. Por ejemplo, al entrenar una red Inception en ImageNet, una buena opción actual es 1.0 o 0.1.
Inicialización:
m_0 <- 0 (Initialize initial 1st moment vector)
v_0 <- 0 (Initialize initial 2nd moment vector)
t <- 0 (Initialize timestep)
m_t
y v_t
llevarán un registro de una media móvil del gradiente y su cuadrado, para cada parámetro de la red. (Entonces, si tienes parámetros 1M, Adam mantendrá en la memoria 2M más parámetros)
En cada iteración t
, y para cada parámetro del modelo :
t <- t + 1
lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t)
m_t <- beta1 * m_{t-1} + (1 - beta1) * gradient
v_t <- beta2 * v_{t-1} + (1 - beta2) * gradient ** 2
variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)
Aquí lr_t
es un poco diferente de learning_rate
porque para las iteraciones tempranas, los promedios móviles aún no han convergido, así que tenemos que normalizar al multiplicar por sqrt(1 - beta2^t) / (1 - beta1^t)
. Cuando t
es alto ( t > 1./(1.-beta2)
), lr_t
es casi igual a learning_rate
Para responder a su pregunta, solo necesita aprobar una tasa de aprendizaje fija , mantener los valores predeterminados beta1
y beta2
, tal vez modificar epsilon
, y Adam hará la magia :)
Enlace con RMSProp
Adam con beta1=1
es equivalente a RMSProp con momentum=0
. El argumento beta2
de Adam y el argumento decay
de RMSProp son los mismos.
Sin embargo, RMSProp no mantiene un promedio móvil del gradiente. Pero puede mantener un impulso, como MomentumOptimizer.
Una descripción detallada de rmsprop.
- mantener un promedio móvil (con descuento) del cuadrado de gradientes
- dividir gradiente por la raíz de este promedio
- (puede mantener un impulso)
Aquí está el pseudo-código:
v_t <- decay * v_{t-1} + (1-decay) * gradient ** 2
mom = momentum * mom{t-1} + learning_rate * gradient / sqrt(v_t + epsilon)
variable <- variable - mom
RMS_PROP y ADAM tienen tasas de aprendizaje adaptativo.
El RMS_PROP básico
cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)
Puedes ver que originalmente tiene dos parámetros decay_rate & eps
Entonces podemos agregar un impulso para hacer que nuestro gradiente sea más estable. Entonces podemos escribir
cache = decay_rate * cache + (1 - decay_rate) * dx**2
**m = beta1*m + (1-beta1)*dx** [beta1 =momentum parameter in the doc ]
x += - learning_rate * dx / (np.sqrt(cache) + eps)
Ahora puede ver aquí si mantenemos beta1 = o Entonces es rms_prop sin impulso.
Luego, Conceptos básicos de ADAM
En cs-231, Andrej Karpathy describió inicialmente a la adam así
Adam es una actualización recientemente propuesta que se parece un poco a RMSProp con impulso
Entonces sí ! Entonces, ¿qué hace que esta diferencia entre el rms_prop y el impulso?
m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
**x += - learning_rate * m / (np.sqrt(v) + eps)**
Él nuevamente mencionó en la ecuación de actualización m, v son más suaves .
Entonces, la diferencia con el rms_prop es que la actualización es menos ruidosa.
¿Qué hace este ruido?
Bien en el procedimiento de inicialización inicializaremos myv como cero.
m = v = 0
Para reducir este efecto de inicialización, siempre es necesario tener un poco de calentamiento. Entonces la ecuación es como
m = beta1*m + (1-beta1)*dx beta1 -o.9 beta2-0.999
**mt = m / (1-beta1**t)**
v = beta2*v + (1-beta2)*(dx**2)
**vt = v / (1-beta2**t)**
x += - learning_rate * mt / (np.sqrt(vt) + eps)
Ahora ejecutamos esto por pocas iteraciones. Claramente preste atención a las líneas gruesas, puede ver cuando t está aumentando (número de iteración) después de que le suceda al mt,
mt = m