Eu escrevi um MLP simples no TensorFlow que está modelando um XOR-Gate .
Então para:
input_data = [[0., 0.], [0., 1.], [1., 0.], [1., 1.]]
deve produzir o seguinte:
output_data = [[0.], [1.], [1.], [0.]]
A rede possui uma camada de entrada, uma camada oculta e uma camada de saída com 2, 5 e 1 neurônios cada.
Atualmente, tenho a seguinte entropia cruzada:
cross_entropy = -(n_output * tf.log(output) + (1 - n_output) * tf.log(1 - output))
Eu também tentei esta alternativa mais simples:
cross_entropy = tf.square(n_output - output)
juntamente com algumas outras tentativas.
No entanto, independentemente da minha configuração, o erro com a GradientDescentOptimizer
estava diminuindo muito mais lentamente que com a AdamOptimizer
.
De fato, tf.train.AdamOptimizer(0.01)
produziu resultados realmente bons após 400-800 etapas de aprendizado (dependendo da taxa de aprendizado, onde 0.01
obtiveram os melhores resultados), enquanto tf.train.GradientDescentOptimizer
sempre eram necessárias mais de 2000 etapas de aprendizado, independentemente do cálculo da entropia cruzada ou da taxa de aprendizado.
Porque isto é assim? Parece que AdamOptimizer
é sempre uma escolha melhor ?!
Respostas:
Ele
tf.train.AdamOptimizer
usa o algoritmo Adam de Kingma e Ba para controlar a taxa de aprendizado. Adam oferece várias vantagens sobre o simplestf.train.GradientDescentOptimizer
. O principal é que ele usa médias móveis dos parâmetros (momento); Bengio discute as razões pelas quais isso é benéfico na Seção 3.1.1 deste documento . Simplificando, isso permite que o Adam use um tamanho de etapa efetivo maior e o algoritmo convergirá para esse tamanho de etapa sem ajuste fino.A principal desvantagem do algoritmo é que o Adam exige que mais cálculos sejam realizados para cada parâmetro em cada etapa do treinamento (para manter as médias móveis e a variação e calcular o gradiente escalado); e mais estados a serem retidos para cada parâmetro (aproximadamente triplicando o tamanho do modelo para armazenar a média e a variação de cada parâmetro). Um simples
tf.train.GradientDescentOptimizer
poderia igualmente ser usado em seu MLP, mas exigiria mais ajuste do hiperparâmetro antes de convergir o mais rápido possível.fonte
learning_rate
argumento para otf.train.GradientDescentOptimizer
construtor até convergir mais rapidamente". :)