我感兴趣的是计算损失的梯度,该梯度是根据 TensorFlow 中矩阵乘法与 Eager Execution 的乘积计算得出的。如果乘积被计算为张量,我可以这样做,但如果它是assign()
ed 到变量中。这里是greatly减少代码:
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。但是,如果“PROBLEMATIC”下面的行被注释并且“NO PROBLEM”未被注释,则梯度计算得很好。我推断这是因为在第二种情况下,activations_net
变成一个张量,但我不知道为什么这突然使梯度可计算,而之前却不能。
我很确定我应该保留activations_net
and multiplier_net
作为变量,因为在更大的方案中,两者都是动态更新的,据我了解,这些东西最好保留为变量,而不是不断地重新分配张量。