假设我有一个简单的单层神经网络:
x = tf.placeholder(tf.float32, [batch_size, input_dim])
W = tf.Variable(tf.random_normal([input_dim, output_dim]))
a = tf.matmul(x, W)
y = tf.nn.softmax(a)
因此,变量
y
是 batch_size
的维度 output_dim
。我想为批次中的每个样本计算 y
相对于 a
的雅可比矩阵,其维度为 batch_size
by output_dim
by output_dim
。现在,在数学上,雅可比行列式 (dy/da)_{i,j} = -y_i y_j for i != j 否则, (dy/da)_{i,i} = y_i (1 - y_i)。我想知道如何根据 TensorFlow 中的输入计算 softmax 的雅可比行列式?我知道
tf.gradients
将计算标量相对于张量的梯度,所以我认为 TensorFlow 中的循环与 tf.gradients
或什至只是尝试实现上面给出的分析形式的某种组合应该可以工作。但我不确定如何在 TensorFlow 中使用它的 ops 来做到这一点,并且希望能有任何代码来做到这一点! 最佳答案
似乎 tf.gradients
对 output_dim
应用了一个总和。解决方法:先拆栈再重新堆垛。不知道这如何影响效率...
import numpy as np
import tensorflow as tf
batch_size = 3
input_dim = 10
output_dim = 20
W_vals = np.random.rand(input_dim, output_dim).astype(np.float32)
graph = tf.Graph()
with graph.as_default():
x = tf.placeholder(tf.float32, [batch_size, input_dim])
# Use a constant for easier checking
W = tf.constant(W_vals, dtype=tf.float32)
a = tf.matmul(x, W)
y = a
# remove softmax for easier checking
# y = tf.nn.softmax(a)
grads = tf.stack([tf.gradients(yi, x)[0] for yi in tf.unstack(y, axis=1)],
axis=2)
with tf.Session(graph=graph) as sess:
x_vals = np.random.rand(batch_size, input_dim).astype(np.float32)
g_vals = sess.run(grads, feed_dict={x: x_vals})
# check gradients match
tol = 1e-10
for i in range(batch_size):
if np.max(np.abs(g_vals[i] - W_vals)) >= tol:
raise Exception('')
print('Gradients seem to match!')
关于python - Tensorflow 中的 Softmax 雅可比行列式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41841492/