4 votes

TensorFlow 2.0 tf.keras API Mode Eager vs. mode Graphique

Dans TensorFlow <2, la fonction de formation pour un acteur DDPG peut être implémentée de manière concise en utilisant tf.keras.backend.function comme suit :

critic_output = self.critic([self.actor(state_input), state_input])
actor_updates = self.optimizer_actor.get_updates(params=self.actor.trainable_weights,
                                                 loss=-tf.keras.backend.mean(critic_output))
self.actor_train_on_batch = tf.keras.backend.function(inputs=[state_input], 
                                                      outputs=[self.actor(state_input)],
                                                      updates=actor_updates)

Ensuite, lors de chaque étape de formation appelant self.actor_train_on_batch([np.array(state_batch)]) calculera les gradients et effectuera les mises à jour.

Cependant, l'exécution de ce programme sur TF 2.0 donne l'erreur suivante en raison de l'activation par défaut de la fonction "eager mode" :

actor_updates = self.optimizer_actor.get_updates(params=self.actor.trainable_weights, loss=-tf.keras.backend.mean(critic_output))
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\optimizer_v2\optimizer_v2.py", line 448, in get_updates
    grads = self.get_gradients(loss, params)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\optimizer_v2\optimizer_v2.py", line 361, in get_gradients
    grads = gradients.gradients(loss, params)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\gradients_impl.py", line 158, in gradients
    unconnected_gradients)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\gradients_util.py", line 547, in _GradientsHelper
    raise RuntimeError("tf.gradients is not supported when eager execution "
RuntimeError: tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.

Comme prévu, la désactivation de l'exécution rapide via tf.compat.v1.disable_eager_execution() corrige le problème.

Cependant, je ne veux pas désactiver l'exécution rapide pour tout - je voudrais utiliser uniquement l'API 2.0. L'exception suggère d'utiliser tf.GradientTape au lieu de tf.gradients mais c'est un appel interne.

Question : Quelle est la manière appropriée de calculer -tf.keras.backend.mean(critic_output) en mode graphique (dans TensorFlow 2.0) ?

0voto

smyskov Points 96

D'après ce que j'ai compris, votre critic_output est juste un tenseur TensorFlow, donc vous pouvez simplement utiliser tf.math.reduce_mean fonctionnement. Et cela fonctionnera dans une session TensorFlow, pas en style impératif. C'est-à-dire que cela retournera une opération à évaluer dans une session TensorFlow.

import tensorflow as tf
import numpy as np

inp = tf.placeholder(dtype=tf.float32)
mean_op = tf.math.reduce_mean(inp)

with tf.Session() as sess:
    print(sess.run(mean_op, feed_dict={inp: np.ones(10)}))
    print(sess.run(mean_op, feed_dict={inp: np.random.randn(10)}))

Il évaluera quelque chose comme :

1.0
-0.002577734

0voto

Andrei Points 1

Donc, tout d'abord, votre erreur est liée au fait que optimizer.get_updates() est conçu pour le mode graphique puisqu'il inclut l'option K.gradients() nécessaire pour obtenir les tenseurs de gradients, puis appliquer la mise à jour basée sur l'optimiseur Keras aux variables entraînables du modèle à l'aide de la fonction K.function . Deuxièmement, en ce qui concerne la solidité de la méthode "eager-mode-or-not", la fonction de coût loss=-tf.keras.backend.mean(critic_output) n'a pas de flux. Ce que vous devriez faire, c'est vous débarrasser de votre code en mode graphique et vous en tenir au mode natif 2.0 eager. Sur la base de votre code, la formation devrait ressembler à ceci :

def train_method(self, state_input):
  with tf.GradientTape() as tape:
    critic_output = self.critic([self.actor(state_input), state_input])
    loss=-tf.keras.backend.mean(critic_output)
  grads = tape.gradient(loss, params=self.actor.trainable_variables)
  # now please note that self.optimizer_actor must have apply_gradients 
  # so it should be tf.train.OptimizerName...
  self.optimizer_actor.apply_gradients(zip(grads, self.actor.trainable_variables))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X