python - pipelines - tensorflow read image dataset
¿Diferencia entre `Dataset.from_tensors` y` Dataset.from_tensor_slices`? (3)
Tengo un conjunto de datos representado como una matriz de forma NumPy (num_features, num_examples)
y deseo convertirlo a TensorFlow tipo tf.Dataset
.
Estoy luchando por entender la diferencia entre estos dos métodos: Dataset.from_tensors
y Dataset.from_tensor_slices
. ¿Cuál es el correcto y por qué?
La documentación de TensorFlow ( link ) dice que ambos métodos aceptan una estructura anidada de tensor, aunque cuando se usa from_tensor_slices
el tensor debe tener el mismo tamaño en la dimensión 0-th.
1) La principal diferencia entre los dos es que los elementos anidados en from_tensor_slices
deben tener la misma dimensión en el rango 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) La segunda diferencia, explicada here , es cuando la entrada a un conjunto de datos tf.Se trata de una lista. Por ejemplo:
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)
En lo anterior, from_tensors
crea un tensor 3D mientras que from_tensor_slices
el tensor de entrada. Esto puede ser útil si tiene diferentes fuentes de canales de imagen diferentes y desea concatenarlas en un tensor de imagen RGB.
3) Como se mencionó en la respuesta anterior, from_tensors
convierten el tensor de entrada en un tensor grande:
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])
salida:
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,)))
Prueba esto :
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)
salida:
========= 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)
La salida es bastante autoexplicativa, pero como puede ver, from_tensor_slices () corta la salida de (lo que sería la salida de) from_tensors () en su primera dimensión. También puedes probar con:
t1 = tf.constant([[[11, 22], [33, 44], [55, 66]],
[[110, 220], [330, 440], [550, 660]]])
from_tensors
combina la entrada y devuelve un conjunto de datos con un solo elemento:
t = tf.constant([[1, 2], [3, 4]])
ds = tf.data.Dataset.from_tensors(t) # [[1, 2], [3, 4]]
from_tensor_slices
crea un conjunto de datos con un elemento separado para cada fila del tensor de entrada:
t = tf.constant([[1, 2], [3, 4]])
ds = tf.data.Dataset.from_tensor_slices(t) # [1, 2], [3, 4]