什麼是變量Variable
在torch中的variable就是一個存放會變化的值的地理位置,裏面的值會不停的變化。就像一個裝雞蛋的籃子,雞蛋數量會不停變動,誰是裏面的雞蛋呢?自然就是torch的tensor了。如果用一個variable進行計算,那返回的也是一個同類型的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]
"""
variable計算,梯度
我們再對比一下tensor的計算和variable的計算
t_out = torch.mean(tensor*tensor) # x^2
v_out = torch.mean(variable*variable) # x^2
print(t_out)
print(v_out) # 7.5
到目前爲止,我們看不出什麼不同,但是記住,variable計算的時候,它在背景幕布後面一步步默默地搭建着一個龐大的系統,叫做計算圖,computaional graph。這個圖是用來做什麼的?原來是將所有的計算步驟(節點)都連接起來,最後進行誤差反向傳遞的時候,一次性將所有variable裏面的修改幅度(梯度)都計算出來,而tensor就沒有這個能力了。
v_out = torch.mean(variable*variable)
就是在計算圖中添加的一個計算步驟,計算誤差反向傳遞的時候有他的一份功勞,我們就來舉個例子
v_out.backward() # 模擬 v_out 的誤差反向傳遞
# 下面兩步看不懂沒關係, 只要知道 Variable 是計算圖的一部分, 可以用來傳遞誤差就好.
# v_out = 1/4 * sum(variable*variable) 這是計算圖中的 v_out 計算步驟
# 針對於 v_out 的梯度就是, d(v_out)/d(variable) = 1/4*2*variable = variable/2
print(variable.grad) # 初始 Variable 的梯度
'''
0.5000 1.0000
1.5000 2.0000
'''
獲取variable裏面的數據
直接print(variable)
只會輸出variable形式的數據,在很多時候是用不了的(比如用plt畫圖),所以我們要轉換一下,將它變成tensor形式
print(variable) # Variable 形式
"""
Variable containing:
1 2
3 4
[torch.FloatTensor of size 2x2]
"""
print(variable.data) # tensor 形式
"""
1 2
3 4
[torch.FloatTensor of size 2x2]
"""
print(variable.data.numpy()) # numpy 形式
"""
[[ 1. 2.]
[ 3. 4.]]
"""