1) Main difference between the two is that nested elements in from_tensor_slices
must have the same dimension in 0th rank:
# 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, first dimension is same
dataset2 = tf.data.Dataset.from_tensors(
(tf.random_uniform([10, 4]), tf.random_uniform([10])))
2) The second difference, explained here, is when the input to a tf.Dataset is a list. For example:
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)
In the above, from_tensors
creates a 3D tensor while from_tensor_slices
merge the input tensor. This can be handy if you have different sources of different image channels and want to concatenate them into a one RGB image tensor.
3) A mentioned in the previous answer, from_tensors
convert the input tensor into one big tensor:
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])
output:
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,)))