如何在 PyTorch 中获取张量的值?

Posted

技术标签:

【中文标题】如何在 PyTorch 中获取张量的值?【英文标题】:How do I get the value of a tensor in PyTorch? 【发布时间】:2020-01-03 17:53:25 【问题描述】:

打印张量给出:

>>> x = torch.tensor([3])
>>> print(x)
tensor([3])

同样索引其.data 给出:

>>> x.data[0]
tensor(3)

我如何获得3 的值?

【问题讨论】:

How to cast a 1-d IntTensor to int in Pytorch的可能重复 【参考方案1】:

您可以使用x.item() 从具有一个元素的张量中获取 Python 数字。

【讨论】:

这应该被标记为最佳解决方案。 如果我们的张量中有多个项目怎么办?当我有一个包含 2 个或更多元素的张量时,它会引发错误。【参考方案2】:

将张量转换为 numpy:

x.numpy()[0]

【讨论】:

x.item() @Vimal Thilak 所写的可能是假设(如您的示例中)张量具有一个元素的最 Pythonic 方式。这种方法最好避免类型之间的额外转换。 如果x 在 GPU 上,这将失败。最好的做法x[0].item()【参考方案3】:

从单个元素张量x.item() 中获取值始终有效:

示例 : CPU 上的单元素张量

x = torch.tensor([3])
x.item()

输出:

3

示例带有 AD 的 CPU 上的单元素张量

x = torch.tensor([3.], requires_grad=True)
x.item()

输出:

3.0

注意:我们需要对 AD 使用浮点运算

示例 : CUDA 上的单元素张量

x = torch.tensor([3], device='cuda')
x.item()

输出:

3

示例带有 AD 的 CUDA 上的单元素张量

x = torch.tensor([3.], device='cuda', requires_grad=True)
x.item()

输出:

3.0

示例 : CUDA 上的单元素张量再次使用 AD

x = torch.ones((1,1), device='cuda', requires_grad=True)
x.item()

输出:

1.0

要从非单元素张量中获取值,我们必须小心:

下一个示例将显示驻留在 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]=10naa 行将保持原样。

示例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 记录。

这就是为什么我们需要在使用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 张量转换为 CPU。这里没有共享存储的影响。

示例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. 将被设置。

【讨论】:

【参考方案4】:

您可以使用x.cpu().detach().numpy() 从具有一个元素的张量中获取 Python 数组,然后您可以从该数组中获取一个数字

【讨论】:

以上是关于如何在 PyTorch 中获取张量的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 Pytorch 中列表的值定义掩码函数

如何在 pytorch 和 tensorflow 中使用张量核心?

如何在pytorch中展平张量?

如何在 Pytorch 中检查张量是不是在 cuda 上?

如何在 TensorFlow 中执行 PyTorch 风格的张量切片更新?

如何在pytorch中连接两个不同尺寸的张量