Разница между "Dataset.from_tensors" и "Dataset.from_tensor_slices"?
У меня есть набор данных, представленный как матрица NumPy формы (num_features, num_examples)
и я хочу преобразовать его в тип tf.Dataset
.
Я изо всех сил пытаюсь понять разницу между этими двумя методами: Dataset.from_tensors
и Dataset.from_tensor_slices
. Какой правильный и почему?
Документация TensorFlow (ссылка) говорит, что оба метода принимают вложенную структуру тензора, хотя при использовании from_tensor_slices
тензор должен иметь одинаковый размер в 0-м измерении.
Ответы
Ответ 1
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]
Ответ 2
1) Основное различие между ними состоит в том, что вложенные элементы в from_tensor_slices
должны иметь одинаковое измерение в 0-м ранге:
# 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])))
2) Второе отличие, поясняемое здесь, заключается в том, что входными данными для tf.Dataset является список. Например:
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)
В приведенном выше from_tensors
создает трехмерный тензор, а from_tensor_slices
объединяет входной тензор. Это может быть удобно, если у вас разные источники разных каналов изображения и вы хотите объединить их в один тензор RGB-изображений.
3) Как упоминалось в предыдущем ответе, 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,)))
Ответ 3
Попробуй это:
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_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)
Выводы в значительной степени говорят сами за себя, но, как вы можете видеть, from_tensor_slices() нарезает выходные данные (что будет выходными данными) from_tensors() в первом измерении. Вы также можете попробовать с:
t1 = tf.constant([[[11, 22], [33, 44], [55, 66]],
[[110, 220], [330, 440], [550, 660]]])