web-dev-qa-db-fra.com

Comment créer un optimiseur dans Tensorflow

Je veux écrire un nouvel algorithme d'optimisation pour mon réseau sur Tensorflow. J'espère implémenter le algorithme d'optimisation de Levenberg Marquardt , qui est maintenant exclu de l'API TF. J'ai trouvé une mauvaise documentation sur la façon d'écrire un optimiseur personnalisé, donc je demande si quelqu'un peut me donner des conseils. Merci.

23
Alberto Manzini

L'exemple le plus simple d'un optimiseur est probablement le optimiseur de descente de gradient . Il montre comment on crée une instance de la base classe optimiseur . La documentation de la classe de base de l'optimiseur explique ce que font les méthodes.

Le côté python des optimiseurs ajoute de nouveaux nœuds au graphique qui calculent et appliquent les gradients rétropropagés. Il fournit les paramètres qui sont passés aux opérations et fait une partie du haut niveau gestion de l’optimiseur. Ensuite, vous avez besoin de l’opération "Appliquer".

Les opérations ont à la fois un python et un composant C++. L'écriture d'une opération d'entraînement est la même (mais spécialisée) que le processus général d'ajout d'un Op = à TensorFlow .

Pour un exemple d'ensemble d'opérations d'entraînement qui calculent et appliquent des gradients, voir python/training/training_ops.py - il s'agit de la colle Python pour les opérations d'entraînement réelles. Remarque que le code ici concerne principalement l'inférence de forme - le calcul va être en C++.

Le calcul réel de l'application des gradients est géré par un Op (rappelant qu'en général, les opérations sont écrites en C++). Dans ce cas, les opérations d'application des gradients sont définies dans core/kernels/training_ops.cc . Vous pouvez y voir, par exemple, l'implémentation de ApplyGradientDescentOp, qui fait référence à un foncteur ApplyGradientDescent:

var.device(d) -= grad * lr();

L'implémentation de la Op elle-même suit l'implémentation de toute autre op comme décrit dans la documentation d'ajout d'une opération.

16
dga

Avant d'exécuter la session Tensorflow, il faut lancer un optimiseur comme indiqué ci-dessous:

# Gradient Descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

tf.train.GradientDescentOptimizer est un objet de la classe GradientDescentOptimizer et as le nom dit, il implémente l'algorithme de descente de gradient.

La méthode minimiser () est appelée avec un "coût" comme paramètre et se compose des deux méthodes compute_gradients ( ) puis apply_gradients () .

Pour la plupart des implémentations d'optimiseur (personnalisées), la méthode apply_gradients () doit être adaptée.

Cette méthode s'appuie sur le (nouveau) Optimizer (classe), que nous allons créer, pour implémenter les méthodes suivantes: _ create_slots (), _prepare (), _apply_dense () et _apply_sparse () .

  • _ create_slots () et _ prepare () crée et initialise des variables supplémentaires, telles que comme un élan.

  • _ apply_dense () , et _ apply_sparse () implémentent les opérations réelles, qui mettre à jour les variables.

Les opérations sont généralement écrites en C++. Sans avoir à modifier vous-même l'en-tête C++, vous pouvez toujours renvoyer un wrapper python de certaines opérations par le biais de ces méthodes. Cela se fait comme suit:

def _create_slots(self, var_list):
   # Create slots for allocation and later management of additional 
   # variables associated with the variables to train.
   # for example: the first and second moments.
   '''
   for v in var_list:
      self._zeros_slot(v, "m", self._name)
      self._zeros_slot(v, "v", self._name)
   '''
def _apply_dense(self, grad, var):
   #define your favourite variable update
    # for example:
   '''
   # Here we apply gradient descents by substracting the variables 
   # with the gradient times the learning_rate (defined in __init__)
   var_update = state_ops.assign_sub(var, self.learning_rate * grad) 
   '''
   #The trick is now to pass the Ops in the control_flow_ops and 
   # eventually groups any particular computation of the slots your 
   # wish to keep track of:
   # for example:    
   '''
    m_t = ...m... #do something with m and grad
    v_t = ...v... # do something with v and grad
    '''
  return control_flow_ops.group(*[var_update, m_t, v_t])

Pour une explication plus détaillée avec un exemple, voir cet article de blog https://www.bigdatarepublic.nl/custom-optimizer-in-tensorflow/

10
Benoit Descamps