pytroch的一點使用心得

目錄

pytroch的一些注意點

pytorch是一個很方便的深度框架,上手簡單,不過也有一些需要注意的點:

  • Tensor和Variable的區別
  • backward的使用

Tensor和Variable的區別

-Tensor只是一個類似與Numpy的矩陣塊,我們可以用Tensor作爲Numpy的代替。 比Numpy相比如果使用的是gpu版的pytorch,則我們可以選擇把Tensor存在顯卡上,使用.cuda的辦法。
- Variable不僅封裝了Tensor作爲對應的激活值,還保存了產生這個Variable的 計算圖,確保之後的自動求導可行。
- 具體可以參考這篇pytorch如何構建計算圖
- 用Tensor構成的Variable並不共享內存。
例如:

import torch 
from torch.autograd import Variable

data = torch.randn(3, 4)
Data = Variable(data, requires_grad=True)
print(data)
print(Data)
"""
-0.4764 -0.3905  0.7649  0.0500
 2.2558 -0.6688  0.3069 -1.1182
 0.0612  0.7757  0.9996 -0.2380
[torch.DoubleTensor of size 3x4]

Variable containing:
-0.4764 -0.3905  0.7649  0.0500
 2.2558 -0.6688  0.3069 -1.1182
 0.0612  0.7757  0.9996 -0.2380
[torch.DoubleTensor of size 3x4]
"""
Data = Data + Variable(torch.ones(3, 4))
print(data)
print(Data)
"""
-0.4764 -0.3905  0.7649  0.0500
 2.2558 -0.6688  0.3069 -1.1182
 0.0612  0.7757  0.9996 -0.2380
[torch.DoubleTensor of size 3x4]

Variable containing:
 0.5236  0.6095  1.7649  1.0500
 3.2558  0.3312  1.3069 -0.1182
 1.0612  1.7757  1.9996  0.7620
[torch.DoubleTensor of size 3x4]
"""

backward的使用

-backwardVariable用來計算梯度的方法。值得注意的是,如果Variable 本身是一個標量時,可以直接使用Variable.backward()來獲得所需要的導數。例如:

import torch 
from torch.autograd import Variable

data = torch.randn(3, 4)
Data = Variable(data, requires_grad=True)
print(Data)
"""
Variable containing:
 0.0291 -0.9512  2.1084  0.7745
-0.5678  1.6256 -0.1632 -0.0343
 0.2082  1.8471  1.4175 -0.3341
[torch.FloatTensor of size 3x4]
"""

print(Data.grad)
"""
None
"""

F = torch.mean(Data + Variable(torch.ones(3, 4)))
F.backward()
print(Data.grad)
"""
Variable containing:
1.00000e-02 *
  8.3333  8.3333  8.3333  8.3333
  8.3333  8.3333  8.3333  8.3333
  8.3333  8.3333  8.3333  8.3333
[torch.FloatTensor of size 3x4]
"""
  • 如果Variable本身是非標量時,可以直接使用Variable.backward(a)來獲得所需要的導數(a的大小和Variable的大小一致)。例如:
import torch 
from torch.autograd import Variable

data = torch.randn(3, 4)
x = Variable(data, requires_grad=True)
y = Variable(torch.randn(2, 3))
print(x)
print(y)
"""
Variable containing:
 0.2585  0.5968 -0.1272 -1.3166
-0.0830 -0.8735  0.1632 -1.0764
-0.5808  0.5057  0.1693  0.7596
[torch.FloatTensor of size 3x4]

Variable containing:
 0.6695 -1.6198 -0.5489
 2.8908  0.1137 -0.7324
[torch.FloatTensor of size 2x3]
"""

print(x.grad)
"""
None
"""

loss = torch.mm(y, x) # torch.mm表示x與y做矩陣乘法,loss的shape爲 2 * 4
loss.backward(torch.ones(2, 4))
print(x.grad)
"""
Variable containing:
 3.5603  3.5603  3.5603  3.5603
-1.5061 -1.5061 -1.5061 -1.5061
-1.2813 -1.2813 -1.2813 -1.2813
[torch.FloatTensor of size 3x4]
"""
  • 上述例子可以理解爲得到的loss與一個和loss一樣大小的全1的矩陣,做對應位置相乘最後相加得到一個標量之後在求導。這就化成第一種情況,所以也就可以理解爲loss在每個分量上的梯度。更多例子可見pytorch自動微分的幾個例子
  • 需要注意的一點,pytorch的 backward在使用過一次之後會把相關信息刪除,所以每次構建的圖只允許一次backward否則會報錯RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.如果要多次使用需要在backward設置 retain_variables=True
  • 最後需要注意一點,使用Variable.backward()Variable的梯度的時候,Variable.grad是累加。例子可見關於Gradient,所以每次完成後記得把梯度變回0,Variable.grad.data.zero_()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章