Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert the strictly upper triangular part of a matrix into an array in Tensorflow

I was trying to convert the strictly upper triangular part of a matrix into an array in Tensorflow. Here is an example:

Input:

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

Output:

[2, 3, 6]

I tried the following code but it did not work (an error was reported):

def upper_triangular_to_array(A):
    mask = tf.matrix_band_part(tf.ones_like(A, dtype=tf.bool), 0, -1)
    return tf.boolean_mask(A, mask)

Thank you!

like image 792
Alex Avatar asked Jan 06 '17 21:01

Alex


2 Answers

The following answer follows closely the answer from @Cech_Cohomology, but it doesn't use Numpy in the process, only TensorFlow.

import tensorflow as tf

# The matrix has size n-by-n
n = 3

# A is the matrix
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

ones = tf.ones_like(A)
mask_a = tf.matrix_band_part(ones, 0, -1) # Upper triangular matrix of 0s and 1s
mask_b = tf.matrix_band_part(ones, 0, 0)  # Diagonal matrix of 0s and 1s
mask = tf.cast(mask_a - mask_b, dtype=tf.bool) # Make a bool mask

upper_triangular_flat = tf.boolean_mask(A, mask)

sess = tf.Session()
print(sess.run(upper_triangular_flat))

This outputs:

[2 3 6]

The advantage of this method is that when the graph is run there is no need to give a feed_dict.

like image 119
Walfits Avatar answered Nov 05 '22 23:11

Walfits


I finally figured out how to do that using Tensorflow.

The idea is to define a placeholder as the boolean mask and then use numpy to pass a boolean matrix to the boolean mask in the runtime. I share my code below:

import tensorflow as tf
import numpy as np

# The matrix has size n-by-n
n = 3
# define a boolean mask as a placeholder
mask = tf.placeholder(tf.bool, shape=(n, n))
# A is the matrix
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    npmask = np.triu(np.ones((n, n), dtype=np.bool_), 1)
    A_upper_triangular = tf.boolean_mask(A, mask)
    print(sess.run(A_upper_triangular, feed_dict={mask: npmask}))

My Python version is 3.6 and my Tensorflow version is 0.12.0rc1. The output of the above code is

[2, 3, 6]

This method can be further generalized. We can use numpy to construct any kind of mask and then pass the mask to the Tensorflow to extract the part of the tensor of interest.

like image 28
Alex Avatar answered Nov 06 '22 00:11

Alex