Вложение тензора векторов в тензор матриц - PullRequest
0 голосов
/ 13 декабря 2018

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

В numpy я могу вычислить их, используя numpy.triu_indices, чтобы получить индексы верхней треугольной матрицы, начиная с первой диагонали над главной диагональю, а затем заполнитьэто по предоставленным параметрам, как в следующем фрагменте кода:

import numpy as np

R = np.array([[1,2,1,1,2,1], [1,1,1,1,1,1]]) 

s = R.shape[1]
M = R.shape[0]

iu_r, iu_c = np.triu_indices(s,1)

Q = np.zeros((M,s,s),dtype=float)
Q[:,iu_r,iu_c] = R
Q = Q + np.transpose(Q,(0,2,1))

Вывод:

[[[0. 1. 2. 1.]
 [1. 0. 1. 2.]
 [2. 1. 0. 1.]
 [1. 2. 1. 0.]]

[[0. 1. 1. 1.]
 [1. 0. 1. 1.]
 [1. 1. 0. 1.]
 [1. 1. 1. 0.]]]

Но, очевидно, нельзя напрямую перевести это в tenorflow, как

import tensorflow as tf
import numpy as np

M = 2
s = 4

iu_r, iu_c = np.triu_indices(s,1)

rates = tf.get_variable(shape=(M,s*(s-1)/2), name="R", dtype=float)

Q = tf.get_variable(shape=(M,s,s), dtype=float, initializer=tf.initializers.zeros, name="Q")
Q = Q[:,iu_r,iu_c].assign(rates)

не удается с

TypeError: Tensors in list passed to 'values' of 'Pack' Op have types [int32, int64, int64] that don't all match.

Как правильно определить этот тензор матриц из тензора векторов в тензорном потоке?

РЕДАКТИРОВАТЬ:

Мое текущее решение состоит в том, чтобы встраивать, используя функцию scatter_nd, предоставляемую tenorflow, так как она соответствует потребности в том, что нет необходимости выделять избыточные переменные, как в случае fill_triangular.Хотя индексация несовместима с индексами, сгенерированными с помощью numpy.В настоящее время жестко запрограммирован следующий пример:

import tensorflow as tf
import numpy as np

M = 2
s = 4

iu_r, iu_c = np.triu_indices(s,1)

rates = tf.get_variable(shape=(M,s*(s-1)/2), name="R", dtype=float)

iupper = [[[0,0,1],[0,0,2],[0,0,3],[0,1,2],[0,1,3],[0,2,3]],[[1,0,1],[1,0,2],[1,0,3],[1,1,2],[1,1,3],[1,2,3]]]
Q = tf.scatter_nd(iupper,rates,shape=(M,s,s), name="rate_matrix")

Не должно быть проблем с переводом индексов, полученных с помощью

iu_r, iu_c = np.triu_indices(s,1)

Но, может быть, у кого-то есть более элегантное решение для этого?

Ответы [ 3 ]

0 голосов
/ 16 декабря 2018

Эта часть неясна для меня, как она работает:

import numpy as np

R = np.array([[1,2,1,1,2,1], [1,1,1,1,1,1]]) 

s = R.shape[1]
M = R.shape[0]

iu_r, iu_c = np.triu_indices(s,1)

Q = np.zeros((M,s,s),dtype=float)
Q[:,iu_r,iu_c] = R
Q = Q + np.transpose(Q,(0,2,1))

, потому что это приведет к ошибке по ошибке.Вы можете использовать более простой код, подобный этому:

import numpy as np
R = [1,2,1,1,2,1]
N = 4
Q = np.zeros((N,N),dtype=float)

for i in range(0,N):
  for j in range(0,N):
    if (i<j):
      Q[i][j] = R.pop(0)

Q будет:

[[0. 1. 2. 1.]
 [0. 0. 1. 2.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]]
<class 'numpy.ndarray'>

Чтобы получить симметричный Q, просто используйте это: Q = Q + np.transpose(Q)

Какой бы зигзаг вы ни делали со своими ставками позже, вы можете преобразовать их в тензорные как:

import tensorflow as tf
data_tf = tf.convert_to_tensor(Q, np.float32)
sess = tf.InteractiveSession()  
print(data_tf.eval())
sess.close()
0 голосов
/ 16 декабря 2018

В других ответах предлагается использовать функцию convert_to_tensor для преобразования массива numpy в тензор TensorFlow.

Это действительно может дать вам матрицы с желаемым свойством симметричности снулевая диагональ.Однако, как только вы начнете тренироваться, эти свойства могут больше не сохраняться, так как в целом нет гарантии, что обновления веса сохранят это свойство фиксированным.

Если вам нужно сохранить матрицы симметричными с нулевой диагональюНа протяжении всего процесса обучения вы можете выполнять следующие действия:

import tensorflow as tf
from tensorflow.contrib.distributions import fill_triangular

M = 2 # batch size
s = 4 # matrix size

rates = tf.get_variable(shape=(M,s*(s+1)/2), name="R", dtype=float)

# Q will be triangular (with a non-zero diagonal!)
Q = fill_triangular(rates)

# set the diagonal of Q to zero.
Q = tf.linalg.set_diag(Q,tf.zeros((M,s)))

# make Q symmetric
Q = Q + tf.transpose(Q,[0,2,1])

Вот тест, который проверяет, что матрицы обладают требуемыми свойствами, даже после обучения:

import numpy as np

# define some arbitrary loss function
Q_target = tf.constant(np.random.normal(size=(1,s,s)).astype(np.float32))
loss = tf.nn.l2_loss(Q-Q_target)

# a single training step (which will update the matrices)
train_step =  tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

# this is Q before training
print(sess.run(Q))
#[[[ 0.    -0.564  0.318 -0.446]
#  [-0.564  0.    -0.028  0.2  ]
#  [ 0.318 -0.028  0.     0.369]
#  [-0.446  0.2    0.369  0.   ]]
#
# [[ 0.     0.412  0.216  0.063]
#  [ 0.412  0.     0.221 -0.336]
#  [ 0.216  0.221  0.    -0.653]
#  [ 0.063 -0.336 -0.653  0.   ]]]


# this is Q after training
sess.run(train_step)
print(sess.run(Q))
#[[[ 0.    -0.548  0.235 -0.284]
#  [-0.548  0.    -0.055  0.074]
#  [ 0.235 -0.055  0.     0.25 ]
#  [-0.284  0.074  0.25   0.   ]]
#
# [[ 0.     0.233  0.153  0.123]
#  [ 0.233  0.     0.144 -0.354]
#  [ 0.153  0.144  0.    -0.568]
#  [ 0.123 -0.354 -0.568  0.   ]]]
0 голосов
/ 14 декабря 2018

Очевидно, вам нужно что-то вроде convert_to_tensor .

Эта функция преобразует объекты Python различных типов в объекты Tensor.Он принимает объекты Tensor, массивы numpy, списки Python и скаляры Python.

Примечание: Операции TensorFlow автоматически преобразуют NumPy ndarrays в Tensors.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...