J'utilise TensorFlow pour former un réseau de neurones. Voici comment j'initialise la GradientDescentOptimizer
:
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
mse = tf.reduce_mean(tf.square(out - out_))
train_step = tf.train.GradientDescentOptimizer(0.3).minimize(mse)
La chose ici est que je ne sais pas comment définir une règle de mise à jour pour le taux d'apprentissage ou une valeur de déclin pour cela.
Comment utiliser un taux d'apprentissage adaptatif ici?
Tout d'abord, _tf.train.GradientDescentOptimizer
_ est conçu pour utiliser un taux d'apprentissage constant pour toutes les variables dans toutes les étapes. TensorFlow fournit également des optimiseurs adaptatifs prêts à l'emploi, notamment le tf.train.AdagradOptimizer
et le tf.train.AdamOptimizer
, et ceux-ci peuvent être utilisés comme remplacements directs.
Toutefois, si vous souhaitez contrôler le taux d’apprentissage avec une descente de gradient d’une autre manière, vous pouvez tirer parti du fait que l’argument _learning_rate
_ du constructeur tf.train.GradientDescentOptimizer
peut être un objet Tensor
. Cela vous permet de calculer une valeur différente pour le taux d'apprentissage à chaque étape, par exemple:
_learning_rate = tf.placeholder(tf.float32, shape=[])
# ...
train_step = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate).minimize(mse)
sess = tf.Session()
# Feed different values for learning rate to each training step.
sess.run(train_step, feed_dict={learning_rate: 0.1})
sess.run(train_step, feed_dict={learning_rate: 0.1})
sess.run(train_step, feed_dict={learning_rate: 0.01})
sess.run(train_step, feed_dict={learning_rate: 0.01})
_
Vous pouvez également créer un scalaire _tf.Variable
_ contenant le taux d’apprentissage et l’affecter à chaque fois que vous souhaitez modifier le taux d’apprentissage.
Tensorflow permet d’appliquer automatiquement une décroissance exponentielle à un tenseur du taux d’apprentissage: tf.train.exponential_decay
. Pour un exemple d'utilisation, voir cette ligne dans l'exemple de modèle de convolution MNIST . Utilisez ensuite la suggestion de @ mrry ci-dessus pour fournir cette variable en tant que paramètre learning_rate à l'optimiseur de votre choix.
L'extrait clé à regarder est:
_# Optimizer: set up a variable that's incremented once per batch and
# controls the learning rate decay.
batch = tf.Variable(0)
learning_rate = tf.train.exponential_decay(
0.01, # Base learning rate.
batch * BATCH_SIZE, # Current index into the dataset.
train_size, # Decay step.
0.95, # Decay rate.
staircase=True)
# Use simple momentum for the optimization.
optimizer = tf.train.MomentumOptimizer(learning_rate,
0.9).minimize(loss,
global_step=batch)
_
Notez le paramètre _global_step=batch
_ à réduire. Cela indique à l'optimiseur d'incrémenter utilement le paramètre 'batch' pour vous chaque fois qu'il s'entraîne.
L'algorithme de descente de gradient utilise le taux d'apprentissage constant que vous pouvez fournir en pendant l'initialisation . Vous pouvez passer différents taux d’apprentissage de la manière montrée par Mrry.
Mais au lieu de cela, vous pouvez également utiliser optimiseurs plus avancés qui ont un taux de convergence plus rapide et s’adapte à la situation.
Voici une brève explication basée sur ma compréhension:
Adam ou dynamique adaptative est un algorithme similaire à AdaDelta. Mais en plus de stocker les taux d’apprentissage pour chacun des paramètres, il stocke également les changements d’élan pour chacun d’eux séparément.
De tensorflow documentation officielle
global_step = tf.Variable(0, trainable=False)
starter_learning_rate = 0.1
learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step,
100000, 0.96, staircase=True)
# Passing global_step to minimize() will increment it at each step.
learning_step = (
tf.train.GradientDescentOptimizer(learning_rate)
.minimize(...my loss..., global_step=global_step))
Si vous souhaitez définir des vitesses d’apprentissage spécifiques pour des intervalles d’époques tels que 0 < a < b < c < ...
. Vous pouvez ensuite définir votre vitesse d’apprentissage en tant que tenseur conditionnel, conditionnel à l’étape globale, et l’envoyer normalement à l’optimiseur.
Vous pouvez y parvenir avec un tas d'instructions imbriquées tf.cond
, mais il est plus facile de construire le tenseur récursivement:
def make_learning_rate_tensor(reduction_steps, learning_rates, global_step):
assert len(reduction_steps) + 1 == len(learning_rates)
if len(reduction_steps) == 1:
return tf.cond(
global_step < reduction_steps[0],
lambda: learning_rates[0],
lambda: learning_rates[1]
)
else:
return tf.cond(
global_step < reduction_steps[0],
lambda: learning_rates[0],
lambda: make_learning_rate_tensor(
reduction_steps[1:],
learning_rates[1:],
global_step,)
)
Ensuite, pour l'utiliser, vous devez savoir combien d'étapes de formation il y a dans une même époque, afin que nous puissions utiliser l'étape globale pour passer au bon moment, et enfin définir les époques et les vitesses d'apprentissage souhaitées. Donc, si je veux les taux d'apprentissage [0.1, 0.01, 0.001, 0.0001]
pendant les intervalles de temps de [0, 19], [20, 59], [60, 99], [100, \infty]
respectivement, je ferais:
global_step = tf.train.get_or_create_global_step()
learning_rates = [0.1, 0.01, 0.001, 0.0001]
steps_per_Epoch = 225
epochs_to_switch_at = [20, 60, 100]
epochs_to_switch_at = [x*steps_per_Epoch for x in epochs_to_switch_at ]
learning_rate = make_learning_rate_tensor(epochs_to_switch_at , learning_rates, global_step)