说v1
和v2
具有相同的形状。在tensorflow中是否可以使用广播语义连接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]
矩阵。
这样做有什么诀窍吗?
答案 0 :(得分:1)
如果你的意思是一个优雅的解决方案,我不这么认为。但是,一个可行的解决方案是平铺并重复传入的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
答案 1 :(得分:-1)
这是我尝试为此笛卡尔积问题添加两个更优雅的解决方案,如下所示(均经过测试);第一个使用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]]]]
根据需要。