张量流扩展计入范围

时间:2018-01-30 21:04:14

标签: tensorflow tensor

我们有一个未知长度为N的Tensor,包含一些int32值。 我们如何生成另一个包含连接在一起的N个范围的Tensor,每个范围在0和原始张量的int32值之间?

例如,如果我们有[4, 4, 5, 3, 1],则输出Tensor应该看起来像[0 1 2 3 0 1 2 3 0 1 2 3 4 0 1 2 0]

感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

您可以通过使用tf.RaggedTensor使其包含张量作为输入来工作,该# Or any other N length tensor tf_counts = tf.convert_to_tensor([4, 4, 5, 3, 1]) tf.print(tf_counts) # [4 4 5 3 1] # Create a ragged tensor, each row is a sequence of length tf_counts[i] tf_ragged = tf.ragged.range(tf_counts) tf.print(tf_ragged) # <tf.RaggedTensor [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2], [0]]> # Read values tf.print(tf_ragged.flat_values, summarize=-1) # [0 1 2 3 0 1 2 3 0 1 2 3 4 0 1 2 0] 可以包含长度不均匀的尺寸。

tf_ragged

对于这种二维情况,参差不齐的张量[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2], [0]] 是长度可变的行的“矩阵”:

starts

tf.ragged.range上查看有关如何在每行上创建序列的更多选项:limits包括下限,deltas表示排他上限,dtype表示增量。每个序列可能会有所不同。

还请注意,tf_counts张量的var students = { "name":"John", "semester":30 "name":"Anna", "semester":12 } Wanted output: var students { "name":"John", "semester":30,8 "name":"Anna", "semester":12,4 } 会传播到最终值。

答案 1 :(得分:0)

如果您想将所有内容都作为张量流对象,请使用tf.range()tf.concat()

In [88]: vals = [4, 4, 5, 3, 1]

In [89]: tf_range = [tf.range(0, limit=item, dtype=tf.int32) for item in vals]

# concat all `tf_range` objects into a single tensor
In [90]: concatenated_tensor = tf.concat(tf_range, 0)

In [91]: concatenated_tensor.eval()
Out[91]: array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 0], dtype=int32)

还有其他方法可以做到这一点。在这里,我假设您需要一个constant tensor,但是一旦拥有完整范围列表,就可以构造任何张量。

首先,我们使用 list comprehension 构建完整范围列表,从中创建一个平面列表,然后构造一个张量。

In [78]: from itertools import chain
In [79]: vals = [4, 4, 5, 3, 1]

In [80]: range_list = list(chain(*[range(item) for item in vals]))
In [81]: range_list
Out[81]: [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 0]

In [82]: const_tensor = tf.constant(range_list, dtype=tf.int32)
In [83]: const_tensor.eval()
Out[83]: array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 0], dtype=int32)

另一方面,我们也可以使用tf.range()但是当你eval时它会返回一个数组。因此,您必须从数组中构造列表,然后从中生成一个平面列表,最后构建张量,如下例所示。

list_of_arr = [tf.range(0, limit=item, dtype=tf.int32).eval() for item in vals]
range_list = list(chain(*[arr.tolist() for arr in list_of_arr]))

# output
[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 0]

const_tensor = tf.constant(range_list, dtype=tf.int32)
const_tensor.eval()

#output tensor as numpy array
array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 0], dtype=int32)