[英]How to get loss gradient wrt internal layer output in tensorflow 2?
[英]Tensorflow cannot get gradient wrt a Variable, but can wrt a Tensor
我感兴趣的是计算从TensorFlow中的矩阵乘法与Eager执行的乘积计算的损失梯度。 如果将产品计算为张量,我可以这样做,但如果它是为变量assign()
,则不能。 这是大大减少的代码:
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值, 但GRADIENT将打印为None 。 但是,如果注释“问题”下方的行并且取消注释“无问题”,则计算梯度就好了。 我推断这是因为在第二种情况下, activations_net
变成了Tensor,但我不知道为什么突然使梯度可计算,而在它之前没有。
我很确定我应该将activations_net
和multiplier_net
保留为变量,因为在更大的方案中,两者都是动态更新的,据我所知,这些东西最好保存为变量而不是不断重新分配Tensors。
我会尽力解释。 问题出现在这一行
de_dm = tape.gradient(loss, multipliers_net)
如果你在“问题”和“无问题”的情况下print(tape.watched_variables()
,你会看到在第一种情况下磁带' tape.reset()
'两次相同的multipliers_net
变量。你可以尝试tape.reset()
和tape.watch()
,但只要你将op传递给它就没有任何效果。如果你在tf.GradientTape()
尝试multipliers_net.assign(any_variable)
tf.GradientTape()
,你会发现它不起作用。但如果你尝试分配产生张量的东西,例如tf.ones_like()
,它会起作用。
multipliers_net.assign(LEARNING_RATE * de_dm)
这也是出于同样的原因。 它似乎只接受eager_tensors
希望这会eager_tensors
帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.