Tensores y operaciones con tensores de TensorFlow

Avanzado
Actualizado: 09/01/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

¿Qué son los tensores en TensorFlow?

Los tensores son las estructuras de datos fundamentales en TensorFlow, representando arreglos multidimensionales utilizados para almacenar y manipular datos. Cada tensor se caracteriza por su forma, que define el número de dimensiones y el tamaño en cada una de ellas, así como por su tipo de dato, como tf.float32 o tf.int64. Por ejemplo, un tensor escalar tiene una forma vacía (), un vector tiene una forma como (3,) y una matriz puede tener una forma (3, 2).

¿Te está gustando esta lección?

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

En TensorFlow, los tensores permiten realizar operaciones matemáticas y transformaciones de manera eficiente dentro del grafo computacional. Esta abstracción facilita la ejecución de operaciones en paralelo y el aprovechamiento de hardware especializado, como las unidades de procesamiento gráfico (GPU) y los tensor cores. Además, los tensores son inmutables, lo que garantiza la consistencia y la integridad de los datos a lo largo de las distintas etapas del procesamiento.

Para crear tensores en TensorFlow, se utilizan funciones como tf.constant, que define un tensor con valores fijos, o tf.Variable, que crea un tensor cuyos valores pueden modificarse durante el entrenamiento de un modelo. A continuación se muestra un ejemplo de creación de diferentes tipos de tensores:

import tensorflow as tf

# Tensor constante de rango 0 (escalar)
escalar = tf.constant(3.14)

# Tensor de rango 1 (vector)
vector = tf.constant([1.0, 2.0, 3.0])

# Tensor de rango 2 (matriz)
matriz = tf.constant([[1, 2], [3, 4], [5, 6]])

# Tensor variable
variable = tf.Variable([[1.0, 2.0], [3.0, 4.0]])

Los tensores son esenciales para representar datos en múltiples dimensiones, lo que permite a TensorFlow manejar una amplia variedad de tareas en Deep Learning, como el procesamiento de imágenes, textos y secuencias temporales. Esta capacidad multidimensional es crucial para construir y entrenar modelos complejos que requieren operaciones avanzadas sobre grandes conjuntos de datos.

Además, los tensores facilitan la interoperabilidad con otras librerías y frameworks dentro del ecosistema de TensorFlow, permitiendo una integración fluida con herramientas de visualización, procesamiento de datos y optimización de modelos. Su diseño optimizado garantiza que las operaciones sobre tensores sean rápidas y eficientes, aprovechando al máximo las capacidades del hardware disponible.

Tipos y formas de tensores

En TensorFlow, los tensores pueden clasificarse según su tipo de dato y su forma. Comprender estas características es fundamental para manejar y operar eficientemente con los datos dentro de los modelos de Deep Learning.

Tipos de tensores

Los tensores en TensorFlow soportan una variedad de tipos de datos que determinan la naturaleza de los valores que almacenan. Algunos de los tipos de datos más comunes incluyen:

  • Números enteros:
    • tf.int8, tf.int16, tf.int32, tf.int64
  • Números de punto flotante:
    • tf.float16, tf.float32, tf.float64
  • Números complejos:
    • tf.complex64, tf.complex128
  • Booleanos:
    • tf.bool
  • Cadenas de texto:
    • tf.string

Cada tipo de dato consume una cantidad específica de memoria y ofrece diferentes rangos y precisiones, lo que influye en el rendimiento y la precisión de los modelos.

import tensorflow as tf

# Tensor de enteros de 32 bits
tensor_int32 = tf.constant([1, 2, 3], dtype=tf.int32)

# Tensor de punto flotante de 64 bits
tensor_float64 = tf.constant([1.0, 2.0, 3.0], dtype=tf.float64)

# Tensor booleano
tensor_bool = tf.constant([True, False, True], dtype=tf.bool)

# Tensor de cadenas de texto
tensor_string = tf.constant(["a", "b", "c"], dtype=tf.string)

Formas de tensores

La forma de un tensor define su estructura multidimensional, especificando el número de dimensiones y el tamaño en cada una de ellas. La forma se representa como una tupla de enteros, donde cada entero corresponde al tamaño en una dimensión específica.

Rangos de tensores

  • Escalar: Un tensor de rango 0, que representa un único valor. Forma: ()
  • Vector: Un tensor de rango 1, que representa una secuencia de valores. Forma: (n,)
  • Matriz: Un tensor de rango 2, que representa una tabla de valores. Forma: (m, n)
  • Tensor de rango superior: Tensores con más de dos dimensiones, utilizados para representar datos más complejos como imágenes (rangos 3 o 4).

Ejemplos de formas

# Tensor escalar
escalar = tf.constant(7)
print(escalar.shape)  # Output: ()

# Tensor vectorial
vector = tf.constant([1, 2, 3, 4])
print(vector.shape)  # Output: (4,)

# Tensor matricial
matriz = tf.constant([[1, 2], [3, 4], [5, 6]])
print(matriz.shape)  # Output: (3, 2)

# Tensor de rango 3
tensor_3d = tf.constant([[[1], [2]], [[3], [4]]])
print(tensor_3d.shape)  # Output: (2, 2, 1)

Operaciones relacionadas con la forma

TensorFlow proporciona varias operaciones para inspeccionar y modificar la forma de los tensores, permitiendo una manipulación flexible de los datos.

  • Obtener la forma de un tensor:
forma = tensor_float64.shape
print(forma)  # Output: (3,)
  • Cambiar la forma de un tensor:
reshaped_tensor = tf.reshape(matriz, (2, 3))
print(reshaped_tensor)
# Output:
# tf.Tensor(
# [[1 2 3]
#  [4 5 6]], shape=(2, 3), dtype=int32)
  • Añadir una dimensión:
expanded_tensor = tf.expand_dims(vector, axis=0)
print(expanded_tensor.shape)  # Output: (1, 4)
  • Eliminar una dimensión:
squeezed_tensor = tf.squeeze(tensor_3d)
print(squeezed_tensor.shape)  # Output: (2, 2)

Comprender los tipos y las formas de los tensores es esencial para diseñar modelos eficientes y garantizar que las operaciones matemáticas se realicen correctamente. Manipular adecuadamente estos atributos facilita el procesamiento de datos y la construcción de arquitecturas de redes neuronales complejas.

Operaciones básicas con tensores

Las operaciones básicas con tensores en TensorFlow son fundamentales para manipular y transformar datos dentro de los modelos de Deep Learning. Estas operaciones permiten realizar cálculos matemáticos, transformar la estructura de los datos y preparar los tensores para su uso en capas y funciones de activación. A continuación, se describen algunas de las operaciones más comunes y su implementación en TensorFlow utilizando Python.

Aritmética elemental

TensorFlow proporciona una amplia gama de operaciones aritméticas para realizar cálculos element-wise (elemento por elemento) entre tensores. Estas operaciones incluyen suma, resta, multiplicación y división, y son esenciales para la mayoría de los cálculos en redes neuronales.

import tensorflow as tf

# Definición de tensores
a = tf.constant([1, 2, 3], dtype=tf.float32)
b = tf.constant([4, 5, 6], dtype=tf.float32)

# Suma
suma = tf.add(a, b)
print('Suma:', suma.numpy())  # Output: [5. 7. 9.]

# Resta
resta = tf.subtract(a, b)
print('Resta:', resta.numpy())  # Output: [-3. -3. -3.]

# Multiplicación
multiplicacion = tf.multiply(a, b)
print('Multiplicación:', multiplicacion.numpy())  # Output: [ 4. 10. 18.]

# División
division = tf.divide(a, b)
print('División:', division.numpy())  # Output: [0.25       0.4        0.5       ]

Estas operaciones aseguran que los cálculos se realicen de manera eficiente y optimizada, aprovechando las capacidades de paralelización de TensorFlow.

Operaciones de álgebra lineal

Las operaciones de álgebra lineal son cruciales para el procesamiento de datos multidimensionales y la transformación de espacios vectoriales en modelos de aprendizaje profundo. TensorFlow ofrece funciones específicas para realizar estas operaciones de manera eficiente.

  • Producto punto

El producto punto (dot product) es una operación fundamental que calcula el producto escalar de dos vectores.

# Definición de vectores
vector1 = tf.constant([1, 2, 3], dtype=tf.float32)
vector2 = tf.constant([4, 5, 6], dtype=tf.float32)

# Producto punto
dot_product = tf.tensordot(vector1, vector2, axes=1)
print('Producto punto:', dot_product.numpy())  # Output: 32.0
  • Multiplicación de matrices

La multiplicación de matrices es esencial para transformar datos en espacios de mayor o menor dimensionalidad, permitiendo la construcción de capas densas en redes neuronales.

# Definición de matrices
matriz1 = tf.constant([[1, 2], [3, 4]], dtype=tf.float32)
matriz2 = tf.constant([[5, 6], [7, 8]], dtype=tf.float32)

# Multiplicación de matrices
producto = tf.matmul(matriz1, matriz2)
print('Producto de matrices:\n', producto.numpy())
# Output:
# [[19. 22.]
#  [43. 50.]]
  • Transposición

La transposición de una matriz invierte sus dimensiones, lo que es útil en diversas operaciones de álgebra lineal y en la preparación de datos para capas específicas.

# Transposición de una matriz
transpuesta = tf.transpose(matriz1)
print('Matriz transpuesta:\n', transpuesta.numpy())
# Output:
# [[1. 3.]
#  [2. 4.]]

Operaciones de reducción

Las operaciones de reducción agregan los elementos de un tensor a lo largo de un eje específico, produciendo un tensor de menor dimensionalidad. Estas operaciones son útiles para resumir información y aplicar funciones de pérdida en modelos de aprendizaje.

  • Suma

Calcula la suma de los elementos a lo largo de un eje especificado.

# Suma a lo largo de un eje
suma_eje0 = tf.reduce_sum(matriz1, axis=0)
print('Suma a lo largo del eje 0:', suma_eje0.numpy())  # Output: [4. 6.]

suma_eje1 = tf.reduce_sum(matriz1, axis=1)
print('Suma a lo largo del eje 1:', suma_eje1.numpy())  # Output: [3. 7.]
  • Media

Calcula la media de los elementos a lo largo de un eje especificado.

# Media a lo largo de un eje
media_eje0 = tf.reduce_mean(matriz1, axis=0)
print('Media a lo largo del eje 0:', media_eje0.numpy())  # Output: [2. 3.]

media_eje1 = tf.reduce_mean(matriz1, axis=1)
print('Media a lo largo del eje 1:', media_eje1.numpy())  # Output: [1.5 3.5]

Manipulación de formas y concatenación

Modificar la forma de los tensores y combinarlos de diferentes maneras es esencial para preparar los datos antes de pasarlos a las capas del modelo. TensorFlow proporciona funciones para reshaping y concatenación que facilitan este proceso.

  • Redimensionamiento (Reshape)

Cambiar la forma de un tensor sin alterar sus datos.

# Redimensionar un tensor
tensor_original = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32)
tensor_reshaped = tf.reshape(tensor_original, [3, 2])
print('Tensor redimensionado:\n', tensor_reshaped.numpy())
# Output:
# [[1. 2.]
#  [3. 4.]
#  [5. 6.]]
  • Concatenación

Unir múltiples tensores a lo largo de un eje específico.

# Definición de tensores para concatenar
tensor_a = tf.constant([[1, 2], [3, 4]], dtype=tf.float32)                  # Forma: [2, 2]
tensor_b = tf.constant([[5, 6], [7, 8], [9, 10]], dtype=tf.float32)       # Forma: [3, 2]

# Concatenar a lo largo del eje 0
concatenado_eje0 = tf.concat([tensor_a, tensor_b], axis=0)
print('Concatenado eje 0:\n', concatenado_eje0.numpy())
# Output:
# [[ 1.  2.]
#  [ 3.  4.]
#  [ 5.  6.]
#  [ 7.  8.]
#  [ 9. 10.]]

# Concatenar a lo largo del eje 1
tensor_c = tf.constant([[7], [8], [9]], dtype=tf.float32)
concatenado_eje1 = tf.concat([tensor_b, tensor_c], axis=1)
print('Concatenado eje 1:\n', concatenado_eje1.numpy())
# Output:
# [[ 5.  6.  7.]
#  [ 7.  8.  8.]
#  [ 9. 10.  9.]]
  • Indexación y segmentación

Acceder a subconjuntos específicos de los datos dentro de un tensor es una operación común que permite focalizar el procesamiento en partes relevantes de los datos.

# Definición de un tensor de 3 dimensiones
tensor_3d = tf.constant([
    [[1, 2], [3, 4]],
    [[5, 6], [7, 8]],
    [[9, 10], [11, 12]]
], dtype=tf.float32)

# Acceder a un elemento específico
elemento = tensor_3d[1, 0, 1]
print('Elemento en (1, 0, 1):', elemento.numpy())  # Output: 6.0

# Extraer una submatriz
subtensor = tensor_3d[:, 1, :]
print('Subtensor:\n', subtensor.numpy())
# Output:
# [[ 3.  4.]
#  [ 7.  8.]
#  [11. 12.]]
  • Broadcasting

El broadcasting permite realizar operaciones entre tensores de diferentes formas sin necesidad de replicar datos, aprovechando la capacidad de TensorFlow para alinear las dimensiones de forma compatible.

# Definición de tensores con shapes diferentes
tensor1 = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32)  # Shape: (2, 3)
tensor2 = tf.constant([10, 20, 30], dtype=tf.float32)           # Shape: (3,)

# Operación con broadcasting
resultado = tensor1 + tensor2
print('Resultado del broadcasting:\n', resultado.numpy())
# Output:
# [[11. 22. 33.]
#  [14. 25. 36.]]

El broadcasting simplifica las operaciones al permitir la compatibilidad de formas sin necesidad de modificar explícitamente los tensores, optimizando así el rendimiento y la eficiencia del código.

Estas operaciones básicas con tensores son pilares esenciales para el desarrollo de modelos de Deep Learning eficientes y efectivos en TensorFlow. Comprender y dominar estas manipulaciones garantiza una base sólida para avanzar hacia operaciones más complejas y la construcción de arquitecturas de redes neuronales avanzadas.

Manipulación y transformación de tensores

La manipulación y transformación de tensores son operaciones esenciales para preparar y adaptar los datos a las necesidades específicas de los modelos de Deep Learning en TensorFlow. Estas operaciones permiten modificar la estructura, el tipo y la disposición de los datos, facilitando así el flujo de información a través de las distintas capas de una red neuronal. A continuación, se describen algunas de las técnicas más utilizadas para manipular y transformar tensores, acompañadas de ejemplos prácticos en Python.

  • Cambio de tipo de datos (Casting)

El casting consiste en transformar un tensor de un tipo de dato a otro, lo cual es fundamental para garantizar la compatibilidad entre diferentes operaciones y optimizar el uso de la memoria.

import tensorflow as tf

# Tensor original de tipo float32
tensor_float = tf.constant([1.5, 2.5, 3.5], dtype=tf.float32)
print('Tipo original:', tensor_float.dtype)  # Output: <dtype: 'float32'>

# Convertir a int32
tensor_int = tf.cast(tensor_float, tf.int32)
print('Tensor convertido:', tensor_int.numpy())  # Output: [1 2 3]
print('Nuevo tipo:', tensor_int.dtype)  # Output: <dtype: 'int32'>
  • Reordenación de ejes (Permutación)

La transposición o permutación de ejes permite reorganizar las dimensiones de un tensor, lo cual es especialmente útil en operaciones con datos de múltiples dimensiones, como imágenes o secuencias temporales.

# Tensor de rango 3 (por ejemplo, una imagen con canales)
tensor_3d = tf.constant([
    [[1, 2], [3, 4]],
    [[5, 6], [7, 8]]
], dtype=tf.float32)
print('Forma original:', tensor_3d.shape)  # Output: (2, 2, 2)

# Transponer los ejes
tensor_transpuesto = tf.transpose(tensor_3d, perm=[2, 0, 1])
print('Tensor transpuesto:\n', tensor_transpuesto.numpy())
# Output:
# [[[1. 3.]
#   [5. 7.]]
#  [[2. 4.]
#   [6. 8.]]]
print('Nueva forma:', tensor_transpuesto.shape)  # Output: (2, 2, 2)
  • Duplicación de datos (Tile)

La función tile replica un tensor a lo largo de sus dimensiones, permitiendo expandirlo sin alterar sus valores originales.

# Tensor original
tensor = tf.constant([1, 2, 3])
print('Tensor original:', tensor.numpy())  # Output: [1 2 3]

# Duplicar el tensor 3 veces
tensor_dup = tf.tile(tensor, multiples=[3])
print('Tensor duplicado:', tensor_dup.numpy())  # Output: [1 2 3 1 2 3 1 2 3]
  • Selección avanzada y extracción (Gather)

La operación gather permite extraer elementos específicos de un tensor según índices proporcionados, facilitando la selección dinámica de datos.

# Tensor de ejemplo
tensor = tf.constant([[10, 20], [30, 40], [50, 60]])
print('Tensor original:\n', tensor.numpy())
# Output:
# [[10 20]
#  [30 40]
#  [50 60]]

# Índices a extraer
indices = [0, 2]

# Aplicar gather en la primera dimensión
gathered = tf.gather(tensor, indices, axis=0)
print('Tensor seleccionado:\n', gathered.numpy())
# Output:
# [[10 20]
#  [50 60]]
  • Apilamiento y desapilamiento (Stack y Unstack)

Las operaciones stack y unstack permiten combinar múltiples tensores en uno solo o dividir un tensor en múltiples tensores a lo largo de una dimensión específica.

# Tensores para apilar
tensor_a = tf.constant([1, 2, 3])
tensor_b = tf.constant([4, 5, 6])
tensor_c = tf.constant([7, 8, 9])

# Apilar en una nueva dimensión
apilados = tf.stack([tensor_a, tensor_b, tensor_c], axis=0)
print('Tensores apilados:\n', apilados.numpy())
# Output:
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
print('Forma apilados:', apilados.shape)  # Output: (3, 3)

# Desapilar a lo largo de la primera dimensión
desapilados = tf.unstack(apilados, axis=0)
for t in desapilados:
    print(t.numpy())
# Output:
# [1 2 3]
# [4 5 6]
# [7 8 9]
  • Padding (Relleno)

La operación de padding añade elementos adicionales alrededor de un tensor, lo cual es útil para mantener dimensiones específicas o para preparar datos para convoluciones en redes neuronales.

# Tensor original
tensor = tf.constant([[1, 2], [3, 4]])
print('Tensor original:\n', tensor.numpy())
# Output:
# [[1 2]
#  [3 4]]

# Aplicar padding
padding = tf.constant([[1, 1], [2, 2]])  # [[antes, después], [antes, después]]
tensor_padded = tf.pad(tensor, paddings=padding, mode='CONSTANT', constant_values=0)
print('Tensor con padding:\n', tensor_padded.numpy())
# Output:
# [[0 0 0 0 0 0]
#  [0 0 1 2 0 0]
#  [0 0 3 4 0 0]
#  [0 0 0 0 0 0]]
  • Fusionar y separar tensores (Merge y Split)

Las operaciones de fusión y separación permiten combinar múltiples tensores en uno solo o dividir un tensor en partes más pequeñas, facilitando la gestión de datos complejos.

# Tensor para dividir
tensor = tf.constant([1, 2, 3, 4, 5, 6])

# Dividir en 3 partes iguales
split_tensors = tf.split(tensor, num_or_size_splits=3)
for t in split_tensors:
    print(t.numpy())
# Output:
# [1 2]
# [3 4]
# [5 6]

# Tensor para fusionar
tensor_a = tf.constant([1, 2])
tensor_b = tf.constant([3, 4])
tensor_c = tf.constant([5, 6])

# Fusionar usando concatenación
fusionado = tf.concat([tensor_a, tensor_b, tensor_c], axis=0)
print('Tensores fusionados:', fusionado.numpy())  # Output: [1 2 3 4 5 6]
  • Manipulación avanzada con tf.function

Para mejorar el rendimiento de las operaciones de manipulación y transformación, TensorFlow permite utilizar tf.function para compilar funciones en gráficos computacionales optimizados.

@tf.function
def manipular_tensor(tensor):
    tensor = tf.cast(tensor, tf.float32)
    tensor = tf.expand_dims(tensor, axis=0)
    tensor = tf.transpose(tensor, perm=[0, 2, 1])
    return tensor

# Aplicar la función optimizada
tensor_original = tf.constant([[1, 2, 3], [4, 5, 6]])
tensor_manipulado = manipular_tensor(tensor_original)
print('Tensor manipulado:\n', tensor_manipulado.numpy())
# Output:
# [[[1. 4.]
#   [2. 5.]
#   [3. 6.]]]

La utilización de estas técnicas de manipulación y transformación de tensores permite una gestión eficiente y flexible de los datos dentro de TensorFlow, facilitando la construcción de modelos más complejos y adaptados a diferentes tipos de tareas en Deep Learning.

Aprendizajes de esta lección

  • Entender la definición de tensores, sus rangos y formas en TensorFlow.
  • Identificar y manejar los tipos de datos soportados por tensores, como enteros, flotantes y cadenas.
  • Realizar operaciones aritméticas, de álgebra lineal y de reducción con tensores.
  • Manipular y transformar tensores mediante técnicas como reshape, concatenación y broadcasting.
  • Aplicar operaciones avanzadas para gestionar eficientemente datos multidimensionales en redes neuronales.

Completa y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración