No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Debugging de operaciones con tensores

5/24
Recursos

Aportes 7

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Si alguien esta utilizando una Mac con los chips nuevos de Apple, se puede usar torch.backends.mps.is\_available(), para checar la disponibilidad del GPU
■ Resumen: Para operar entre tensores es clave entender que: * **El tipo de tensor:** PyTorch interpretará las unidades de los tensores basándose en sus tipos de datos (por ejemplo, `torch.float32`, `torch.int64`, etc.). La conversión implícita puede llevar a resultados no deseados o errores. * **Dispositivo del Tensor**: Los tensores deben estar en el mismo dispositivo (`device`) para realizar operaciones entre ellos. Esto significa que todos deben estar en CPU (`cpu`), GPU (`cuda`), o cualquier otro dispositivo como NPU o TPU, dependiendo del entorno de ejecución. PyTorch permite mover tensores entre dispositivos usando métodos como `.to()`, `.cuda()`, o `.cpu()`. * **Forma del Tensor**: La forma (shape) de los tensores debe ser compatible para las operaciones que desea realizar. Por ejemplo, la suma de tensores requiere que sus formas sean iguales o que sean broadcastables, mientras que la multiplicación matricial requiere que las dimensiones sean compatibles de acuerdo a las reglas del álgebra lineal.
El proceso de depuración ("debugging") de operaciones con tensores en PyTorch implica revisar el estado y las transformaciones que sufren los tensores durante el proceso de cálculo. Aquí te ofrezco algunas técnicas y herramientas útiles para depurar operaciones con tensores: \### 1. \*\*Verificar las dimensiones de los tensores (shape)\*\* Un error común al trabajar con tensores es que no coincidan sus dimensiones para las operaciones. Usar `tensor.shape` te permite revisar la forma (dimensión) de los tensores. ```python import torch tensor = torch.rand(3, 4) print(tensor.shape) # Salida: torch.Size(\[3, 4]) ``` Si una operación falla, lo primero que deberías hacer es verificar que las dimensiones sean compatibles. \### 2. \*\*Imprimir el tensor en varios puntos del código\*\* Cuando algo no sale como esperas, puedes imprimir el tensor en diferentes etapas del cálculo para verificar su contenido. ```python tensor = torch.rand(3, 4) print(tensor) # Imprime el contenido del tensor ``` También puedes verificar propiedades como: \- \*\*dtype\*\* (tipo de dato del tensor) \- \*\*device\*\* (si está en CPU o GPU) ```python print(tensor.dtype) # Tipo de dato del tensor (float, int, etc.) print(tensor.device) # Verificar si el tensor está en CPU o GPU ``` \### 3. \*\*Usar `assert` para validar condiciones\*\* Puedes usar `assert` para validar que ciertas propiedades del tensor sean las correctas antes de realizar una operación. ```python tensor = torch.rand(3, 4) assert tensor.shape == (3, 4), "El tensor no tiene la forma correcta" ``` \### 4. \*\*Tener cuidado con la asignación en GPU\*\* Si trabajas con GPU y ocurre un error, asegúrate de que los tensores estén en el mismo dispositivo. No puedes realizar operaciones entre tensores en dispositivos diferentes. ```python if torch.cuda.is\_available(): tensor\_cpu = torch.rand(3, 4) tensor\_gpu = tensor\_cpu.to('cuda') print(tensor\_gpu.device) # Verifica que el tensor esté en la GPU ``` Si intentas operar entre un tensor en CPU y otro en GPU, obtendrás un error, así que asegúrate de moverlos al mismo dispositivo: ```python \# tensor\_cpu + tensor\_gpu -> Esto generará un error tensor\_cpu = tensor\_cpu.to('cuda') # Movemos ambos tensores a la GPU result = tensor\_cpu + tensor\_gpu ``` \### 5. \*\*Comprobar errores numéricos (NaN, Inf)\*\* En ocasiones, los valores de los tensores pueden convertirse en `NaN` o `Inf` debido a cálculos mal condicionados (como divisiones por cero o logaritmos de valores negativos). Puedes verificar si un tensor contiene estos valores: ```python tensor = torch.tensor(\[float('inf'), -float('inf'), float('nan'), 1.0]) \# Comprobar si hay NaNs print(torch.isnan(tensor)) # Salida: tensor(\[False, False, True, False]) \# Comprobar si hay Infs print(torch.isinf(tensor)) # Salida: tensor(\[ True, True, False, False]) ``` \### 6. \*\*Trazado con `autograd` para identificar errores en el cálculo de gradientes\*\* Si estás utilizando autograd y los gradientes no se calculan como esperas, puedes revisar el flujo de cálculo del gradiente mediante `torch.autograd`. ```python x = torch.tensor(\[2.0], requires\_grad=True) y = x\*\*2 y.backward() print(x.grad) # Imprime el gradiente de `x` ``` Si en algún momento pierdes el gradiente o se genera un error en el flujo de cálculo, puedes depurar revisando el historial de operaciones. \### 7. \*\*Uso de `torch.set\_printoptions` para mejorar la visualización\*\* A veces los tensores grandes no se muestran completamente, lo cual puede dificultar la depuración. Puedes ajustar las opciones de impresión para mostrar más detalles del tensor: ```python torch.set\_printoptions(precision=3, edgeitems=2, linewidth=75) tensor = torch.rand(100, 4) print(tensor) ``` \### 8. \*\*Depurar operaciones en GPU\*\* Depurar tensores en GPU puede ser un desafío, ya que los errores son menos descriptivos. Para aislar el problema, puedes copiar el tensor de vuelta a la CPU y revisar su valor: ```python tensor\_gpu = torch.rand(3, 4).to('cuda') tensor\_cpu = tensor\_gpu.cpu() print(tensor\_cpu) # Inspecciona el tensor en CPU ``` \### 9. \*\*Comparación con NumPy\*\* A veces, puedes comparar resultados de operaciones en PyTorch con NumPy para asegurarte de que todo funcione como esperas. ```python import numpy as np tensor = torch.rand(3, 4) array = tensor.numpy() \# Comparar una operación assert np.allclose(tensor.sum().item(), array.sum()), "Los resultados no coinciden" ``` \### 10. \*\*Uso de herramientas de depuración como PDB\*\* Si necesitas una depuración más profunda, puedes usar el depurador interactivo de Python, `pdb`. Por ejemplo, puedes pausar el programa y examinar el estado de las variables en ese punto: ```python import pdb tensor = torch.rand(3, 4) pdb.set\_trace() # Inicia el depurador interactivo aquí ``` Esto te permitirá ejecutar comandos para inspeccionar variables y entender el flujo del programa. Estas técnicas te ayudarán a depurar operaciones con tensores y detectar problemas en tus redes neuronales o cualquier cálculo que estés haciendo en PyTorch.
cuando dice int64 (signed) quiere decir que la representación es **con signo.** No "firmado" como dice el profe. Por ejemplo, en el caso de int8 (signed) quiere decir que puede representar desde -128 hasta 127. Si es int8 (unsigned) va de 0 a 255. Por fuera de eso, muy buena clase y en particular interesante curso!.
Mis apuntes: `import torch` `tensor = torch.tensor([[1, 2], [3, 4], [5, 6]])print('tensor: \n',tensor)print("Shape del tensor:", tensor.shape)  # Output: (3, 2)print("Número de dimensiones:", tensor.dim())  # Output: 2` `#tensor = torch.tensor([[[1, 2], [3, 4], [5, 6]],[[1992,1992],[1993,1992],[1994,1994]]])  -> shape = [2,3,2]` `tensor_float = torch.tensor([[1.0, 2.0], [3.0, 4.0]])tensor_int = torch.tensor([[1, 2], [3, 4]])` `print("Tipo de datos del tensor float:", tensor_float.dtype)  # Output: torch.float32print("Tipo de datos del tensor int:", tensor_int.dtype)  # Output: torch.int64` `#sumamos los dos para ver como hace el broadcasting del tipo -> int a float:tensor_sumado = tensor_float + tensor_intprint('El tensor sumado tiene tipo', tensor_sumado.dtype)` `#Para cambiar manualmente los dtypes:tensor_float = torch.tensor([[1.0, 2.0], [3.0, 4.0]])tensor_int = tensor_float.to(torch.int64)` `print("Tensor original (float):", tensor_float.dtype)  # Output: torch.float32print("Tensor convertido (int):", tensor_int.dtype)  # Output: torch.int64` `#Operaciones dentro de distintos devices:#Verificamos donde esta el tensor:print('Tensor_float esta en el device: ',tensor_float.device)#Reasignamos al GPU:tensor_float = tensor_float.to(torch.device('cuda'))#Verificamos:print('Tensor_float esta en el device: ',tensor_float.device) #-> cuda:0` `#Hagamos una operacion entre distintos devices:tensor_sumado = tensor_float + tensor_int#Da Error: RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!#Debemos tener los tensores en el mismo device si queremos operarlos entre ellos:` `device = torch.device("cuda" if torch.cuda.is_available() else "cpu")` `tensor_int = tensor_int.to(device)` `# Operación entre tensores en el mismo dispositivotensor_sumado = tensor_float + tensor_intprint('Suma exitosa entre tensores del mismo device', tensor_sumado)`
Runtime> Change RunTime type > T4 GPU De esta forma se habilita el CUDA
Hola*# Función para operar con cuda si hay en el hardware*if torch.cuda.is\_available(): matriz\_uinit64\_cuda = matriz\_uinit64.to(torch.device("cuda")) print(matriz\_uinit64\_cuda, matriz\_uinit64\_cuda.type()) print(matriz\_uinit64\_cuda.to("cpu", torch.float32)) para el caso que este realizando en local, sino tengo GPU y tengo solo CPU el codigo no deberia mostrarme nada? ```js # Función para operar con cuda si hay en el hardware if torch.cuda.is_available(): matriz_uinit64_cuda = matriz_uinit64.to(torch.device("cuda")) print(matriz_uinit64_cuda, matriz_uinit64_cuda.type()) print(matriz_uinit64_cuda.to("cpu", torch.float32)) ```