Tensorflow:针对每个样本计算Hessian

时间:2018-05-12 20:45:48

标签: python tensorflow

我的张量X大小 M x D 。我们可以将X的每一行解释为训练样本,将每列作为特征解释。

X用于计算尺寸 M x 1 的张量u(换句话说,u取决于计算图中的X)。我们可以将其解释为预测的向量;每个样本一个。特别是,u的第m行仅使用X的第m行计算。

现在,如果我运行tensor.gradients(u, X)[0],我会获得与" per-sample"相对应的 M x D 张量。 u相对于X的渐变。

我怎样才能类似地计算" per-sample" Hessian张量? (即 M x D x D 数量)

附录:彼得的答案是正确的。我还发现了一种使用堆叠和取消堆叠的不同方法(使用彼得的符号):

hess2 = tf.stack([
    tf.gradients( tmp, a )[ 0 ]
    for tmp in tf.unstack( grad, num=5, axis=1 )
], axis = 2)

在彼得的例子中, D = 5是功能的数量。 我怀疑(但我没有检查过) M 的上述速度更快,因为它跳过了Peter提到的零条目&# 39;答案。

1 个答案:

答案 0 :(得分:3)

tf.hessians()正在计算所提供的 ys xs 的Hessian,无论维度如何。由于您的尺寸 M x D xs 尺寸 M x的结果D 因此结果的尺寸为 M x D x M x D 。但由于每个示例的输出彼此独立,因此大多数Hessian将为零,即第三维中只有一个切片将具有任何值。因此,为了得到你想要的结果,你应该采用两个 M 维度的对角线,或者更容易,你应该简单地总结并消除第三个维度,如下所示: / p>

hess2 = tf.reduce_sum( hess, axis = 2 )

示例代码(已测试):

import tensorflow as tf

a = tf.constant( [ [ 1.0, 1, 1, 1, 1 ], [ 2, 2, 2, 2, 2 ], [ 3, 3, 3, 3, 3 ] ] )
b = tf.constant( [ [ 1.0 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ] ] )
c = tf.matmul( a, b )
c_sq = tf.square( c )

grad = tf.gradients( c_sq, a )[ 0 ]

hess = tf.hessians( c_sq, a )[ 0 ]
hess2 = tf.reduce_sum( hess, axis = 2 )


with tf.Session() as sess:
    res = sess.run( [ c_sq, grad, hess2 ] )

    for v in res:
        print( v.shape )
        print( v )
        print( "=======================")

将输出:

  

(3,1)
  [[225.]
   [900.]
   [2025]
   =======================
  (3,5)
  [[30. 60. 90. 120. 150.]
   [60. 120. 180. 240. 300.]
   [90. 180. 270. 360. 450.]]
   =======================
  (3,5,5)
  [[[2. 4. 6. 8. 10.]
    [4. 8. 12. 16. 20.]
    [6. 12. 18. 24. 30.]
    [8. 16. 24. 32. 40.]
    [10。 20. 30. 40. 50.]]

     

[[2. 4. 6. 8. 10.]
    [4. 8. 12. 16. 20.]
    [6. 12. 18. 24. 30.]
    [8. 16. 24. 32. 40.]
    [10。 20. 30. 40. 50.]]

     

[[2. 4. 6. 8. 10.]
    [4. 8. 12. 16. 20.]
    [6. 12. 18. 24. 30.]
    [8. 16. 24. 32. 40.]
    [10。 20. 30. 40. 50.]]]
   =======================