简体   繁体   English

在TensorFlow中获取矩阵的对角线

[英]Get the diagonal of a matrix in TensorFlow

Is there a way to extract the diagonal of a square matrix in TensorFlow? 有没有办法在TensorFlow中提取方阵的对角线? That is, for a matrix like this: 也就是说,对于这样的矩阵:

[
 [0, 1, 2],
 [3, 4, 5],
 [6, 7, 8]
]

I want to fetch the elements: [0, 4, 8] 我想获取元素: [0, 4, 8]

In numpy, this is pretty straight-forward via np.diag : Numpy中,通过np.diag非常简单:

In TensorFlow, there is a diag function , but it only forms a new matrix with the elements specified in the argument on the diagonal, which is not what I want. 在TensorFlow中,有一个diag函数 ,但它只与对角线上的参数中指定的元素形成一个新的矩阵,这不是我想要的。

I could imagine how this could be done via striding... but I don't see striding for tensors in TensorFlow. 我可以想象如何通过跨步来实现这一目标...但我不认为在TensorFlow中争取张量。

with tensorflow 0.8 its possible to extract the diagonal elements with tf.diag_part() (see documentation ) 使用tensorflow 0.8可以使用tf.diag_part()提取对角元素(参见文档

UPDATE UPDATE

for tensorflow >= r1.12 its tf.linalg.tensor_diag_part (see documentation ) for tensorflow> = r1.12 its tf.linalg.tensor_diag_part (参见文档

Currently it is possible to extract diagonal elements with tf.diag_part . 目前,可以使用tf.diag_part提取对角元素。 Here is their example: 这是他们的例子:

"""
'input' is [[1, 0, 0, 0],
            [0, 2, 0, 0],
            [0, 0, 3, 0],
            [0, 0, 0, 4]]
"""

tf.diag_part(input) ==> [1, 2, 3, 4]

Old answer (when diag_part) was not available (still relevant if you want to achieve something that is not available now): 旧答案(当diag_part时)不可用(如果你想要实现现在不可用的东西,仍然相关):

After looking though the math operations and tensor transformations , it does not look like such operation exists. 在查看数学运算张量变换之后 ,看起来不存在这样的操作。 Even if you can extract this data with matrix multiplications it would not be efficient (get diagonal is O(n) ). 即使你可以用矩阵乘法提取这些数据,它也不会有效(得到对角线是O(n) )。

You have three approaches, starting with easy to hard. 你有三种方法,从易于努力开始。

  1. Evaluate the tensor, extract diagonal with numpy, build a variable with TF 评估张量,用numpy提取对角线,用TF构建变量
  2. Use tf.pack in a way Anurag suggested (also extract the value 3 using tf.shape 以Anurag建议的方式使用tf.pack (也使用tf.shape提取值3)
  3. Write your own op in C++ , rebuild TF and use it natively. 用C ++编写自己的op ,重建TF并原生使用它。

Use the tf.diag_part() 使用tf.diag_part()

with tf.Session() as sess:
    x = tf.ones(shape=[3, 3])
    x_diag = tf.diag_part(x)
    print(sess.run(x_diag ))

This is probably is a workaround, but works. 这可能是一种解决方法,但有效。

>> sess = tensorflow.InteractiveSession()
>> x = tensorflow.Variable([[1,2,3],[4,5,6],[7,8,9]])
>> x.initializer.run()
>> z = tensorflow.pack([x[i,i] for i in range(3)])
>> z.eval()
array([1, 5, 9], dtype=int32)

Use the gather operation. 使用gather操作。

x = tensorflow.Variable([[1,2,3],[4,5,6],[7,8,9]])
x_flat = tf.reshape(x, [-1])  # flatten the matrix
x_diag = tf.gather(x, [0, 3, 6])

Depending on the context, a mask can be a nice way to `cancel' off diagonal elements of the matrix, especially if you plan in reducing it anyway: 根据上下文,掩码可以是一种很好的方法来“取消”矩阵的对角元素,特别是如果你打算减少它的话:

mask = tf.diag(tf.ones([n]))
y = tf.mul(mask,y)
cost = -tf.reduce_sum(y)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM