TensorFlow - return 多维张量的不同子张量
TensorFlow - return distinct sub-tensors of multidimensional tensor
在 TensorFlow 中,tf.unique
函数可用于 return 一维 Tensor
的不同元素。我怎样才能得到不同的子 Tensor
沿着更高维 Tensor
的轴 0?例如,给定以下 Tensor
,所需的 distinct
函数将 return 指定的结果:
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]])
如何为任意维数的 Tensor
生成不同的多维元素?
一种方法是寻找前一个子 Tensor
沿轴 0 相等的元素,然后将其过滤掉:
- 使用
tf.equal
获取输入的各个轴 -1 元素沿轴 0 与自身交叉的成对相等性。
- 使用
tf.math.reduce_all
聚合成对等式,直到您拥有输入的轴 0 元素的二维等式矩阵。
- 生成一个 upper-triangular 假值矩阵
- 使用该三角矩阵将我们的相等性比较限制在沿轴 0 的一个方向上。
- 用
tf.reduce_any
找哪个轴0元素等于后面的任何元素;它们是将被删除的重复项。
- 使用
tf.math.logical_not
和tf.boolean_mask
仅获取轴0的non-duplicate个元素。
此过程在以下 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
不保留顺序
您可以使用 tf.py_function
并调用 np.unique
到 return 个沿 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)>
在 TensorFlow 中,tf.unique
函数可用于 return 一维 Tensor
的不同元素。我怎样才能得到不同的子 Tensor
沿着更高维 Tensor
的轴 0?例如,给定以下 Tensor
,所需的 distinct
函数将 return 指定的结果:
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]])
如何为任意维数的 Tensor
生成不同的多维元素?
一种方法是寻找前一个子 Tensor
沿轴 0 相等的元素,然后将其过滤掉:
- 使用
tf.equal
获取输入的各个轴 -1 元素沿轴 0 与自身交叉的成对相等性。 - 使用
tf.math.reduce_all
聚合成对等式,直到您拥有输入的轴 0 元素的二维等式矩阵。 - 生成一个 upper-triangular 假值矩阵
- 使用该三角矩阵将我们的相等性比较限制在沿轴 0 的一个方向上。
- 用
tf.reduce_any
找哪个轴0元素等于后面的任何元素;它们是将被删除的重复项。 - 使用
tf.math.logical_not
和tf.boolean_mask
仅获取轴0的non-duplicate个元素。
此过程在以下 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
不保留顺序
您可以使用 tf.py_function
并调用 np.unique
到 return 个沿 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)>