Pytorch 张量到 numpy 数组
Pytorch tensor to numpy array
我有一个 Tensor
形状 [4, 3, 966, 1296]
的火炬。我想使用以下代码将其转换为 numpy
数组:
imgs = imgs.numpy()[:, ::-1, :, :]
该代码如何工作?
您要转换的张量有 4 个维度。
[:, ::-1, :, :]
:
表示第一维原样复制转换,第三维和第四维同理
::-1
表示对于第二个轴它反转轴
相信你也得用.detach()
。我必须在使用 CUDA 和 GPU 的 Colab 上将 Tensor 转换为 numpy 数组。我是这样做的:
# this is just my embedding matrix which is a Torch tensor object
embedding = learn.model.u_weight
embedding_list = list(range(0, 64382))
input = torch.cuda.LongTensor(embedding_list)
tensor_array = embedding(input)
# the output of the line below is a numpy array
tensor_array.cpu().detach().numpy()
如果你的变量附加了一些梯度,你可以使用这个语法。
y=torch.Tensor.cpu(x).detach().numpy()[:,:,:,-1]
你的问题措辞很差。您的代码(某种程度上)已经做了您想要的。你到底在迷惑什么? x.numpy()
回答你问题的原标题:
Pytorch tensor to numpy array
您需要从标题开始改进您的问题。
无论如何,以防万一这对其他人有用。您可能需要调用 detach 才能让您的代码正常工作。例如
RuntimeError: Can't call numpy() on Variable that requires grad.
所以打电话给.detach()
。示例代码:
# creating data and running through a nn and saving it
import torch
import torch.nn as nn
from pathlib import Path
from collections import OrderedDict
import numpy as np
path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)
num_samples = 3
Din, Dout = 1, 1
lb, ub = -1, 1
x = torch.torch.distributions.Uniform(low=lb, high=ub).sample((num_samples, Din))
f = nn.Sequential(OrderedDict([
('f1', nn.Linear(Din,Dout)),
('out', nn.SELU())
]))
y = f(x)
# save data
y.numpy()
x_np, y_np = x.detach().cpu().numpy(), y.detach().cpu().numpy()
np.savez(path / 'db', x=x_np, y=y_np)
print(x_np)
cpu 分离后。参见:https://discuss.pytorch.org/t/should-it-really-be-necessary-to-do-var-detach-cpu-numpy/35489/5
此外,我不会对光滑问题发表任何评论,因为那是题外话,不应该成为您问题的重点。看到这个:
虽然其他答案完美地解释了这个问题,但我将添加一些将张量转换为 numpy 数组的真实示例:
示例:共享存储
驻留在 CPU 上的 PyTorch 张量与 numpy 数组 na
共享相同的存储空间
import torch
a = torch.ones((1,2))
print(a)
na = a.numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]])
[[10. 1.]]
tensor([[10., 1.]])
示例:消除共享存储的影响,先复制numpy数组
为了避免共享存储的影响,我们需要 copy()
numpy 数组 na
到一个新的 numpy 数组 nac
。 Numpy copy()
方法创建新的独立存储。
import torch
a = torch.ones((1,2))
print(a)
na = a.numpy()
nac = na.copy()
nac[0][0]=10
print(nac)
print(na)
print(a)
输出:
tensor([[1., 1.]])
[[10. 1.]]
[[1. 1.]]
tensor([[1., 1.]])
现在,只有 nac
numpy 数组将更改为行 nac[0][0]=10
,na
和 a
将保持原样。
示例:CPU 张量与 requires_grad=True
import torch
a = torch.ones((1,2), requires_grad=True)
print(a)
na = a.detach().numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]], requires_grad=True)
[[10. 1.]]
tensor([[10., 1.]], requires_grad=True)
在这里我们调用:
na = a.numpy()
这会导致:RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
,因为 require_grad=True
的张量由 PyTorch AD 记录。请注意 tensor.detach()
是 tensor.data
.
的新方法
这解释了为什么我们需要在使用 numpy()
转换之前先 detach()
它们。
示例:CUDA 张量 requires_grad=False
a = torch.ones((1,2), device='cuda')
print(a)
na = a.to('cpu').numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]], device='cuda:0')
[[10. 1.]]
tensor([[1., 1.]], device='cuda:0')
示例:CUDA 张量 requires_grad=True
a = torch.ones((1,2), device='cuda', requires_grad=True)
print(a)
na = a.detach().to('cpu').numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]], device='cuda:0', requires_grad=True)
[[10. 1.]]
tensor([[1., 1.]], device='cuda:0', requires_grad=True)
如果没有 detach()
方法,将设置错误 RuntimeError: Can't call
numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
。
如果没有 .to('cpu')
方法,将设置 TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
。
你可以使用 cpu()
但不是 to('cpu')
但我更喜欢更新的 to('cpu')
.
这对我有用:
np_arr = torch_tensor.cpu().detach().numpy()
我有一个 Tensor
形状 [4, 3, 966, 1296]
的火炬。我想使用以下代码将其转换为 numpy
数组:
imgs = imgs.numpy()[:, ::-1, :, :]
该代码如何工作?
您要转换的张量有 4 个维度。
[:, ::-1, :, :]
:
表示第一维原样复制转换,第三维和第四维同理
::-1
表示对于第二个轴它反转轴
相信你也得用.detach()
。我必须在使用 CUDA 和 GPU 的 Colab 上将 Tensor 转换为 numpy 数组。我是这样做的:
# this is just my embedding matrix which is a Torch tensor object
embedding = learn.model.u_weight
embedding_list = list(range(0, 64382))
input = torch.cuda.LongTensor(embedding_list)
tensor_array = embedding(input)
# the output of the line below is a numpy array
tensor_array.cpu().detach().numpy()
如果你的变量附加了一些梯度,你可以使用这个语法。
y=torch.Tensor.cpu(x).detach().numpy()[:,:,:,-1]
你的问题措辞很差。您的代码(某种程度上)已经做了您想要的。你到底在迷惑什么? x.numpy()
回答你问题的原标题:
Pytorch tensor to numpy array
您需要从标题开始改进您的问题。
无论如何,以防万一这对其他人有用。您可能需要调用 detach 才能让您的代码正常工作。例如
RuntimeError: Can't call numpy() on Variable that requires grad.
所以打电话给.detach()
。示例代码:
# creating data and running through a nn and saving it
import torch
import torch.nn as nn
from pathlib import Path
from collections import OrderedDict
import numpy as np
path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)
num_samples = 3
Din, Dout = 1, 1
lb, ub = -1, 1
x = torch.torch.distributions.Uniform(low=lb, high=ub).sample((num_samples, Din))
f = nn.Sequential(OrderedDict([
('f1', nn.Linear(Din,Dout)),
('out', nn.SELU())
]))
y = f(x)
# save data
y.numpy()
x_np, y_np = x.detach().cpu().numpy(), y.detach().cpu().numpy()
np.savez(path / 'db', x=x_np, y=y_np)
print(x_np)
cpu 分离后。参见:https://discuss.pytorch.org/t/should-it-really-be-necessary-to-do-var-detach-cpu-numpy/35489/5
此外,我不会对光滑问题发表任何评论,因为那是题外话,不应该成为您问题的重点。看到这个:
虽然其他答案完美地解释了这个问题,但我将添加一些将张量转换为 numpy 数组的真实示例:
示例:共享存储
驻留在 CPU 上的 PyTorch 张量与 numpy 数组 na
import torch
a = torch.ones((1,2))
print(a)
na = a.numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]])
[[10. 1.]]
tensor([[10., 1.]])
示例:消除共享存储的影响,先复制numpy数组
为了避免共享存储的影响,我们需要 copy()
numpy 数组 na
到一个新的 numpy 数组 nac
。 Numpy copy()
方法创建新的独立存储。
import torch
a = torch.ones((1,2))
print(a)
na = a.numpy()
nac = na.copy()
nac[0][0]=10
print(nac)
print(na)
print(a)
输出:
tensor([[1., 1.]])
[[10. 1.]]
[[1. 1.]]
tensor([[1., 1.]])
现在,只有 nac
numpy 数组将更改为行 nac[0][0]=10
,na
和 a
将保持原样。
示例:CPU 张量与 requires_grad=True
import torch
a = torch.ones((1,2), requires_grad=True)
print(a)
na = a.detach().numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]], requires_grad=True)
[[10. 1.]]
tensor([[10., 1.]], requires_grad=True)
在这里我们调用:
na = a.numpy()
这会导致:RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
,因为 require_grad=True
的张量由 PyTorch AD 记录。请注意 tensor.detach()
是 tensor.data
.
这解释了为什么我们需要在使用 numpy()
转换之前先 detach()
它们。
示例:CUDA 张量 requires_grad=False
a = torch.ones((1,2), device='cuda')
print(a)
na = a.to('cpu').numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]], device='cuda:0')
[[10. 1.]]
tensor([[1., 1.]], device='cuda:0')
示例:CUDA 张量 requires_grad=True
a = torch.ones((1,2), device='cuda', requires_grad=True)
print(a)
na = a.detach().to('cpu').numpy()
na[0][0]=10
print(na)
print(a)
输出:
tensor([[1., 1.]], device='cuda:0', requires_grad=True)
[[10. 1.]]
tensor([[1., 1.]], device='cuda:0', requires_grad=True)
如果没有 detach()
方法,将设置错误 RuntimeError: Can't call
numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
。
如果没有 .to('cpu')
方法,将设置 TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
。
你可以使用 cpu()
但不是 to('cpu')
但我更喜欢更新的 to('cpu')
.
这对我有用:
np_arr = torch_tensor.cpu().detach().numpy()