我有一个数据集表示为形状为(num_features, num_examples)
的NumPy矩阵,我希望将其转换为TensorFlow类型tf.Dataset
。
我正在努力理解这两种方法之间的区别:Dataset.from_tensors
和Dataset.from_tensor_slices
。什么是正确的,为什么?
TensorFlow文档(link)说两种方法都接受张量的嵌套结构,尽管使用from_tensor_slices
时张量在第0维上应具有相同的大小。
from_tensors
组合输入并返回具有单个元素的数据集:
t = tf.constant([[1, 2], [3, 4]])
ds = tf.data.Dataset.from_tensors(t) # [[1, 2], [3, 4]]
from_tensor_slices
为输入张量的每一行创建一个具有单独元素的数据集:
t = tf.constant([[1, 2], [3, 4]])
ds = tf.data.Dataset.from_tensor_slices(t) # [1, 2], [3, 4]
1)两者之间的主要区别是from_tensor_slices
中的嵌套元素必须在第0位具有相同的维数:
from_tensor_slices
2)第二个区别(解释为# exception: ValueError: Dimensions 10 and 9 are not compatible
dataset1 = tf.data.Dataset.from_tensor_slices(
(tf.random_uniform([10, 4]), tf.random_uniform([9])))
# OK
dataset2 = tf.data.Dataset.from_tensors(
(tf.random_uniform([10, 4]), tf.random_uniform([9])))
)是tf.Dataset的输入是列表时。例如:
here
在上面,dataset1 = tf.data.Dataset.from_tensor_slices(
[tf.random_uniform([2, 3]), tf.random_uniform([2, 3])])
dataset2 = tf.data.Dataset.from_tensors(
[tf.random_uniform([2, 3]), tf.random_uniform([2, 3])])
print(dataset1) # shapes: (2, 3)
print(dataset2) # shapes: (2, 2, 3)
创建3D张量,而from_tensors
合并输入张量。如果您有不同图像通道的不同来源,并希望将它们串联为一个RGB图像张量,则此方法很方便。
3)上一个答案中提到的A,from_tensor_slices
将输入张量转换为一个大张量:
from_tensors
输出:
import tensorflow as tf
tf.enable_eager_execution()
dataset1 = tf.data.Dataset.from_tensor_slices(
(tf.random_uniform([4, 2]), tf.random_uniform([4])))
dataset2 = tf.data.Dataset.from_tensors(
(tf.random_uniform([4, 2]), tf.random_uniform([4])))
for i, item in enumerate(dataset1):
print('element: ' + str(i + 1), item[0], item[1])
print(30*'-')
for i, item in enumerate(dataset2):
print('element: ' + str(i + 1), item[0], item[1])
尝试一下:
element: 1 tf.Tensor(... shapes: ((2,), ()))
element: 2 tf.Tensor(... shapes: ((2,), ()))
element: 3 tf.Tensor(... shapes: ((2,), ()))
element: 4 tf.Tensor(... shapes: ((2,), ()))
-------------------------
element: 1 tf.Tensor(... shapes: ((4, 2), (4,)))
输出:
import tensorflow as tf # 1.13.1
tf.enable_eager_execution()
t1 = tf.constant([[11, 22], [33, 44], [55, 66]])
print("\n========= from_tensors ===========")
ds = tf.data.Dataset.from_tensors(t1)
print(ds.output_types, end=' : ')
print(ds.output_shapes)
for e in ds:
print (e)
print("\n========= from_tensor_slices ===========")
ds = tf.data.Dataset.from_tensor_slices(t1)
print(ds.output_types, end=' : ')
print(ds.output_shapes)
for e in ds:
print (e)
输出几乎是不言而喻的,但正如您所看到的,from_tensor_slices()在其第一维上对from_tensors()的输出(将是其输出)进行切片。您也可以尝试:
========= from_tensors ===========
<dtype: 'int32'> : (3, 2)
tf.Tensor(
[[11 22]
[33 44]
[55 66]], shape=(3, 2), dtype=int32)
========= from_tensor_slices ===========
<dtype: 'int32'> : (2,)
tf.Tensor([11 22], shape=(2,), dtype=int32)
tf.Tensor([33 44], shape=(2,), dtype=int32)
tf.Tensor([55 66], shape=(2,), dtype=int32)