核心要点
torch.from_numpy(arr) 与原数组共享内存、零拷贝,适合读大批数据,但改一方会影响另一方
torch.tensor(arr) 拷贝一份独立数据,可顺带指定 dtype、device、requires_grad
注意 dtype:NumPy 默认 float64,直接转来需显式转 float32 才适合训练
反向转回用 .numpy();GPU 或带梯度的张量要先 .detach().cpu() 再 .numpy()
标准回答
NumPy 与 PyTorch 互操作常见方式:
1. torch.from_numpy(ndarray)(推荐读数据)
- 与原数组共享内存,修改一方影响另一方;
- 保留 NumPy 的 dtype(float64 仍是 float64),且不会自动 requires_grad。
import numpy as np
arr = np.array([1.0, 2.0, 3.0])
t = torch.from_numpy(arr) # 共享内存2. torch.tensor(data)
- 拷贝数据、独立存储;
- 可显式指定 dtype、device、requires_grad,最稳妥。
3. torch.as_tensor(data)
- 类似 from_numpy,能零拷贝时零拷贝,否则拷贝。
转回 NumPy
t.detach().cpu().numpy() # 断开梯度、搬回 CPU 再转注意:GPU 张量不能直接 .numpy(),需先 .cpu();带梯度张量需 detach() 断图;float64 转来的张量训练前一般要 .float()。DataLoader 常直接产出 Tensor,避免反复转换。详见 深度学习基础。
常见误区
⚠️ 常见踩坑
GPU tensor 直接 .numpy();需要梯度时对 tensor.numpy() 未 detach;共享内存意外修改数据。
追问
追问 1:from_numpy 后改 NumPy 影响训练吗?
会。from_numpy 共享内存,若 DataLoader/预处理在原 ndarray 上原地修改,已转出的张量内容也会跟着变,可能引入难查的数据 bug;多进程 num_workers 下还可能有数据竞争。要彻底隔离就用 torch.tensor(arr)(拷贝),或转完后立即 .clone()。
追问 2:float64 NumPy 转 tensor 训练有问题吗?
有。NumPy 默认 float64,而模型权重一般是 float32,二者参与运算会 dtype 不匹配报错,或被迫升到 float64 导致显存翻倍、GPU 吞吐骤降。正确做法是转换时显式 .float()(或 torch.tensor(arr, dtype=torch.float32))。
追问 3:PIL 图像如何进 PyTorch?
题库专题:PyTorch 中反向传播的过程是怎样的?最常用 torchvision.transforms.ToTensor(),它把 PIL.Image(HWC、0~255 的 uint8)转成 CHW、归一化到 [0,1] 的 float32 张量,常配合 Compose 接 Normalize、Resize 等。手动做则需 np.array(img) 再 torch.from_numpy 并 permute(2,0,1)、/255。新版也可用 transforms.PILToTensor()(保留 uint8、不缩放)。
题库延伸:与本追问相关的专题题 → PyTorch 中反向传播的过程是怎样的?
延伸学习
与本题相关的知识库文章、术语、工具与行业资讯。
📰 AI 资讯
🛠️ AI 工具
- Pytorch
Meta 开源的深度学习框架,100K+ stars。以动态计算图和 Pythonic 风格著称,在学术界和工业界都有广泛应用,支持分布式训练、移动端部署和 ONNX 导出
- Tensorflow
全球最流行的机器学习框架之一,195K+ stars。Google 开源的端到端 ML 平台,支持 TensorFlow、Keras 等多种 API,覆盖深度学习、强化学习、移动端部署等全场景,是 AI 工程师的必备工具