He escrito un MLP simple en TensorFlow que está modelando un XOR-Gate .
Entonces para:
input_data = [[0., 0.], [0., 1.], [1., 0.], [1., 1.]]
debería producir lo siguiente:
output_data = [[0.], [1.], [1.], [0.]]
La red tiene una capa de entrada, una capa oculta y una capa de salida con 2, 5 y 1 neuronas cada una.
Actualmente tengo la siguiente entropía cruzada:
cross_entropy = -(n_output * tf.log(output) + (1 - n_output) * tf.log(1 - output))
También probé esta alternativa más simple:
cross_entropy = tf.square(n_output - output)
junto con algunos otros intentos.
Sin embargo, no importa cuál sea mi configuración, el error con a GradientDescentOptimizer
disminuía mucho más lentamente que un AdamOptimizer
.
De hecho, tf.train.AdamOptimizer(0.01)
produjo resultados realmente buenos después de 400-800 pasos de aprendizaje (en dependencia de la tasa de aprendizaje, donde 0.01
tuvo los mejores resultados), mientras que tf.train.GradientDescentOptimizer
siempre se necesitaron más de 2000 pasos de aprendizaje sin importar qué cálculo de entropía cruzada o tasa de aprendizaje se usó.
¿Por qué esto es tan? Parece AdamOptimizer
que siempre es una mejor opción?
Respuestas:
Los
tf.train.AdamOptimizer
usos Kingma y de Ba Adam algoritmo para controlar la velocidad de aprendizaje. Adam ofrece varias ventajas sobre lo simpletf.train.GradientDescentOptimizer
. Lo más importante es que usa promedios móviles de los parámetros (impulso); Bengio discute las razones por las cuales esto es beneficioso en la Sección 3.1.1 de este documento . En pocas palabras, esto le permite a Adam usar un tamaño de paso efectivo más grande, y el algoritmo convergerá a este tamaño de paso sin un ajuste fino.El principal inconveniente del algoritmo es que Adam requiere que se realicen más cálculos para cada parámetro en cada paso de entrenamiento (para mantener los promedios móviles y la varianza, y calcular el gradiente escalado); y se retendrá más estado para cada parámetro (aproximadamente el triple del tamaño del modelo para almacenar el promedio y la varianza de cada parámetro). Un simple
tf.train.GradientDescentOptimizer
podría usarse igualmente en su MLP, pero requeriría más ajuste de hiperparámetro antes de que convergiera tan rápido.fuente
learning_rate
argumento altf.train.GradientDescentOptimizer
constructor hasta que converja más rápido". :)