[英]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.