【问题标题】:How to use tf.unique_with_counts for each row/column of a tensor如何为张量的每一行/列使用 tf.unique_with_counts
【发布时间】:2018-07-06 18:36:33
【问题描述】:

我正在尝试使用 tensorflow 解决 KNN。在我得到 N 个向量的 K 个邻居之后,我有一个 N×K 张量。现在,对于 N 中的每个向量,我需要使用tf.unique_with_counts 来找到多数票。但是,我无法在张量中进行迭代,也无法使用多维张量运行 tf.unique_with_counts。它一直给我InvalidArgumentError (see above for traceback): unique expects a 1D vector. 示例:

def knnVote():
  '''
  KNN using majority vote
  '''
  #nearest indices
  A = tf.constant([1, 1, 2, 4, 4, 4, 7, 8, 8])
  print(A.shape)

  nearest_k_y, idx, votes = tf.unique_with_counts(A)
  print("y", nearest_k_y.eval())
  print("idx", idx.eval())
  print("votes", votes.eval())
  majority = tf.argmax(votes)
  predict_res = tf.gather(nearest_k_y, majority)


  print("majority", majority.eval())
  print("predict", predict_res.eval())
  return predict_res

结果:

y [1 2 4 7 8]
idx [0 0 1 2 2 2 3 4 4]
votes [2 1 3 1 2]
majority 2
predict 4

但是如何通过D输入A把这个扩展到N,比如A = tf.constant([[1, 1, 2, 4, 4, 4, 7, 8, 8], [2, 2, 3, 3, 3, 4, 4, 5, 6]])的情况

【问题讨论】:

    标签: python tensorflow machine-learning artificial-intelligence nearest-neighbor


    【解决方案1】:

    您可以使用tf.while_loop 迭代A 行并独立处理每一行。这需要使用shape_invariants(累积结果)和在循环体中仔细处理的一点黑魔法。但多看几眼后,就会或多或少地清晰起来。

    这是一个代码:

    def multidimensionalKnnVote():
      A = tf.constant([
        [1, 1, 2, 4, 4, 4, 7, 8, 8],
        [2, 2, 3, 3, 3, 4, 4, 5, 6],
      ])
    
      def cond(i, all_idxs, all_vals):
        return i < A.shape[0]
    
      def body(i, all_idxs, all_vals):
        nearest_k_y, idx, votes = tf.unique_with_counts(A[i])
        majority_idx = tf.argmax(votes)
        majority_val = nearest_k_y[majority_idx]
    
        majority_idx = tf.reshape(majority_idx, shape=(1,))
        majority_val = tf.reshape(majority_val, shape=(1,))
    
        new_idxs = tf.cond(tf.equal(i, 0),
                           lambda: majority_idx,
                           lambda: tf.concat([all_idxs, majority_idx], axis=0))
    
        new_vals = tf.cond(tf.equal(i, 0),
                           lambda: majority_val,
                           lambda: tf.concat([all_vals, majority_val], axis=0))
    
        return i + 1, new_idxs, new_vals
    
      # This means: starting from 0, apply the `body`, while the `cond` is true.
      # Note that `shape_invariants` allow the 2nd and 3rd tensors to grow.
      i0 = tf.constant(0)
      idx0 = tf.constant(0, shape=(1,), dtype=tf.int64)
      val0 = tf.constant(0, shape=(1,), dtype=tf.int32)
      _, idxs, vals = tf.while_loop(cond, body,
                                    loop_vars=(i0, idx0, val0),
                                    shape_invariants=(i0.shape, tf.TensorShape([None]), tf.TensorShape([None])))
    
      print('majority:', idxs.eval())
      print('predict:', vals.eval())
    

    【讨论】:

      【解决方案2】:

      您可以使用tf.map_fn 将函数应用于矩阵变量的每一行

      def knnVote(A):
        nearest_k_y, idx, votes = tf.unique_with_counts(A)
        majority = tf.argmax(votes)
        predict_res = tf.gather(nearest_k_y, majority)
        return predict_res
      
      sess = tf.Session()
      with sess.as_default():
        B = tf.constant([[1, 1, 2, 4, 4, 4, 7, 8, 8],
                         [2, 2, 3, 3, 3, 4, 4, 5, 6]])
        C = tf.map_fn(knnVote, B)
        print(C.eval())
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-03
        • 1970-01-01
        • 2023-03-28
        相关资源
        最近更新 更多