将代码从 Tensorflow 1 迁移到 Tensorflow 2 时,如何处理属性错误:“Adam”对象没有属性“compute_gradient”?

Max*_*ius 5 python tensorflow

我正在使用 Tensorflow 并使用已为 Tensorflow 1 实现的代码(https://github.com/openai/maddpg/blob/master/maddpg/common/tf_util.py)。在将代码迁移到 TensorFlow 2 时,我可以使用在线提供的文献进行大部分更改。但是,我无法找到第 145 行的合适替代方案:

gradients = optimizer.compute_gradients(objective, var_list=var_list)
Run Code Online (Sandbox Code Playgroud)

这会引发错误

Attribute Error: 'Adam' object has no attribute 'compute_gradient'
Run Code Online (Sandbox Code Playgroud)

由于此功能不再存在,我可以使用哪些可能的替代方案?我读到可以使用以下函数代替:

gradients = optimizer.get_gradients(objective, var_list)
Run Code Online (Sandbox Code Playgroud)

这会引发值错误

ValueError: Variable <tf.Variable 'agent_0/q_func/fully_connected/weights:0' shape=(9, 64) 
dtype=float32> has `None` for gradient. Please make sure that all of your ops have a 
gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, 
K.round, K.eval.
Run Code Online (Sandbox Code Playgroud)
Versions:
tensorflow              2.4.1
tensorflow-estimator    2.4.0
Run Code Online (Sandbox Code Playgroud)

小智 0

你应该使用tf.GradientTape. 像这样的东西:

with tf.GradientTape() as tape:
    y_pred = my_obj_function(w, b, x)
    loss = my_loss(y_pred, y)

dw, db = tape.gradient(loss, [w, b])
optimizer.apply_gradients(zip([dw, db], [w, b]))
Run Code Online (Sandbox Code Playgroud)

因此梯度位于磁带内部,因为该对象正在观察变量 (w和b) 以及与这些变量相关的损失函数的梯度。然后,您可以将变量及其梯度传递给优化器以执行优化迭代。上例的目标函数和损失函数:

def my_loss(y_pred, y_true):
    return tf.abs(y_pred - y_true)


def my_obj_function(w, b, x):
    return w * x + b
Run Code Online (Sandbox Code Playgroud)

更新

正如我在评论中提到的,确保 var 列表中的所有元素都是TF variables. 如果其中一些不是,只需使用以下命令即可隐藏它们:

var_list = [tf.variable(var) for var in var_list]
Run Code Online (Sandbox Code Playgroud)

然后你就可以计算梯度如下:

with tf.GradientTape() as tape:
    cost = objective(target, the_inputs)
gradients = tape.gradient(cost, var_list)
Run Code Online (Sandbox Code Playgroud)

the_inputs是计算cost使用objective函数所需的值。唯一tape监视定义为的值TF variables并且只能计算它们的梯度。有了梯度,您可以简单地使用优化器来降低本次迭代的成本:

optimizer.apply_gradients(zip(gradients, var_list))
Run Code Online (Sandbox Code Playgroud)