【问题标题】:how to produce a tensor containing the indices of nonzero elements?如何生成包含非零元素索引的张量?
【发布时间】:2018-10-22 00:19:16
【问题描述】:

我有一个像

这样的张量
 [[0, 0, 0, 1, 0, 0],
  [0, 3, 0, 0, 0, 1],
  [0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0],
  [0, 0, 0, 2, 0, 0],
  [0, 0, 0, 0, 0, 0]]

如何生成仅包含前者的非零索引的张量?

[[0,3],[1,1],[1,5],[4,3]]

我在 tfjs 上,所以它似乎没有 boolean_mask 或其他一些似乎在索引中使用的其他有用功能。如果不使用.data() 逃生舱口和对数组进行映射/过滤,这是否可行? (我只是将 tensorflow 用于它的快速线性代数方法,所以这不会是最糟糕的,对吧?)

【问题讨论】:

    标签: javascript node.js tensorflow tensorflow.js


    【解决方案1】:

    确实,目前没有可用于使用掩码定义分区的运算符。您可以将此answer 视为一种解决方法。但是即使使用掩码,这里的问题也不能轻易解决,因为创建分区假设事先知道要检索的索引。

    为了解决这个问题,可以在输入张量和所有元素都等于 1 的形状相同的张量之间使用logicalAnd。它很有用,因为它会返回与输入形状相同的张量如果初始元素为 0,则值为 0,否则为 1。使用argMax,可以检索等于 1 的元素的索引

    let t = tf.tensor2d([[0, 0, 0, 1, 0, 0], [0, 3, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 0]])
    let a = t.as1D()
    
    const b = tf.cast(a, 'bool')
    let helper = b.logicalAnd(tf.cast(tf.ones([a.size]), 'bool'))
    const n = helper.sum().dataSync()[0]
    const noNull = []
    for(let i = 0; i < n ; i++) {
      let ind = tf.argMax(helper)
      let s = ind.dataSync()[0]
      noNull.push(tf.argMax(helper).dataSync()[0])
      if (s === 0) {
         const [x, y] = helper.split([1, helper.size - 1])
         helper = tf.concat(tf.tensor1d([0]), y)
      } else if (s === helper.size) {
        const [x, y] = helper.split([helper.size -1, 1])
        helper = tf.concat(x, tf.tensor1d([0]))
      } else {
        const [x, _, y] = helper.split([s, 1, helper.size - s - 1])
        helper = tf.concat([x,tf.tensor1d([0]), y])
      }
    }
    
    const indexToCoords = (index, shape) => {
      const pseudoShape = shape.map((a, b, c) => c.slice(b + 1).reduce((a, b) => a * b, 1))
      let coords = []
      let ind = index
      for (let i = 0; i < shape.length; i++) {
        coords.push(Math.floor(ind / pseudoShape[i]))
        ind = ind % pseudoShape[i]
      }
      return coords
    }
    
    const coords = noNull.map(e => indexToCoords(e, t.shape))
    
    console.log(coords)
    <html>
      <head>
        <!-- Load TensorFlow.js -->
        <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.0"> </script>
      </head>
    
      <body>
      </body>
    </html>

    按照这个thread,有一个更简单的方法来实现同样的事情

    (async function() {
      const x = tf.tensor2d(
        [[0, 0, 0, 1, 0, 0],
        [0, 3, 0, 0, 0, 1],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 2, 0, 0],
        [0, 0, 0, 0, 0, 0]]);
    
      const mask = x.greater([0]).asType('bool');
      const coords = await tf.whereAsync(mask);
    
      coords.print();
    }());
    <html>
      <head>
        <!-- Load TensorFlow.js -->
        <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.13.0"> </script>
      </head>
    
      <body>
      </body>
    </html>

    【讨论】:

      【解决方案2】:

      您可以使用tf.whereAsync(condition) 返回索引。见docs

      例子:

      (await tf.whereAsync(tf.tensor1d([0,1,2,0,1]).notEqual(0))).print();
      ==> Tensor
          [[1],
           [2],
           [4]]
      

      【讨论】:

        猜你喜欢
        • 2019-09-16
        • 1970-01-01
        • 2020-07-04
        • 1970-01-01
        • 2019-09-28
        • 2017-12-05
        • 2017-01-18
        • 2021-01-26
        • 2021-09-14
        相关资源
        最近更新 更多