Does .item() automatically move the data to the cpu?

When you call item(), the number is no longer a tensor, does this necessarily mean that it can no longer live on the gpu? The docs for .item() don’t say anything about the data moving, however, the docs for .tolist(), which is the same as .item() except for multiple items, says the data is moved to cpu first ‘if necessary’. What does that mean? https://pytorch.org/docs/stable/tensors.html#torch.Tensor.tolist

1 Like

Hi,

Yes .item() moves the data to CPU. It converts the value into a plain python number. And plain python number can only live on the CPU.

6 Likes

Hi,

Sorry if this might come of as a stupid question;

What’s the difference between using .item and .data then?

.item() returns the value as a “standard Python number”, while the .data attribute accesses the internal tensor with its value (and you could thus easily break the computation graph by manipulating it).

x = torch.randn(1)
print(x.item())
> -0.7826926112174988
print(x.data)
> tensor([-0.7827])
3 Likes

Thank you so much for your prompt reply! :grin:

So let’s say that I would like to use sklearn’s metrics, what would be the best approach to copy my tensor as a numpy input?

Let’s take the example below where my preds and labels are tensors on the GPU

precision,recall,f1,_ = precision_recall_fscore_support(labels,preds,average='binary')

Would I use .item().numpy() in this case?

Because it seems that .item() only works when you have a single value.

No, you would detach the tensor (in case it has an Autograd history), push the data to the CPU, and transform it to a numpy array via:

preds = torch.randn(10, 10, requires_grad=True) # GPUTensors with Autograd history
preds_arr = preds.detach().cpu().numpy()
np_fun(preds_arr)
4 Likes

Would it be equivelent to the below?

with torch.no_grad():
    preds_array  = preds.cpu().numpy()

Also is there a downside to doing the following instead:

with torch.no_grad():
    outputs  = np_fun(preds.cpu().numpy())

The first code snippet would be equivalent to my example and you might prefer one or the other approach.
No, there is no downside in “combining” the calls. Note however, that the numpy() operation is cheap, as no data will be copied.

2 Likes

Thank you so much for your help, you have no idea how much your contributions have helped this community! :grin:

1 Like