2016-05-18 2 views
3

Я хотел бы упаковать массив формы (..., n * (n - 1)/2) в нижнюю треугольную часть тензора с формой (..., n, n), где ... обозначает произвольную форму. В NumPy, я бы реализовать его какУпаковочная решетка в нижний треугольник тензора

import numpy as np 

# Create the array to store data in 
arbitrary_shape = (10, 11, 12) 
n = 5 
target = np.zeros(arbitrary_shape + (n, n)) 
# Create the source array 
source = np.random.normal(0, 1, arbitrary_shape + (n * (n - 1)/2,)) 
# Create indices and set values 
u, v = np.tril_indices(n, -1) 
target[..., u, v] = source 
# Check that everything went ok 
print target[0, 0, 0] 

До сих пор я был в состоянии достичь чего-то подобного в tensorflow, используя комбинацию transpose, reshape и scatter_update, но он чувствует себя неуклюжим.

import tensorflow as tf 

# Create the source array 
source = np.random.normal(0, 1, (n * (n - 1)/2,) + arbitrary_shape) 

sess = tf.InteractiveSession() 

# Create a flattened representation 
target = tf.Variable(np.zeros((n * n,) + arbitrary_shape)) 
# Assign the values 
target = tf.scatter_update(target, u * n + v, source) 
# Reorder the axes and reshape into a square matrix along the last dimension 
target = tf.transpose(target, (1, 2, 3, 0)) 
target = tf.reshape(target, arbitrary_shape + (n, n)) 

# Initialise variables and check results 
sess.run(tf.initialize_all_variables()) 
print target.eval()[0, 0, 0] 

sess.close() 

Есть ли лучший способ достичь этого?

ответ

2

Я понимаю, что это немного поздно, но я пытаюсь загрузить нижнюю треугольную матрицу, и я получил это работает, используя sparse_to_dense:

import tensorflow as tf 
import numpy as np 

session = tf.InteractiveSession() 

n = 4 # Number of dimensions of matrix 

# Get pairs of indices of positions 
indices = list(zip(*np.tril_indices(n))) 
indices = tf.constant([list(i) for i in indices], dtype=tf.int64) 

# Test values to load into matrix 
test = tf.constant(np.random.normal(0, 1, int(n*(n+1)/2)), dtype=tf.float64) 

# Can pass in list of values and indices to tf.sparse_to_dense 
# and it will return a dense matrix 
dense = tf.sparse_to_dense(sparse_indices=indices, output_shape=[n, n], \ 
          sparse_values=test, default_value=0, \ 
          validate_indices=True) 

sess.close() 
1

Вы можете сделать это с fill_lower_triangular:

import numpy as np 
import tensorflow as tf 
from tensorflow.python.ops.distributions.util import fill_lower_triangular 
n = 4 
coeffs = tf.constant(np.random.normal(0, 1, int(n*(n+1)/2)), dtype=tf.float64) 
lower_diag = fill_lower_triangular(coeffs) 
Смежные вопросы