¿Se puede usar solo PyTorch sin NumPy?
Si eres desarrollador de deep learning, seguramente te has preguntado alguna vez sobre esta relación.
Al mirar los códigos de fine‑tuning, siempre aparecen dos nombres:
import numpy as np
import torch
“¿No basta con PyTorch para las operaciones con tensores? ¿Por qué necesito NumPy?” “¿Los conceptos se superponen? ¿Debo estudiar NumPy por separado?”
Yo también tenía curiosidad y, basándome en una respuesta clara, he organizado la información.
1. ¿Qué diferencia a NumPy y PyTorch?
En términos muy generales, PyTorch es:
“NumPy en la GPU + autograd”
Dividamos los roles:
- NumPy
- Biblioteca de matrices/arrays que corre en la CPU.
- Calcula numéricamente, álgebra lineal y estadísticas: el “estándar de Python”.
-
Se centra en la estructura de datos
ndarray. -
PyTorch
- API casi idéntica a NumPy.
- Se ejecuta en CPU y GPU (CUDA).
- Soporta autograd para que sea posible entrenar modelos de deep learning.
Los desarrolladores de PyTorch adoptaron deliberadamente la sintaxis de NumPy:
np.array([...])→torch.tensor([...])x_np.shape→x_torch.shapenp.reshape(x, …)→x_torch.view(…)ox_torch.reshape(…)
Al aprender operaciones con tensores de PyTorch, también se aprende la forma de pensar y la sintaxis de NumPy.
2. ¿Debo estudiar NumPy primero? Respuesta práctica
Muchos tutoriales empiezan con NumPy y eso puede confundir, pero desde la práctica la respuesta es:
No es necesario estudiar NumPy antes. PyTorch ya cubre las operaciones con tensores.
Razones:
- Conceptos como forma, broadcasting e indexación son prácticamente idénticos en NumPy y PyTorch.
- En deep learning lo que realmente usamos es la combinación de operaciones con tensores y autograd, que solo está en PyTorch.
Por lo tanto, si tu objetivo es deep learning:
- Aprende primero las operaciones con tensores de PyTorch.
- Cuando veas
np.xxxen el código, simplemente entiende que es la versión de CPU de la misma operación.
3. ¿Por qué sigue apareciendo NumPy? “Lenguaje común del ecosistema”
Entonces surge la pregunta:
“Si PyTorch es más potente, ¿por qué no usar solo tensores?”
La respuesta es que la mayoría del ecosistema de datos y ciencia en Python está centrado en NumPy.
3‑1. Pre‑procesamiento: el mundo de NumPy
Al preparar datos, se usan librerías como:
OpenCV,Pillow→ devuelven arrays NumPy.pandas→DataFrame.values/to_numpy().- Paquetes estadísticos y numéricos → entrada/salida en NumPy.
En otras palabras, la manipulación de datos antes de entrar al modelo suele hacerse con NumPy.
3‑2. Entrenamiento/Inferencia: el mundo de PyTorch
Para pasar los datos al modelo:
import numpy as np
import torch
x_np = ... # array NumPy
x_tensor = torch.from_numpy(x_np) # convertir a tensor
x_tensor = x_tensor.to("cuda")
out = model(x_tensor)
Desde aquí, todo es PyTorch.
3‑3. Visualización/Almacenamiento/Pos‑procesamiento: vuelve a NumPy
Para graficar con matplotlib, guardar en pandas o hacer estadísticas simples, las librerías esperan arrays NumPy.
out_cpu = out.detach().cpu().numpy()
Un error común es:
TypeError: can't convert cuda:0 device type tensor to numpy
Para convertir un tensor en GPU a NumPy, primero hay que moverlo a CPU.
4. Punto importante desde la perspectiva del sistema: “Zero‑Copy”
Un detalle interesante a nivel bajo es que la conversión no implica copia de datos:
x_np = np.random.randn(3, 3)
x_tensor = torch.from_numpy(x_np) # ¡sin copia!
torch.from_numpy(...) comparte la misma memoria que el array NumPy. Lo mismo ocurre en sentido inverso:
x_np2 = x_tensor.numpy()
Esto permite que la manipulación de datos entre NumPy y PyTorch sea muy eficiente.
Ejemplo:
x_np = np.zeros((2, 2))
x_tensor = torch.from_numpy(x_np)
x_tensor[0, 0] = 1
print(x_np)
# [[1. 0.]
# [0. 0.]] ← el array NumPy también cambia
En resumen:
- PyTorch y NumPy pueden compartir memoria en la CPU.
- Esto facilita el flujo pre‑procesamiento (NumPy) → entrenamiento (PyTorch) → pos‑procesamiento (NumPy) sin costos de copia significativos.
5. Ejemplo completo de flujo
Supongamos un caso muy simple de clasificación de imágenes:
import cv2
import numpy as np
import torch
# 1. Cargar imagen y pre‑procesar con NumPy
img = cv2.imread("cat.png") # (H, W, C), BGR, array NumPy
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (224, 224))
img = img.astype(np.float32) / 255.0
img = np.transpose(img, (2, 0, 1)) # (C, H, W)
# 2. Convertir a tensor y mover a GPU
x = torch.from_numpy(img) # (3, 224, 224)
x = x.unsqueeze(0) # (1, 3, 224, 224)
x = x.to("cuda")
# 3. Inferencia
with torch.no_grad():
logits = model(x)
probs = torch.softmax(logits, dim=1)
# 4. Convertir de vuelta a NumPy para post‑procesar
probs_np = probs.cpu().numpy()
pred_class = np.argmax(probs_np, axis=1)[0]
El flujo muestra claramente:
- Entrada/Salida: NumPy.
- Entrenamiento/Inferencia: PyTorch.
6. Resumen final: cómo entenderlo
- Estudiar PyTorch es aprender un “NumPy futuro”: las operaciones con tensores y broadcasting son prácticamente las mismas.
- No necesitas profundizar en NumPy si tu objetivo es deep learning; entiende
np.xxxcomo la versión de CPU de la operación. - En la práctica, pre‑procesamiento, visualización y estadísticas siguen usando NumPy, por lo que no se puede evitar por completo.
- La conversión entre NumPy y PyTorch es zero‑copy en la CPU, lo que hace que el flujo sea eficiente.
Al mirar un código de deep learning, piensa así:
- Si la operación necesita GPU y autograd → PyTorch.
- Si la operación es de manipulación de datos o visualización → NumPy.
Moverse entre estos dos mundos es la habilidad básica de cualquier desarrollador de deep learning en Python.

No hay comentarios.