Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Introducción a los tensores

Ver en TensorFlow.org Ejecutar en Google Colab Ver fuente en GitHub Descargar cuaderno
import tensorflow as tf
import numpy as np

Los tensores son matrices multidimensionales con un tipo uniforme (llamado dtype ). Puede ver todos los dtypes admitidos en tf.dtypes.DType .

Si está familiarizado con NumPy , los tensores son (algo así como) como np.arrays .

Todos los tensores son inmutables como los números y las cadenas de Python: nunca se puede actualizar el contenido de un tensor, solo crear uno nuevo.

Lo esencial

Creemos algunos tensores básicos.

Aquí hay un tensor "escalar" o "rango 0". Un escalar contiene un valor único y no "ejes".

# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)

Un tensor de "vector" o de "rango 1" es como una lista de valores. Un vector tiene 1 eje:

# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)

Un tensor de "matriz" o "rango 2" tiene 2 ejes:

# If we want to be specific, we can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
                             [3, 4],
                             [5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor(
[[1. 2.]
 [3. 4.]
 [5. 6.]], shape=(3, 2), dtype=float16)

Un escalar, forma: [] Un vector, forma: [3] Una matriz, forma: [3, 2]
Un escalar, el número 4La línea con 3 secciones, cada una con un número.Una cuadrícula de 3x2, con cada celda que contiene un número.

Los tensores pueden tener más ejes, aquí hay un tensor con 3 ejes:

# There can be an arbitrary number of
# axes (sometimes called "dimensions")
rank_3_tensor = tf.constant([
  [[0, 1, 2, 3, 4],
   [5, 6, 7, 8, 9]],
  [[10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19]],
  [[20, 21, 22, 23, 24],
   [25, 26, 27, 28, 29]],])

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Hay muchas formas de visualizar un tensor con más de 2 ejes.

Un tensor de 3 ejes, forma: [3, 2, 5]

Puede convertir un tensor en una matriz NumPy usando np.array o el método tensor.numpy :

np.array(rank_2_tensor)
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)
rank_2_tensor.numpy()
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)

Los tensores suelen contener flotadores e ints, pero tienen muchos otros tipos, que incluyen:

  • números complejos
  • instrumentos de cuerda

La clase base tf.Tensor requiere que los tensores sean "rectangulares", es decir, a lo largo de cada eje, todos los elementos tienen el mismo tamaño. Sin embargo, existen tipos especializados de tensores que pueden manejar diferentes formas:

Podemos hacer matemáticas básicas con tensores, incluida la suma, la multiplicación por elementos y la multiplicación de matrices.

a = tf.constant([[1, 2],
                 [3, 4]])
b = tf.constant([[1, 1],
                 [1, 1]]) # Could have also said `tf.ones([2,2])`

print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32) 


print(a + b, "\n") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32) 


Los tensores se utilizan en todo tipo de operaciones (ops).

c = tf.constant([[4.0, 5.0], [10.0, 1.0]])

# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32)
tf.Tensor([1 0], shape=(2,), dtype=int64)
tf.Tensor(
[[2.6894143e-01 7.3105860e-01]
 [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)

Acerca de las formas

Los tensores tienen formas. Algo de vocabulario:

  • Forma : La longitud (número de elementos) de cada una de las dimensiones de un tensor.
  • Rango : Número de dimensiones del tensor. Un escalar tiene rango 0, un vector tiene rango 1, una matriz tiene rango 2.
  • Eje o dimensión : dimensión particular de un tensor.
  • Tamaño : el número total de elementos en el tensor, el vector de forma del producto

Los objetos Tensors y tf.TensorShape tienen propiedades convenientes para acceder a estos:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
Un tensor de rango 4, forma: [3, 2, 4, 5]
La forma de un tensor es como un vector.Un tensor de 4 ejes
print("Type of every element:", rank_4_tensor.dtype)
print("Number of dimensions:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements along axis 0 of tensor:", rank_4_tensor.shape[0])
print("Elements along the last axis of tensor:", rank_4_tensor.shape[-1])
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy())
Type of every element: <dtype: 'float32'>
Number of dimensions: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*4*5):  120

Si bien a menudo se hace referencia a los ejes por sus índices, siempre debe realizar un seguimiento del significado de cada uno. A menudo, los ejes se ordenan de global a local: el eje del lote primero, seguido de las dimensiones espaciales y las características de cada ubicación al final. De esta manera, los vectores de características son regiones contiguas de memoria.

Orden de eje típico
Mantenga un registro de lo que es cada eje. Un tensor de 4 ejes podría ser: Lote, Ancho, Alto, Fracturas

Indexación

Indexación de un solo eje

TensorFlow sigue las reglas de indexación estándar de Python, similares a indexar una lista o una cadena en Python , y las reglas básicas para la indexación de NumPy.

  • los índices comienzan en 0
  • los índices negativos cuentan hacia atrás desde el final
  • los dos puntos, : , se utilizan para los cortes: start:stop:step
rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print(rank_1_tensor.numpy())
[ 0  1  1  2  3  5  8 13 21 34]

La indexación con un escalar elimina la dimensión:

print("First:", rank_1_tensor[0].numpy())
print("Second:", rank_1_tensor[1].numpy())
print("Last:", rank_1_tensor[-1].numpy())
First: 0
Second: 1
Last: 34

La indexación con un : segmento mantiene la dimensión:

print("Everything:", rank_1_tensor[:].numpy())
print("Before 4:", rank_1_tensor[:4].numpy())
print("From 4 to the end:", rank_1_tensor[4:].numpy())
print("From 2, before 7:", rank_1_tensor[2:7].numpy())
print("Every other item:", rank_1_tensor[::2].numpy())
print("Reversed:", rank_1_tensor[::-1].numpy())
Everything: [ 0  1  1  2  3  5  8 13 21 34]
Before 4: [0 1 1 2]
From 4 to the end: [ 3  5  8 13 21 34]
From 2, before 7: [1 2 3 5 8]
Every other item: [ 0  1  3  8 21]
Reversed: [34 21 13  8  5  3  2  1  1  0]

Indexación multieje

Los tensores de rango superior se indexan pasando varios índices.

Las reglas de un solo eje exactamente las mismas que en el caso de un solo eje se aplican a cada eje de forma independiente.

print(rank_2_tensor.numpy())
[[1. 2.]
 [3. 4.]
 [5. 6.]]

Pasando un número entero para cada índice, el resultado es un escalar.

# Pull out a single value from a 2-rank tensor
print(rank_2_tensor[1, 1].numpy())
4.0

Puede indexar utilizando cualquier combinación de enteros y sectores:

# Get row and column tensors
print("Second row:", rank_2_tensor[1, :].numpy())
print("Second column:", rank_2_tensor[:, 1].numpy())
print("Last row:", rank_2_tensor[-1, :].numpy())
print("First item in last column:", rank_2_tensor[0, -1].numpy())
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n")
Second row: [3. 4.]
Second column: [2. 4. 6.]
Last row: [5. 6.]
First item in last column: 2.0
Skip the first row:
[[3. 4.]
 [5. 6.]] 


Aquí hay un ejemplo con un tensor de 3 ejes:

print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)

Seleccionar la última característica en todas las ubicaciones en cada ejemplo del lote
Un tensor de 3x2x5 con todos los valores en el índice-4 del último eje seleccionado.Los valores seleccionados empaquetados en un tensor de 2 ejes.

Manipular formas

Reformar un tensor es de gran utilidad.

# Shape returns a `TensorShape` object that shows the size on each dimension
var_x = tf.Variable(tf.constant([[1], [2], [3]]))
print(var_x.shape)
(3, 1)

# You can convert this object into a Python list, too
print(var_x.shape.as_list())
[3, 1]

Puede remodelar un tensor en una nueva forma. La operación tf.reshape es rápida y económica, ya que no es necesario duplicar los datos subyacentes.

# We can reshape a tensor to a new shape.
# Note that we're passing in a list
reshaped = tf.reshape(var_x, [1, 3])
print(var_x.shape)
print(reshaped.shape)
(3, 1)
(1, 3)

Los datos mantienen su disposición en memoria y se crea un nuevo tensor, con la forma solicitada, apuntando a los mismos datos. TensorFlow usa el orden de memoria "fila principal" de estilo C, donde incrementar el índice de la derecha corresponde a un solo paso en la memoria.

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Si aplana un tensor, puede ver en qué orden se coloca en la memoria.

# A `-1` passed in the `shape` argument says "Whatever fits".
print(tf.reshape(rank_3_tensor, [-1]))
tf.Tensor(
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29], shape=(30,), dtype=int32)

Normalmente, los únicos usos razonables de tf.reshape son combinar o dividir ejes adyacentes (o agregar / eliminar 1 s).

Para este tensor 3x2x5, remodelar a (3x2) x5 o 3x (2x5) son dos cosas razonables, ya que los cortes no se mezclan:

print(tf.reshape(rank_3_tensor, [3*2, 5]), "\n")
print(tf.reshape(rank_3_tensor, [3, -1]))
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]
 [25 26 27 28 29]], shape=(6, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]], shape=(3, 10), dtype=int32)

Algunas buenas remodelaciones.
Un tensor de 3x2x5Los mismos datos reformados a (3x2) x5Los mismos datos reformados a 3x (2x5)

La remodelación "funcionará" para cualquier forma nueva con el mismo número total de elementos, pero no servirá de nada si no respeta el orden de los ejes.

El intercambio de ejes en tf.reshape no funciona, necesita tf.transpose para eso.

# Bad examples: don't do this

# You can't reorder axes with reshape.
print(tf.reshape(rank_3_tensor, [2, 3, 5]), "\n") 

# This is a mess
print(tf.reshape(rank_3_tensor, [5, 6]), "\n")

# This doesn't work at all
try:
  tf.reshape(rank_3_tensor, [7, -1])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]]

 [[15 16 17 18 19]
  [20 21 22 23 24]
  [25 26 27 28 29]]], shape=(2, 3, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]
 [24 25 26 27 28 29]], shape=(5, 6), dtype=int32) 

InvalidArgumentError: Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]

Algunas remodelaciones malas.
No puede reordenar los ejes, use tf.transpose para esoCualquier cosa que mezcle las porciones de datos probablemente sea incorrecta.La nueva forma debe encajar exactamente.

Puede encontrarse con formas no completamente especificadas. O la forma contiene None (se desconoce la longitud de una dimensión) o la forma es None (se desconoce el rango del tensor).

A excepción de tf.RaggedTensor , tales formas solo aparecerán en el contexto de las API simbólicas de creación de gráficos de TensorFlow:

Más sobre DTypes

Para inspeccionar el tipo de datos de un tf.Tensor , use la propiedad Tensor.dtype .

Al crear un tf.Tensor partir de un objeto Python, opcionalmente puede especificar el tipo de datos.

Si no lo hace, TensorFlow elige un tipo de datos que puede representar sus datos. TensorFlow convierte los números enteros de Python en tf.int32 y los números de punto flotante de Python en tf.float32 . De lo contrario, TensorFlow usa las mismas reglas que usa NumPy al convertir en matrices.

Puede emitir de un tipo a otro.

the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)
the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)
# Now, cast to an uint8 and lose the decimal precision
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)

Radiodifusión

La transmisión es un concepto tomado de la función equivalente en NumPy . En resumen, bajo ciertas condiciones, los tensores más pequeños se "estiran" automáticamente para adaptarse a tensores más grandes cuando se ejecutan operaciones combinadas en ellos.

El caso más simple y común es cuando intenta multiplicar o agregar un tensor a un escalar. En ese caso, el escalar se transmite para que tenga la misma forma que el otro argumento.

x = tf.constant([1, 2, 3])

y = tf.constant(2)
z = tf.constant([2, 2, 2])
# All of these are the same computation
print(tf.multiply(x, 2))
print(x * y)
print(x * z)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)

Asimismo, las dimensiones de 1 tamaño se pueden estirar para que coincidan con los otros argumentos. Ambos argumentos se pueden estirar en el mismo cálculo.

En este caso, una matriz de 3x1 se multiplica por elementos por una matriz de 1x4 para producir una matriz de 3x4. Observe que el 1 inicial es opcional: la forma de y es [4] .

# These are the same computations
x = tf.reshape(x,[3,1])
y = tf.range(1, 5)
print(x, "\n")
print(y, "\n")
print(tf.multiply(x, y))
tf.Tensor(
[[1]
 [2]
 [3]], shape=(3, 1), dtype=int32) 

tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) 

tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)

Un anuncio emitido: a [3, 1] multiplicado por [1, 4] da un [3,4]
Agregar una matriz de 3x1 a una matriz de 4x1 da como resultado una matriz de 3x4

Aquí está la misma operación sin transmisión:

x_stretch = tf.constant([[1, 1, 1, 1],
                         [2, 2, 2, 2],
                         [3, 3, 3, 3]])

y_stretch = tf.constant([[1, 2, 3, 4],
                         [1, 2, 3, 4],
                         [1, 2, 3, 4]])

print(x_stretch * y_stretch)  # Again, operator overloading
tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)

La mayoría de las veces, la transmisión es eficiente tanto en el tiempo como en el espacio, ya que la operación de transmisión nunca materializa los tensores expandidos en la memoria.

Verá cómo se ve la transmisión usando tf.broadcast_to .

print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))
tf.Tensor(
[[1 2 3]
 [1 2 3]
 [1 2 3]], shape=(3, 3), dtype=int32)

A diferencia de una operación matemática, por ejemplo, broadcast_to no hace nada especial para ahorrar memoria. Aquí estás materializando el tensor.

Puede volverse aún más complicado. Esta sección del libro Python Data Science Handbook de Jake VanderPlas muestra más trucos de transmisión (nuevamente en NumPy).

tf.convert_to_tensor

La mayoría de las operaciones, como tf.matmul y tf.reshape toman argumentos de la clase tf.Tensor . Sin embargo, notará que en el caso anterior, con frecuencia pasamos objetos Python con forma de tensores.

La mayoría, pero no todas, las operaciones llaman a convert_to_tensor en argumentos no tensoriales. Existe un registro de conversiones y la mayoría de las clases de objetos como ndarray , TensorShape , Python de tf.Variable y tf.Variable se convertirán todas automáticamente.

Consulte tf.register_tensor_conversion_function para obtener más detalles, y si tiene su propio tipo, le gustaría convertir automáticamente a un tensor.

Tensores irregulares

Un tensor con números variables de elementos a lo largo de algún eje se llama "irregular". Utilice tf.ragged.RaggedTensor para datos irregulares.

Por ejemplo, esto no se puede representar como un tensor regular:

A tf.RaggedTensor , forma: [4, None]
Un tensor irregular de 2 ejes, cada fila puede tener una longitud diferente.
ragged_list = [
    [0, 1, 2, 3],
    [4, 5],
    [6, 7, 8],
    [9]]
try:
  tensor = tf.constant(ragged_list)
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Can't convert non-rectangular Python sequence to Tensor.

En su lugar, cree un tf.RaggedTensor usando tf.ragged.constant :

ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor)
<tf.RaggedTensor [[0, 1, 2, 3], [4, 5], [6, 7, 8], [9]]>

La forma de un tf.RaggedTensor contiene dimensiones desconocidas:

print(ragged_tensor.shape)
(4, None)

Tensores de cuerda

tf.string es un tipo dtype , lo que quiere decir que podemos representar datos como cadenas (matrices de bytes de longitud variable) en tensores.

Las cadenas son atómicas y no se pueden indexar como las cadenas de Python. La longitud de la cuerda no es una de las dimensiones del tensor. Consulte tf.strings para conocer las funciones para manipularlas.

Aquí hay un tensor de cadena escalar:

# Tensors can be strings, too here is a scalar string.
scalar_string_tensor = tf.constant("Gray wolf")
print(scalar_string_tensor)
tf.Tensor(b'Gray wolf', shape=(), dtype=string)

Y un vector de cuerdas:

Un vector de cadenas, forma: [3,]
La longitud de la cuerda no es uno de los ejes del tensor.
# If we have three string tensors of different lengths, this is OK.
tensor_of_strings = tf.constant(["Gray wolf",
                                 "Quick brown fox",
                                 "Lazy dog"])
# Note that the shape is (3,). The string length is not included.
print(tensor_of_strings)
tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)

En la impresión anterior, el prefijo b indica que tf.string dtype no es una cadena Unicode, sino una cadena de bytes. Consulta el tutorial de Unicode para obtener más información sobre cómo trabajar con texto Unicode en TensorFlow.

Si pasa caracteres Unicode, están codificados en utf-8.

tf.constant("🥳👍")
<tf.Tensor: shape=(), dtype=string, numpy=b'\xf0\x9f\xa5\xb3\xf0\x9f\x91\x8d'>

Algunas funciones básicas con cadenas se pueden encontrar en tf.strings , incluido tf.strings.split .

# We can use split to split a string into a set of tensors
print(tf.strings.split(scalar_string_tensor, sep=" "))
tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)

# ...but it turns into a `RaggedTensor` if we split up a tensor of strings,
# as each string might be split into a different number of parts.
print(tf.strings.split(tensor_of_strings))
<tf.RaggedTensor [[b'Gray', b'wolf'], [b'Quick', b'brown', b'fox'], [b'Lazy', b'dog']]>

Tres cadenas divididas, forma: [3, None]
Dividir varias cadenas devuelve un tf.RaggedTensor

Y tf.string.to_number :

text = tf.constant("1 10 100")
print(tf.strings.to_number(tf.strings.split(text, " ")))
tf.Tensor([  1.  10. 100.], shape=(3,), dtype=float32)

Aunque no puede usar tf.cast para convertir un tensor de cadena en números, puede convertirlo en bytes y luego en números.

byte_strings = tf.strings.bytes_split(tf.constant("Duck"))
byte_ints = tf.io.decode_raw(tf.constant("Duck"), tf.uint8)
print("Byte strings:", byte_strings)
print("Bytes:", byte_ints)
Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)
Bytes: tf.Tensor([ 68 117  99 107], shape=(4,), dtype=uint8)

# Or split it up as unicode and then decode it
unicode_bytes = tf.constant("アヒル 🦆")
unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, "UTF-8")
unicode_values = tf.strings.unicode_decode(unicode_bytes, "UTF-8")

print("\nUnicode bytes:", unicode_bytes)
print("\nUnicode chars:", unicode_char_bytes)
print("\nUnicode values:", unicode_values)

Unicode bytes: tf.Tensor(b'\xe3\x82\xa2\xe3\x83\x92\xe3\x83\xab \xf0\x9f\xa6\x86', shape=(), dtype=string)

Unicode chars: tf.Tensor([b'\xe3\x82\xa2' b'\xe3\x83\x92' b'\xe3\x83\xab' b' ' b'\xf0\x9f\xa6\x86'], shape=(5,), dtype=string)

Unicode values: tf.Tensor([ 12450  12498  12523     32 129414], shape=(5,), dtype=int32)

El tf.string dtf.string se usa para todos los datos de bytes sin procesar en TensorFlow. El módulo tf.io contiene funciones para convertir datos hacia y desde bytes, incluida la decodificación de imágenes y el análisis de csv.

Tensores escasos

A veces, sus datos son escasos, como un espacio de incrustación muy amplio. TensorFlow admite tf.sparse.SparseTensor y operaciones relacionadas para almacenar datos dispersos de manera eficiente.

Un tf.SparseTensor , forma: [3, 4]
Una cuadrícula de 3x4, con valores en solo dos de las celdas.
# Sparse tensors store values by index in a memory-efficient manner
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],
                                       values=[1, 2],
                                       dense_shape=[3, 4])
print(sparse_tensor, "\n")

# We can convert sparse tensors to dense
print(tf.sparse.to_dense(sparse_tensor))
SparseTensor(indices=tf.Tensor(
[[0 0]
 [1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64)) 

tf.Tensor(
[[1 0 0 0]
 [0 0 2 0]
 [0 0 0 0]], shape=(3, 4), dtype=int32)