Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tensorflow不能得到变量的梯度,但可以得到张量_Python_Tensorflow_Eager Execution - Fatal编程技术网

Python Tensorflow不能得到变量的梯度,但可以得到张量

Python Tensorflow不能得到变量的梯度,但可以得到张量,python,tensorflow,eager-execution,Python,Tensorflow,Eager Execution,我感兴趣的是计算一个损失的梯度,这个梯度是由TensorFlow中的矩阵乘法的乘积计算出来的。如果乘积是作为张量计算的,我可以这样做,但如果它是assign()ed,则不能这样做。以下是大大简化的代码: import tensorflow as tf import numpy as np tf.enable_eager_execution() multipliers_net = tf.get_variable("multipliers", shape=(1, 3, 3, 1),

我感兴趣的是计算一个损失的梯度,这个梯度是由TensorFlow中的矩阵乘法的乘积计算出来的。如果乘积是作为张量计算的,我可以这样做,但如果它是
assign()
ed,则不能这样做。以下是大大简化的代码:

import tensorflow as tf
import numpy as np
tf.enable_eager_execution()

multipliers_net = tf.get_variable("multipliers", shape=(1, 3, 3, 1),
                                  initializer=tf.random_normal_initializer())
activations_net = tf.Variable(tf.ones_like(multipliers_net))
output_indices = [(0, 1, 2, 0)]

def step():
    global activations_net

    #### PROBLEMATIC ####
    activations_net.assign(multipliers_net * activations_net)
    #### NO PROBLEM ####
    # activations_net = multipliers_net * activations_net

    return tf.gather_nd(activations_net, output_indices)


def train(targets):
    for y in targets:
        with tf.GradientTape() as tape:
            out = step()
            print("OUT", out)
            loss = tf.reduce_mean(tf.square(y - out))
            print("LOSS", loss)
        de_dm = tape.gradient(loss, multipliers_net)
        print("GRADIENT", de_dm, sep="\n")
        multipliers_net.assign(LEARNING_RATE * de_dm)


targets = [[2], [3], [4], [5]]

train(targets)
目前,此代码将显示正确的OUT和LOSS值,但渐变将打印为None。但是,如果对“PROBLEM”下面的行进行了注释,而对“NO PROBLEM”未进行注释,那么梯度的计算就可以了。我推断这是因为在第二种情况下,
activations\u net
变成了一个张量,但我不知道为什么会突然使梯度变得可计算,而以前不是


我很确定我应该把
activations\u net
multiplier\u net
作为变量,因为在更大的情况下,两者都是动态更新的,据我所知,这些东西最好作为变量保存,而不是不断地重新分配张量。

我将尽力解释。 该问题发生在该生产线的一个生产线中

de_dm = tape.gradient(loss, multipliers_net)
如果在“有问题”和“没有问题”两种情况下都打印(tape.wasted_variables()),您将看到在第一种情况下,磁带会两次“监视”相同的
乘数。
您可以尝试
tape.reset()
tape.watch()
,但只要您将assign op传递给它,它就没有效果。 如果您尝试在
tf.GradientTape()
中使用
multipliers\u net.assign(任何变量)
,您会发现它不起作用。但是如果您尝试分配产生张量的东西,例如
tf.ones\u like()
,它会起作用

multipliers_net.assign(LEARNING_RATE * de_dm)
这是出于同样的原因。它似乎只接受
eager\u张量

希望这能有所帮助

看起来
assign
op没有梯度,不管你在分配什么…是的。我实际上有点混淆了它的行为,尤其是eager.Variable.assign,它应该可以工作,但它不工作。read\u value参数也可以。但我认为只要你做
乘法器\u net.assign
你就会得到一个resourceVariable这就是你想要的