假设我有一个简单的单层神经网络:

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)

因此,变量 ybatch_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.gradientsoutput_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/

10-14 09:31