莫煩pytorch學習筆記(二)——variable


1.簡
torch.autograd.Variable是Autograd的核心類,它封裝了Tensor,並整合了反向傳播的相關實現
Variable和tensor的區別和聯系 Variable是籃子,而tensor是雞蛋,雞蛋應該放在籃子里才能方便拿走(定義variable時一個參數就是tensor) Variable這個籃子里除了裝了tensor外還有requires_grad參數,表示是否需要對其求導,默認為False Variable這個籃子呢,自身有一些屬性 比如grad,梯度variable.grad是d(y)/d(variable)保存的是變量y對variable變量的梯度值,如果requires_grad參數為False,所以variable.grad返回值為None,如果為True,返回值就為對variable的梯度值 比如grad_fn,對於用戶自己創建的變量(Variable())grad_fn是為none的,也就是不能調用backward函數,但對於由計算生成的變量,如果存在一個生成中間變量的requires_grad為true,那其的grad_fn不為none,反則為none 比如data,這個就很簡單,這個屬性就是裝的雞蛋(tensor)

 

Varibale包含三個屬性:
data:存儲了Tensor,是本體的數據
grad:保存了data的梯度,本事是個Variable而非Tensor,與data形狀一致
grad_fn:指向Function對象,用於反向傳播的梯度計算之用
 
具體來說,在pytorch中的Variable就是一個存放會變化值的地理位置,里面的值會不停發生片花,就像一個裝雞蛋的籃子,雞蛋數會不斷發生變化。
那誰是里面的雞蛋呢,自然就是pytorch中的tensor了。(也就是說,pytorch都是有tensor計算的,而tensor里面的參數都是Variable的形式)。
如果用Variable計算的話,那返回的也是一個同類型的Variable。
【tensor 是一個多維矩陣】
用一個例子說明,Variable的定義:
import torch
from torch.autograd import Variable # torch 中 Variable 模塊
tensor = torch.FloatTensor([[1,2],[3,4]])
# 把雞蛋放到籃子里, requires_grad是參不參與誤差反向傳播, 要不要計算梯度
variable = Variable(tensor, requires_grad=True)

print(tensor)
"""
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""
 
print(variable)
"""
Variable containing:
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""

 

 注:tensor不能反向傳播,variable可以反向傳播

二、Variable求梯度

Variable計算時,它會逐漸地生成計算圖。這個圖就是將所有的計算節點都連接起來,最后進行誤差反向傳遞的時候,一次性將所有Variable里面的梯度都計算出來,而tensor就沒有這個能力。

 

v_out.backward()    # 模擬 v_out 的誤差反向傳遞

print(variable.grad)    # 初始 Variable 的梯度
'''
 0.5000  1.0000
 1.5000  2.0000
'''

 

三、獲取Variable里面的數據

直接print(Variable) 只會輸出Variable形式的數據,在很多時候是用不了的。所以需要轉換一下,將其變成tensor形式。

print(variable)     #  Variable 形式
"""
Variable containing:
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""
 
print(variable.data)    # 將variable形式轉為tensor 形式
"""
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""
print(variable.data.numpy())    # numpy 形式
"""
[[ 1.  2.]
 [ 3.  4.]]
"""

 

 

四:關於require_grad對variable的作用

 代碼一: 

 

import numpy as np
import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad = False)
temp = Variable(torch.zeros(2,2),requires_grad = True)
y = x + temp + 2
y = y.mean()  #求平均數
y.backward()  #反向傳遞函數,用於求y對前面的變量(x)的梯度
print(x.grad) # d(y)/d(x)

 

   none

  (因為requires_grad=False)

代碼二:

import numpy as np
import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad = False)
temp = Variable(torch.zeros(2,2),requires_grad = True)
y = x + temp + 2
y = y.mean()  #求平均數
y.backward()  #反向傳遞函數,用於求y對前面的變量(x)的梯度
print(temp.grad)  # d(y)/d(temp)

 

tensor([[0.2500, 0.2500],
        [0.2500, 0.2500]])

代碼三:

import numpy as np
import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad = False)
temp = Variable(torch.zeros(2,2),requires_grad = True)
y = x + 2
y = y.mean()  #求平均數
y.backward()  #反向傳遞函數,用於求y對前面的變量(x)的梯度
print(x.grad)  # d(y)/d(x)

 

Traceback (most recent call last):
  File "path", line 12, in <module>
    y.backward()
(報錯了,因為生成變量y的中間變量只有x,而x的requires_grad是False,所以y的grad_fn是none)
 
代碼四:
import numpy as np
import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad = False)
temp = Variable(torch.zeros(2,2),requires_grad = True)
y = x + 2
y = y.mean()  #求平均數
#y.backward()  #反向傳遞函數,用於求y對前面的變量(x)的梯度
print(y.grad_fn)  # d(y)/d(x)

none

五:grad屬性

在每次backward后,grad值是會累加的,所以利用BP算法,每次迭代是需要將grad清零的。

x.grad.data.zero_()

(in-place操作需要加上_,即zero_)

六:擴展
在PyTorch中計算圖的特點總結如下:
autograd根據用戶對Variable的操作來構建其計算圖。
requires_grad
variable默認是不需要被求導的,即requires_grad屬性默認為False,如果某一個節點的requires_grad為True,那么所有依賴它的節點requires_grad都為True。
volatile
variable的volatile屬性默認為False,如果某一個variable的volatile屬性被設為True,那么所有依賴它的節點volatile屬性都為True。volatile屬性為True的節點不會求導,volatile的優先級比requires_grad高。
retain_graph
多次反向傳播(多層監督)時,梯度是累加的。一般來說,單次反向傳播后,計算圖會free掉,也就是反向傳播的中間緩存會被清空【這就是動態度的特點】。為進行多次反向傳播需指定retain_graph=True來保存這些緩存。
.backward()
反向傳播,求解Variable的梯度。放在中間緩存中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM