问题
考虑问题设置
x : A (N, K) tensor that we want to differentiate with respect to.
f(x): A function sending x to a scalar i.e.
f: R^(N x K) -> R
我想要找到的是每个观察值x[i,:]
(大小N
轴)、梯度(N x K
)和 Hessian (N x K x K
)。
渐变
现在,每次观察的梯度很容易找到,因为您只需找到f
相对于所有x
值的梯度,即
df/dx[0,0] ... df/dx[0,K]
. .
. .
. .
df/dx[N,0] ... df/dx[N,K]
这可以简单地完成
tf.gradients(f(x), x)
黑森州
我现在遇到的问题是找到大小(N, K, K)
Hessian 张量。如果我tf.hessians
天真地使用该功能,即
tf.hessians(f(x), x)
这找到(正确地)(N, K, N, K)
偏二阶导数的张量,即使对于x
观察之间的值也是如此。这些始终为 0(在我的情况下),因此对于较大的值N
可能非常低效。
我怎样才能让 Tensorflow 只找到带有条目的N
(K x K)
Hessian 矩阵进行观察?j, k
df/(dx[i,j]dx[i,k])
i
我认为值可能有一个循环解决方案0, ..., N-1
,但是N
静态图也不知道它,它只是为新输入动态定义的。
虚拟代码
以下是说明该问题的最小工作示例。
import tensorflow as tf
import numpy as np
N = 2
K = 3
# Create dummy data.
x_np = np.random.rand(N, K).astype(np.float32)
# Define Tensorflow graph.
x = tf.placeholder(tf.float32, shape=(None, K), name='x')
f = tf.reduce_sum(tf.multiply(x, x), name='f')
grad = tf.gradients(f, x, name='grad')
hess = tf.hessians(f, x, name='hess')
# Run the Tensorflow graph.
sess = tf.Session()
print("\nTensorflow gradient:")
print(sess.run(grad, feed_dict={'x:0': x_np})[0])
print("\nTensorflow Hessian:")
hess_tf = sess.run(hess, feed_dict={'x:0': x_np})[0]
print(hess_tf)
# Show how we can get the Hessian we want from `hess_tf`.
hess_np = np.empty([N, K, K])
for i in range(N):
hess_np[i, :, :] = hess_tf[i, :, i, :]
print("\nWanted Hessian:")
print(hess_np)