Пакетная трансляция вектора при поэлементном вычислении

#tensorflow

#tensorflow

Вопрос:

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

 import tensorflow as tf

#initx = [[1.0, 2.0, 3.0, 4.0],[1.0, 2.0, 3.0, 4.0]]
#initx = [[[1.0, 2.0, 3.0, 4.0]],[[1.0, 2.0, 3.0, 4.0]]]
initx = [[1.0, 2.0, 3.0, 4.0]]

x = tf.placeholder(dtype=tf.float32)

deltas = tf.sub(x,tf.transpose(x))

reshaped_deltas = tf.reshape(deltas,[-1])

with tf.Session('') as session:
  session.run(tf.initialize_all_variables())   

  print "Delta:",session.run([deltas],feed_dict={x:initx })
  print "Flattened Output:",session.run([reshaped_deltas],feed_dict={x:initx })
  

Я получаю ожидаемый результат для одного примера:

 Delta: [array([[ 0.,  1.,  2.,  3.],
       [-1.,  0.,  1.,  2.],
       [-2., -1.,  0.,  1.],
       [-3., -2., -1.,  0.]], dtype=float32)]
Flattened Output: [array([ 0.,  1.,  2.,  3., -1.,  0.,  1.,  2., -2., -1.,  0.,  1., -3.,
       -2., -1.,  0.], dtype=float32)]
  

Я просто не могу понять, как заставить функцию «tf.sub ()» работать с пакетами и при этом правильно транслировать вектор [1,4] для каждого пакета.

Кто-нибудь знает, как это сделать? Я знаю, что есть tf.batch_matmul(), но не batch_sub(), который, вероятно, решил бы проблему.

РЕДАКТИРОВАТЬ: обновленный скрипт для решения проблемы на основе отзывов Ярослава Булатова

 import tensorflow as tf

initx = [[1.5, 2.0, 3.0, 4.0],[1.0, 2.0, 3.0, 4.0]]
#initx = [[1.0, 2.0, 3.0, 4.0]]

VectorSize = len(initx[1])

x = tf.placeholder(dtype=tf.float32)

batch1 = tf.reshape(x, (-1,VectorSize, 1))
deltas = tf.sub(batch1, tf.transpose(batch1, (0, 2, 1)))

reshaped_deltas = tf.reshape(deltas,[-1])

with tf.Session('') as session:
  session.run(tf.initialize_all_variables())   

  print "Delta:",session.run([deltas],feed_dict={x:initx })
  print "Flattened Output:",session.run([reshaped_deltas],feed_dict={x:initx })
  

Ответ №1:

Предположим, что размер вашего пакета n равен, а размер ваших данных k равен. Если ваши входные данные sub будут иметь формы n, k, 1 и n, 1, k , трансляция заполнит одноэлементные размеры, чтобы вывести результат формы n, k, k , который вы хотите. Так что можно было бы использовать tf.reshape , чтобы превратить ваш оригинал в n, k, 1 и tf.transpose(..., perm=(0, 2, 1)) получить n, 1, k форму. Т.Е. что-то вроде этого

 x1 = tf.constant([1,2,3])
x2 = tf.constant([4,4,5])
batch = tf.pack([x1,x2])
n = 2
k = 3
batch1 = tf.reshape(batch, (n, k, 1))
sess = tf.Session()
sess.run(tf.sub(batch1, tf.transpose(batch1, (0, 2, 1))))

Out[] = array([[[ 0, -1, -2],
        [ 1,  0, -1],
        [ 2,  1,  0]],

       [[ 0,  0, -1],
        [ 0,  0, -1],
        [ 1,  1,  0]]], dtype=int32)