pytorch中.numpy()、.item()、.cpu()、.detach()以及.data的使用方法

.numpy()

Tensor.numpy()將Tensor轉化為ndarray,這裡的Tensor可以是標量或者向量(與item()不同)轉換前後的dtype不會改變

a = torch.tensor([[1.,2.]])
a_numpy = a.numpy() #[[1., 2.]]

.item()

將一個Tensor變量轉換為python標量(int float等)常用於用於深度學習訓練時,將loss值轉換為標量並加,以及進行分類任務,計算準確值值時需要

        optimizer.zero_grad()
        outputs = model(data)
        loss = F.cross_entropy(outputs, label)
        #計算這一個batch的準確率
        acc = (outputs.argmax(dim=1) == label).sum().cpu().item() / len(labels) #這裡也用到瞭.item()
        loss.backward()
        optimizer.step()
        train_loss += loss.item()   #這裡用到瞭.item()
        train_acc += acc

.cpu()

將數據的處理設備從其他設備(如.cuda()拿到cpu上),不會改變變量類型,轉換後仍然是Tensor變量。

.detach()和.data(重點)

.detach()就是返回一個新的tensor,並且這個tensor是從當前的計算圖中分離出來的。但是返回的tensor和原來的tensor是共享內存空間的。

舉個例子來說明一下detach有什麼用。 如果A網絡的輸出被喂給B網絡作為輸入, 如果我們希望在梯度反傳的時候隻更新B中參數的值,而不更新A中的參數值,這時候就可以使用detach()

a = A(input)
a = a.deatch() # 或者a.detach_()進行in_place操作
out = B(a)
loss = criterion(out, labels)
loss.backward()

Tensor.data和Tensor.detach()一樣, 都會返回一個新的Tensor, 這個Tensor和原來的Tensor共享內存空間,一個改變,另一個也會隨著改變,且都會設置新的Tensor的requires_grad屬性為False。這兩個方法隻取出原來Tensor的tensor數據, 丟棄瞭grad、grad_fn等額外的信息。

tensor.data是不安全的, 因為 x.data 不能被 autograd 追蹤求微分

這是為什麼呢?我們對.data進行進一步探究

import torch

a = torch.tensor([4., 5., 6.], requires_grad=True)
print("a", a)
out = a.sigmoid()
print("out", out)
print(out.requires_grad)   #在進行.data前仍為true
result = out.data  #共享變量,同時將requires_grad設置為false
result.zero_()  # 改變c的值,原來的out也會改變
print("result", result)
print("out", out)
out.sum().backward()  # 對原來的out求導,
print(a.grad)  # 不會報錯,但是結果卻並不正確
'''運行結果為:
a tensor([4., 5., 6.], requires_grad=True)
out tensor([0.9820, 0.9933, 0.9975], grad_fn=<SigmoidBackward0>)
True
result tensor([0., 0., 0.])
out tensor([0., 0., 0.], grad_fn=<SigmoidBackward0>)
tensor([0., 0., 0.])
'''

由於更改分離之後的變量值result,導致原來的張量out的值也跟著改變瞭,但是這種改變對於autograd是沒有察覺的,它依然按照求導規則來求導,導致得出完全錯誤的導數值卻渾然不知。

那麼我們繼續看看.detach()

可以看到將.data改為.detach()後程序立馬報錯,阻止瞭非法的修改,安全性很高

我們需要記住的就是:

  • .data 是一個屬性,二.detach()是一個方法;
  • .data 是不安全的,.detach()是安全的。

補充:關於.data和.cpu().data的各種操作

先上圖

仔細分析:

1.首先a是一個放在GPU上的Variable,a.data是把Variable裡的tensor取出來,

  可以看出與a的差別是:缺少瞭第一行(Variable containing)

2.a.cpu()和a.data.cpu()是分別把a和a.data放在cpu上,其他的沒區別,另外:a.data.cpu()和a.cpu().data一樣

3.a.data[0] |  a.cpu().data[0]  | a.data.cpu()[0]是一樣的,都是把第一個值取出來,類型均為float

4.a.data.cpu().numpy()把tensor轉換成numpy的格式

總結

到此這篇關於pytorch中.numpy()、.item()、.cpu()、.detach()以及.data使用的文章就介紹到這瞭,更多相關pytorch .numpy()、.item()、.cpu()、.detach()及.data內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: