To get a value from single element tensor x.item() works always:
Example : Single element tensor on CPU
x = torch.tensor([3])
x.item()
Output:
3
Example : Single element tensor on CPU with AD
x = torch.tensor([3.], requires_grad=True)
x.item()
Output:
3.0
NOTE: We needed to use floating point arithmetic for AD
Example : Single element tensor on CUDA
x = torch.tensor([3], device='cuda')
x.item()
Output:
3
Example : Single element tensor on CUDA with AD
x = torch.tensor([3.], device='cuda', requires_grad=True)
x.item()
Output:
3.0
Example : Single element tensor on CUDA with AD again
x = torch.ones((1,1), device='cuda', requires_grad=True)
x.item()
Output:
1.0
To get a value from non single element tensor we have to be careful:
The next example will show that PyTorch tensor residing on CPU shares the same storage as numpy array na
Example: Shared storage
import torch
a = torch.ones((1,2))
print(a)
na = a.numpy()
na[0][0]=10
print(na)
print(a)
Output:
tensor([[1., 1.]])
[[10. 1.]]
tensor([[10., 1.]])
Example: Eliminate effect of shared storage, copy numpy array first
To avoid the effect of shared storage we need to copy() the numpy array na to a new numpy array nac. Numpy copy() method creates the new separate storage.
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)
This would cause: RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead., because tensors that require_grad=True are recorded by PyTorch AD.
This is why we need to detach() them first before converting using numpy().
Example: CUDA tensor 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)
Without detach() method the error RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead. will be set.
Without .to('cpu') method TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first. will be set.