【问题标题】:TensorFlow - return distinct sub-tensors of multidimensional tensorTensorFlow - 返回多维张量的不同子张量
【发布时间】:2019-07-19 16:03:51
【问题描述】:

在 TensorFlow 中,tf.unique 函数可用于返回一维 Tensor 的不同元素。如何沿更高维Tensor 的轴 0 获得不同的 sub-Tensors?例如,给定以下Tensor,所需的distinct 函数将返回指定的结果:

input = tf.constant([
    [0,3],
    [0,1],
    [0,4],
    [0,1],
    [1,5],
    [3,9],
    [3,2],
    [3,6],
    [3,5],
    [3,3]])

distinct(input) == tf.constant([
    [0,3],
    [0,1],
    [0,4],
    [1,5],
    [3,9],
    [3,2],
    [3,6],
    [3,5],
    [3,3]])

如何为任意维数的Tensors 生成不同的多维元素?

【问题讨论】:

    标签: python tensorflow tensorflow2.0


    【解决方案1】:

    不保留秩序

    您可以使用tf.py_function 并调用np.unique 来返回沿axis=0 的唯一多维张量。请注意,这会找到唯一的行,但不会保留顺序。

    def distinct(a):
        _a =  np.unique(a, axis=0)
        return _a
    
    >> input = tf.constant([
    [0,3],
    [0,1],
    [0,4],
    [0,1],
    [1,5],
    [3,9],
    [3,2],
    [3,6],
    [3,5],
    [3,3]])
    
    >> tf.py_function(distinct, [input], tf.int32)
    <tf.Tensor: id=940, shape=(9, 2), dtype=int32, numpy=
    array([[0, 1],
       [0, 3],
       [0, 4],
       [1, 5],
       [3, 2],
       [3, 3],
       [3, 5],
       [3, 6],
       [3, 9]], dtype=int32)>
    

    保留订单

    def distinct_with_order_preserved(a):
        _a = a.numpy()
        return pd.DataFrame(_a).drop_duplicates().values
    
    >> tf.py_function(distinct_with_order_preserved, [input], tf.int32)
    <tf.Tensor: id=950, shape=(9, 2), dtype=int32, numpy=
    array([[0, 3],
       [0, 1],
       [0, 4],
       [1, 5],
       [3, 9],
       [3, 2],
       [3, 6],
       [3, 5],
       [3, 3]], dtype=int32)>
    

    【讨论】:

    • 这比目前接受的答案 imo 更好、更简单。
    • 我认为这个解决方案行不通。如答案本身所述,输出包含 [0,1] 的两个副本。 (我刚才自己测试了它,以确认它确实做到了。)
    • 现在可以使用了,谢谢。我在各种大小和重复级别的数组上对非保序版本进行了一些性能测试。看起来我的答案中仅 tensorflow 的代码对于小型和大型数组的运行时间减少了 60%,而这种(也更简单,这很好)numpy 方法的运行时间减少了 30%一些中间数组大小(约 400-1000 个输入元素)。 YMMV 基于硬件,但两种方法似乎都有其用途。
    【解决方案2】:

    一种方法是查找沿轴 0 的先前子Tensor 相等的元素,然后将其过滤掉:

    1. 使用 tf.equal 获得输入的单个轴 -1 元素沿轴 0 与其自身相交的成对相等性。
    2. 使用 tf.math.reduce_all 聚合成对等式,直到输入的轴 0 元素具有二维等式矩阵。
    3. 生成 False 值的上三角矩阵
    4. 使用该三角矩阵将我们的相等比较限制为沿轴 0 的一个方向。
    5. 使用tf.reduce_any 查找哪些轴0 元素等于任何后面的元素;它们是将被删除的重复项。
    6. 使用tf.math.logical_nottf.boolean_mask 仅获取轴0 的非重复元素。

    此过程在以下 Python 代码中实现,并在 TensorFlow 2.0 beta 中进行了测试:

    def distinct(input:tf.Tensor) -> tf.Tensor:
        """Returns only the distinct sub-Tensors along the 0th dimension of the provided Tensor"""
        is_equal = tf.equal(input[:,tf.newaxis], input[tf.newaxis,:])
        while len(is_equal.shape) > 2:
            is_equal = tf.math.reduce_all(is_equal, axis=2)
        all_true = tf.constant(True, shape=is_equal.shape)
        true_upper_tri = tf.linalg.band_part(all_true, 0, -1)
        false_upper_tri = tf.math.logical_not(true_upper_tri)
        is_equal_one_way = tf.math.logical_and(is_equal, false_upper_tri)
        is_duplicate = tf.reduce_any(is_equal_one_way, axis=1)
        is_distinct = tf.math.logical_not(is_duplicate)
        distinct_elements = tf.boolean_mask(input, is_distinct, 0)
        return distinct_elements
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-03
      • 1970-01-01
      • 2018-08-23
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      相关资源
      最近更新 更多