天天看點

Pytorch學習筆記_2_Autograd自動求導機制Autograd 自動求導機制

Autograd 自動求導機制

PyTorch 中所有神經網絡的核心是

autograd

包。

autograd

包為張量上的所有操作提供了自動求導。它是一個在運作時定義的架構,可以通過代碼的運作來決定反向傳播的過程,并且每次疊代可以是不同的。

通過一些示例來了解

Tensor 張量

torch.tensor

是這個包的核心類。

  • 設定

    .requires_grad

    True

    ,會追蹤所有對于該張量的操作。計算完成後調用

    .backward()

    ,可以自動計算所有的梯度,并自動累計到

    .grad

    屬性中
事實上即使

.requires_grad

True

并不意味着

.grad

一定不為

None

  • 可以調用

    .detach()

    将該張量與計算曆史記錄分離,并禁止跟蹤它将來的計算記錄
  • 為防止跟蹤曆史記錄(和使用記憶體),可以将代碼塊包裝在

    with torch.no_grad():

    中。這在評估模型時特别有用,因為模型可能具有

    requires_grad = True

    的可訓練參數,但是我們不需要梯度計算。

Function類

Tensor

Function

互相連接配接并生成一個非循環圖,它表示和存儲了完整的計算曆史。

每個張量都有一個

.grad_fn

屬性,這個屬性引用了一個建立了

Tensor

Function

(除非這個張量是使用者手動建立的,即,這個張量的

grad_fn

None

leaf Tensors 葉張量

Tensor

中有一屬性

is_leaf

,當它為

True

有兩種情況:
  1. 按照慣例,

    requires_grad = False

    的 Tensor
  2. requires_grad = True

    且由使用者建立的 Tensor。這意味着它們不是操作的結果且

    grad_fn = None

    隻有leaf Tensors葉張量在反向傳播時才會将本身的

    grad

    傳入

    backward()

    的運算中。要想得到non-leaf Tensors非葉張量在反向傳播時的

    grad

    ,可以使用

    retain_grad()

如果需要計算導數,可以在

Tensor

上調用

.backward()

:若

Tensor

是一個标量(即包含一個元素資料)則不需要為

backward()

指定任何參數, 但是如果它有更多的元素,需要指定一個

gradient

參數來比對張量的形狀。

x = torch.ones(2, 2, requires_grad=True)
print(x) 
# Output:
# tensor([[1., 1.],
#        [1., 1.]], requires_grad=True)
y = x + 2
print(y)
# Output:
# tensor([[3., 3.],
#        [3., 3.]], grad_fn=<AddBackward0>)
           

此時,

y

已經被計算出來,

grad_fn

已經自動生成了

>>> print(y.grad_fn)
<AddBackward0 object at 0x0000013D6C2AB848>
           

對y進行操作

z = y * y * 3
out = z.mean()
print(z, out)
# Output:
# tensor([[27., 27.],
#        [27., 27.]], grad_fn=<MulBackward0>) # tensor(27., grad_fn=<MeanBackward0>)
           

.requires_grad_( ... )

可以改變現有張量的

requires_grad

屬性。 如果沒有指定的話,預設輸入的flag是

False

Gradients 梯度

現在開始反向傳播

因為

out

是一個标量,是以不需要為

backward()

指定任何參數:

out.backward()
print(x.grad)
# Output:
# tensor([[4.5000, 4.5000],
#        [4.5000, 4.5000]])
           
Pytorch學習筆記_2_Autograd自動求導機制Autograd 自動求導機制
Pytorch學習筆記_2_Autograd自動求導機制Autograd 自動求導機制

現在讓我們來看一個vector-Jacobian product的例子

x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
    y = y * 2
print(y) 
# Output:
# tensor([ 293.4463,   50.6356, 1031.2501], grad_fn=<MulBackward0>)
           
此處

y.data.norm()

指y的範數,即(y_1^2 + … + y_n2)(1/2)

在這個情形中,y不再是個标量。

torch.autograd

無法直接計算出完整的雅可比行列,但是如果我們隻想要vector-Jacobian product,隻需将向量作為參數傳入

backward

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
# Output:
# tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])
           

如果

.requires_grad=True

但是你又不希望進行autograd的計算, 那麼可以将變量包裹在

with torch.no_grad()

中:

print(x.requires_grad) # True
print((x ** 2).requires_grad) # True

with torch.no_grad():
	print((x ** 2).requires_grad) # False
           

繼續閱讀