使用张量流生成“对称梯形”或“相邻”矩阵的好方法是什么?

时间:2018-06-15 07:03:20

标签: tensorflow matrix

(更新我忘了说输入是批处理的)给定一个bool数组,例如[[false, false, false, true, false, false, true, false, false], [false, true, false, false, false, false, true, false, false]],“true”定义单独序列的边界。我想生成一个相邻矩阵,表示由边界分隔的不同组。使用Tensorflow生成以下“对称阶梯”矩阵的好方法是什么?

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

2018年6月15日更新 实际上,我只是在这个问题上有一些进展,如果我可以将输入senqence从[false,false,false,true,false,false,true,false,false]转换为[1,1,1,0,2, 2,0,3,3],我可以使用以下Tensorflow代码得到一些结果。但我不确定是否有向量操作可以将[false,false,false,true,false,false,true,false,false]转换为[1,1,1,0,2,2,0,3,3 ]?

import tensorflow as tf
sess = tf.Session()

x = tf.constant([1, 1, 1, 0, 2, 2, 0, 3, 3], shape=(9, 1), dtype=tf.int32)
y = tf.squeeze(tf.cast(tf.equal(tf.expand_dims(x, 1), x), tf.int32))
print(sess.run(y))
[[1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0]
 [0 0 0 1 0 0 1 0 0]
 [0 0 0 0 1 1 0 0 0]
 [0 0 0 0 1 1 0 0 0]
 [0 0 0 1 0 0 1 0 0]
 [0 0 0 0 0 0 0 1 1]
 [0 0 0 0 0 0 0 1 1]]

最后更新: 我从@Willem Van Onsem那里获得了很多灵感。 对于批量版本,可以通过修改@Willem Van Onsem解决方案来解决。

import tensorflow as tf
b = tf.constant([[False, False, False, True, False, False, True, False, False], [False, True, False, False, False, False, False, False, False]], shape=(2, 9, 1), dtype=tf.int32)
x = (1 + tf.cumsum(tf.cast(b, tf.int32), axis=1))  * (1-b)
x = tf.cast(tf.equal(x, tf.transpose(x, perm=[0,2,1])),tf.int32) - tf.transpose(b, perm=[0,2,1])*b


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

1 个答案:

答案 0 :(得分:1)

  

但我不确定是否有向量操作可以将[False, False, False, True, False, False, True, False, False]转换为[1, 1, 1, 0, 2, 2, 0, 3, 3]

有,请考虑以下示例:

b = tf.constant([False, False, False, True, False, False, True, False, False], shape=(9,), dtype=tf.int32)

然后我们可以使用tf.cumsum(..)生成:

>>> print(sess.run(1+tf.cumsum(b)))
[1 1 1 2 2 2 3 3 3]

如果我们将这些值乘以b的相反值,我们得到:

>>> print(sess.run((1+tf.cumsum(b))*(1-b)))
[1 1 1 0 2 2 0 3 3]

因此我们可以将此表达式存储在变量中,例如x

x = (1+tf.cumsum(b))*(1-b)
  

我想生成一个相邻矩阵,表示由边界分隔的不同组。使用Tensorflow生成以下“对称阶梯”矩阵的好方法是什么?

如果我们按照您的方法操作,我们只需要同时删除两个列表均为0的点。我们可以这样做:

tf.cast(tf.equal(x, tf.transpose(x)),tf.int32) - tf.transpose(b)*b

所以在这里我们使用你的方法,我们基本上广播x,转换x,并检查元素相等,然后我们减去b的元素乘法从中。然后产生:

>>> print(sess.run(tf.cast(tf.equal(x, tf.transpose(x)),tf.int32) - tf.transpose(b)*b))
[[1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0]
 [0 0 0 0 1 1 0 0 0]
 [0 0 0 0 1 1 0 0 0]
 [0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 1]
 [0 0 0 0 0 0 0 1 1]]