Тензор потока в сочетании с транспонированием с использованием широковещательной семантики - PullRequest
0 голосов
/ 02 мая 2018

Скажите v1 и v2 имеет одинаковую форму. Возможно ли в tenorflow объединить v1 и транспонированную версию v2 с использованием семантической трансляции?

Например,

v1 = tf.constant([[1,1,1,1],[3,3,3,3],[5,5,5,5]])
v2 = tf.constant([[2,2,2,2],[4,4,4,4]])

Я хочу произвести что-то вроде

[
 [[[1,1,1,1], [2,2,2,2]],
  [[1,1,1,1], [4,4,4,4]]],
 [[[3,3,3,3], [2,2,2,2]],
  [[3,3,3,3], [4,4,4,4]]],
 [[[5,5,5,5], [2,2,2,2]],
  [[5,5,5,5], [4,4,4,4]]]]

то есть с v1 как [3, 4] и v2 как [2,4], я хочу сделать

tf.concat([v1, tf.transpose(v2)], axis=0)

и производим матрицу [3,2,2,4].

Есть ли какая-нибудь хитрость для этого?

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Вот моя попытка добавить два более изящных решения этой проблемы декартовых произведений следующим образом (оба проверены); первый с использованием tf.map_fn():

import tensorflow as tf

v1 = tf.constant([[1, 1, 1, 1],
                  [3, 3, 3, 3],
                  [5, 5, 5, 5]])
v2 = tf.constant([[2, 2, 2, 2],
                  [4, 4, 4, 4]])

cartesian_product = tf.map_fn( lambda x: tf.map_fn( lambda y: tf.stack( [ x, y ] ), v2 ), v1 )

with tf.Session() as sess:
    print( sess.run( cartesian_product ) )

или этот, использующий неявную трансляцию add:

import tensorflow as tf

v1 = tf.constant([[1, 1, 1, 1],
                  [3, 3, 3, 3],
                  [5, 5, 5, 5]])
v2 = tf.constant([[2, 2, 2, 2],
                  [4, 4, 4, 4]])

v1, v2 = v1[ :, None, None, : ], v2[ None, :, None, : ]
cartesian_product = tf.concat( [ v1 + tf.zeros_like( v2 ),
                                 tf.zeros_like( v1 ) + v2 ], axis = 2 )

with tf.Session() as sess:
    print( sess.run( cartesian_product ) )

оба выхода:

[[[[1 1 1 1]
[2 2 2 2]]

[[1 1 1 1]
[4 4 4 4]]]

[[[3 3 3 3]
[2 2 2 2]]

[[3 3 3 3]
[4 4 4 4]]]

[[[5 5 5 5]
[2 2 2 2]]

[[5 5 5 5]
[4 4 4 4]]]]

по желанию.

0 голосов
/ 02 мая 2018

Если под трюком вы подразумеваете элегантное решение, я так не думаю. Однако, рабочим решением было бы выложить и повторить входящие v1, v2

import tensorflow as tf

v1 = tf.constant([[1, 1, 1, 1],
                  [3, 3, 3, 3],
                  [7, 7, 7, 7],
                  [5, 5, 5, 5]])
v2 = tf.constant([[2, 2, 2, 2],
                  [6, 6, 6, 6],
                  [4, 4, 4, 4]])


def my_concat(v1, v2):
    v1_m, v1_n = v1.shape.as_list()
    v2_m, v2_n = v2.shape.as_list()

    v1 = tf.concat([v1 for i in range(v2_m)], axis=-1)
    v1 = tf.reshape(v1, [v2_m * v1_m, -1])

    v2 = tf.tile(v2, [v1_m, 1])
    v1v2 = tf.concat([v1, v2], axis=-1)

    return tf.reshape(v1v2, [v1_m, v2_m, 2, v2_n])


with tf.Session() as sess:
    ret = sess.run(my_concat(v1, v2))

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