评估tensorflow中两个张量的行的所有对组合

时间:2017-04-21 04:37:16

标签: python numpy tensorflow

我试图在tensorflow中定义一个自定义op,其中我需要构造一个矩阵(z),它包含两个矩阵的行对的所有组合的总和({{1 }和x)。通常,yx的行数是动态的。

在numpy中它很简单:

y

返回:

import numpy as np
from itertools import product

rows_x = 4
rows_y = 2
dim = 2

x = np.arange(dim*rows_x).reshape(rows_x, dim)
y = np.arange(dim*rows_y).reshape(rows_y, dim)

print('x:\n{},\ny:\n{}\n'.format(x, y))

z = np.zeros((rows_x*rows_y, dim))
print('for loop:')
for i, (x_id, y_id) in enumerate(product(range(rows_x), range(rows_y))):
    print('row {}: {} + {}'.format(i, x[x_id, ], y[y_id, ]))
    z[i, ] = x[x_id, ] + y[y_id, ]

print('\nz:\n{}'.format(z))

但是,我还没有弄清楚如何在tensorflow中实现类似的东西。

我主要是通过SO和tensorflow API来寻找能够产生两个张量元素组合的函数,或者是一个能够给出张量元素排列的函数,但无济于事。

欢迎任何建议。

2 个答案:

答案 0 :(得分:15)

你可以简单地使用张量流的广播能力。

import tensorflow as tf

x = tf.constant([[0, 1],[2, 3],[4, 5],[6, 7]], dtype=tf.float32)
y = tf.constant([[0, 1],[2, 3]], dtype=tf.float32)

x_ = tf.expand_dims(x, 0)
y_ = tf.expand_dims(y, 1)
z = tf.reshape(tf.add(x_, y_), [-1, 2])
# or more succinctly 
z = tf.reshape(x[None] + y[:, None], [-1, 2])

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

答案 1 :(得分:0)

选项1

z定义为变量并更新其行:

import tensorflow as tf
from itertools import product


x = tf.constant([[0, 1],[2, 3],[4, 5],[6, 7]],dtype=tf.float32)
y = tf.constant([[0, 1],[2, 3]],dtype=tf.float32)

rows_x,dim=x.get_shape()
rows_y=y.get_shape()[0]

z=tf.Variable(initial_value=tf.zeros([rows_x*rows_y,dim]),dtype=tf.float32)
for i, (x_id, y_id) in enumerate(product(range(rows_x), range(rows_y))):
    z=tf.scatter_update(z,i,x[x_id]+y[y_id])

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    z_val=sess.run(z)
    print(z_val)

打印

[[  0.   2.]
 [  2.   4.]
 [  2.   4.]
 [  4.   6.]
 [  4.   6.]
 [  6.   8.]
 [  6.   8.]
 [  8.  10.]]

选项2

创建z投掷列表理解:

import tensorflow as tf
from itertools import product


x = tf.constant([[0, 1],[2, 3],[4, 5],[6, 7]],dtype=tf.float32)
y = tf.constant([[0, 1],[2, 3]],dtype=tf.float32)

rows_x,dim=x.get_shape().as_list()
rows_y=y.get_shape().as_list()[0]


z=[x[x_id]+y[y_id] for x_id in range(rows_x) for y_id in range(rows_y)]
z=tf.reshape(z,(rows_x*rows_y,dim))

with tf.Session() as sess:
    z_val=sess.run(z)
    print(z_val)

比较:第二种解决方案快两倍(仅测量两种解决方案中z的构造)。特别是,时间是: 第一种溶液:0.211秒,第二种溶液:0.137秒。