【问题标题】:Create a tensor from another with a condition从另一个有条件的张量创建一个张量
【发布时间】:2018-10-15 10:57:29
【问题描述】:

我有一个这样的张量

...
0
0
2
0
1
0
3
1
0
0
0
0
2
3
...

我必须找到一种方法来创建一个形状相同但只有 0 和 1 的张量。这个张量必须与特定数字处于相同的位置。这里是一个例子

# for number 2
...
0
0
1
0
0
0
0
0
0
0
0
0
1
0
...

有没有内置函数可以做到这一点?我在网上和文档中都找不到任何东西。

然后我必须将这个张量乘以这样的数字列表

l = [..., 1.3, 4.3, ...]

获得这个

...
0
0
1.3
0
0
0
0
0
0
0
0
0
4.3
0
...

有没有办法得到这个结果?

编辑

在我的案例中应用此方法时遇到问题。我解释一下。我的索引张量是这样的

points = tf.constant([[[0], [1], [0], [2], [1], [0], [2], [2], [0], [1]],
                      [[1], [2], [0], [0], [1], [0], [1], [2], [0], [2]],
                      [[0], [2], [1], [0], [2], [0], [1], [2], [0], [1]]], dtype=tf.float32)
# shape=(3, 10, 1)

我必须只取第一行的索引,所以我以这种方式取它们

idx = tf.cast(tf.where(tf.equal(tf.slice(points, [0, 0, 0], [1, 10, 1]), tf.constant([2], dtype=tf.float32))), dtype=tf.int32)
# shape=(3, 3)
idx = tf.expand_dims(idx, 0)
# shape=(1, 3, 3)

要输入的值在一个名为 vectors 的列表中,我将它们转换为具有相同的形状

to_feed = np.expand_dims(np.array(vectors), 0)
# shape=(1, 3, 3)

然后我以这种方式应用该方法

res = tf.scatter_nd(idx, to_feed, tf.shape(tf.slice(points, [0, 0, 0], [1, 10, 3])))

但我得到了这个错误

ValueError: The inner 0 dimensions of output.shape=[?,?,?] must match the inner 1 dimensions of updates.shape=[1,3,3]: Shapes must be equal rank, but are 0 and 1 for 'ScatterNd' (op: 'ScatterNd') with input shapes: [1,3,3], [1,3,3], [3].

我最后需要的是这样的张量

to_feed = [[[10, 10, 10], [11, 11, 11], [12, 12, 12]]] # shape=(1, 3, 3)
res = [[[0, 0, 0], [10, 10, 10], [0, 0, 0], [11, 11, 11], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [12, 12, 12], [0, 0, 0]]] # shape=(1, 10, 3)

[0, 0, 0] 随机放置只是为了有个想法)

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    您可以与tf.equal 进行比较,然后将布尔结果转换为与tf.cast 的数字:

    import tensorflow as tf
    
    vector = tf.placeholder(tf.int32, [None])
    num = tf.placeholder(tf.int32, [])
    result = tf.cast(tf.equal(vector, num), tf.int32)
    with tf.Session() as sess:
        print(sess.run(result, feed_dict={vector: [0, 0, 2, 1, 0, 3, 2, 0], num: 2}))
    

    输出:

    [0 0 1 0 0 0 1 0]
    

    编辑:

    上面解决了更简单的第一个问题,但我认为您需要解决您的问题类似于以下内容,使用tf.wheretf.scatter_nd

    import tensorflow as tf
    
    vector = tf.placeholder(tf.int32, [None])
    num = tf.placeholder(tf.int32, [])
    values = tf.placeholder(tf.float32, [None])
    idx = tf.where(tf.equal(vector, num))
    result = tf.scatter_nd(idx, values, tf.cast(tf.shape(vector), idx.dtype))
    with tf.Session() as sess:
        print(sess.run(result, feed_dict={vector: [0, 2, 1, 2, 3, 2, 2, 0],
                                          num: 2,
                                          values: [3, 4.4, 2, 2.2]}))
    

    输出:

    [0.  3.  0.  4.4 0.  2.  2.2 0. ]
    

    编辑:

    关于您的最新示例,我整理了一个 sn-p 来说明我认为您正在努力实现的目标:

    import tensorflow as tf
    
    points = tf.constant([[[0], [1], [0], [2], [1], [0], [2], [2], [0], [1]],
                          [[1], [2], [0], [0], [1], [0], [1], [2], [0], [2]],
                          [[0], [2], [1], [0], [2], [0], [1], [2], [0], [1]]], dtype=tf.float32)
    vectors = tf.constant([[10, 11, 12], [20, 21, 22], [30, 31, 21]], dtype=tf.float32)
    
    points_row = points[:1]
    idx = tf.where(tf.equal(points_row, 2))
    idx = tf.cast(idx, tf.int32)
    res_shape = tf.concat([tf.shape(points_row), [tf.shape(vectors)[1]]], axis=0)
    res = tf.scatter_nd(idx, vectors, res_shape)
    res = tf.squeeze(res, 2)
    
    with tf.Session() as sess:
        print(sess.run(res))
    

    输出:

    [[[ 0.  0.  0.]
      [ 0.  0.  0.]
      [ 0.  0.  0.]
      [10. 11. 12.]
      [ 0.  0.  0.]
      [ 0.  0.  0.]
      [20. 21. 22.]
      [30. 31. 21.]
      [ 0.  0.  0.]
      [ 0.  0.  0.]]]
    

    【讨论】:

    • 谢谢!第二部分?你有什么想法吗?
    • @User 啊等等我没看错。您应该能够使用 * 运算符将一个张量与另一个张量相乘(只要它们具有兼容的尺寸)。请注意,您可能必须转换结果以使数据类型匹配(例如,如果您的第二个张量的类型为 tf.float32,那么您将 tf.cast 改为 tf.int32,而不是 tf.int32)。
    • 是的,我考虑过将其相乘,但问题是张量的形状例如为 [200, 1] 并且值位于长度可能为 40 的列表中,所以我不能在张量之间使用乘法。列表的第一个元素必须与张量中的第一个元素相乘,依此类推。
    • @User 我想我明白你的意思,我已经用另一个 sn-p 更新了答案。
    • @User 再次更新,仍然不确定是不是这样。老实说,这些都是不同(并且越来越复杂)的问题,将来请考虑为每个问题发布一个新问题,或者首先提出完整的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多