我想计算神经网络输出相对于输入的梯度。我有以下张量:
Input: (num_timesteps, features)
Output: (num_timesteps, 1)
对于从输入到整个输出向量的渐变,我可以使用以下内容:
tf.gradients(Output, Input)
由于我想计算每一次样本的渐变,我想计算
tf.gradients(Output[i], Input)
每个i
。
最好的方法是什么?
答案 0 :(得分:1)
首先,我想你的意思是Output
关于 Input
的渐变。
现在,这两个电话都是the result:
dO = tf.gradients(Output, Input)
dO_i = tf.gradients(Output[i], Input)
(适用于任何有效的i
)将是一个包含单个元素的列表 - 与Input
具有相同形状的张量,即[num_timesteps, features]
矩阵。此外,如果您对所有矩阵求和dO_i
(超过所有有效i
),则正好是矩阵dO
。
考虑到这一点,回到你的问题。在许多情况下,Input
中的各个行都是独立的,这意味着Output[i]
仅从Input[i]
计算,并且不知道其他输入(典型情况:没有batchnorm的批处理) 。如果是这种情况,那么dO
会立即为您提供所有单独的组件dO_i
。
这是因为每个dO_i
矩阵看起来都是这样的:
[[ 0. 0. 0.]
[ 0. 0. 0.]
...
[ 0. 0. 0.]
[ xxx xxx xxx] <- i-th row
[ 0. 0. 0.]
...
[ 0. 0. 0.]]
除了0
之外,所有行都将是i
。因此,只需计算一个矩阵dO
,您就可以轻松获得每个dO_i
。这非常有效。
但是,如果不是您的情况且所有Output[i]
都依赖于所有输入,那么就无法从其总和中提取单个dO_i
。除了单独计算每个渐变之外别无选择:只需迭代i
并执行tf.gradients
。