[英]TensorFlow 2.0 tf.keras API Eager mode vs. Graph mode
In TensorFlow <2 the training function for a DDPG actor could be concisely implemented using tf.keras.backend.function
as follows: 在TensorFlow <2中,DDPG actor的训练函数可以使用
tf.keras.backend.function
简洁地实现,如下所示:
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)
Then during each training step calling self.actor_train_on_batch([np.array(state_batch)])
would compute the gradients and perform the updates. 然后在每个训练步骤中调用
self.actor_train_on_batch([np.array(state_batch)])
将计算渐变并执行更新。
However running that on TF 2.0 gives the following error due to eager mode being on by default: 但是,由于默认情况下打开了急切模式,因此在TF 2.0上运行会出现以下错误:
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.
As expected, disabling eager execution via tf.compat.v1.disable_eager_execution()
fixes the issue. 正如预期的那样,通过
tf.compat.v1.disable_eager_execution()
禁用急切执行可以解决问题。
However I don't want to disable eager execution for everything - I would like to use purely the 2.0 API. 但是我不想禁用所有内容的急切执行 - 我想纯粹使用2.0 API。 The exception suggests using
tf.GradientTape
instead of tf.gradients
but that's an internal call. 例外建议使用
tf.GradientTape
而不是tf.gradients
但这是一个内部调用。
Question: What is the appropriate way of computing -tf.keras.backend.mean(critic_output)
in graph mode (in TensorFlow 2.0)? 问题:在图形模式下(在TensorFlow 2.0中)计算
-tf.keras.backend.mean(critic_output)
的适当方法是什么?
As far as I understood, your critic_output
is just a TensorFlow tensor, so you can just use tf.math.reduce_mean
operation. 据我
critic_output
,您的critic_output
只是一个TensorFlow张量,所以你可以使用tf.math.reduce_mean
操作。 And it'll work in a TensorFlow session, not in imperative style. 它将在TensorFlow会话中工作,而不是以命令式方式工作。 Ie this will return an operation to be evaluated in a TensorFlow 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)}))
It'll evaluate in something like: 它将评估类似于:
1.0
-0.002577734
So, first of all you error is related to the fact that optimizer.get_updates()
is designed for graph mode as it does include the K.gradients()
needed to get the gradients tensors and then apply the Keras optimizer-based update to the trainable variables of the model using the K.function
. 所以,首先你的错误与
optimizer.get_updates()
是为图形模式设计的事实有关,因为它包含了获得渐变张量所需的K.gradients()
,然后将基于Keras优化器的更新应用于使用K.function
的模型的可训练变量。 Secondly, in terms of eager-mode-or-not soundness the cost function loss=-tf.keras.backend.mean(critic_output)
has no flows. 其次,就急切模式或非健全性而言,成本函数
loss=-tf.keras.backend.mean(critic_output)
没有流动。 What you should to is get rid of your graph mode code and stick to the native 2.0 eager mode. 你应该摆脱你的图形模式代码并坚持原生的2.0渴望模式。 Based on your code the training should look like:
根据您的代码,培训应如下所示:
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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.