4 2 PyTorch自動反向傳播

2021-10-02 20:33:32 字數 3098 閱讀 3726

4.1節中介紹了全手工進行模型構建與訓練的過程,因為一元線性回歸模型只涉及2個引數w,b,所以寫起來倒也不費勁,但真實業務場景中自然會複雜很多,可能會涉及百萬的參數量,因此手工求每個引數的梯度簡直難以想象。

不用擔心,pytorch提供了自動反向計算的機制,一行**搞定你的煩惱。

還是按照原來的步驟,先進行前向計算:

import torch

# 構建模型函式

defmodel

(x, w, b)

:return w*x + b

# 構建損失函式

defloss_fn

(y_p, y)

: squared_diffs =

(y_p - y)**2

return squared_diffs.mean(

)# x與y

x =[

0.5,

14.0

,15.0

,28.0

,11.0

,8.0

,3.0,-

4.0,

6.0,

13.0

,21.0

]y =

[35.7

,55.9

,58.2

,81.9

,56.3

,48.9

,33.9

,21.8

,48.4

,60.4

,68.4

]x = torch.tensor(x)

y = torch.tensor(y)

x =0.1

* x# 初始化引數

params = torch.tensor(

[1.0

,0.0

], requires_grad=

true

)# 注意這裡

# 前向計算

y_p = model(x,

*params)

loss = loss_fn(y_p, y)

注意,在建立初始化引數的時候,requires_grad=true表示告訴pytorch需要跟蹤在params上的所有操作與tensor,並記錄下param tensor的梯度。通常情況下, 所有的pytorch tensor都回有乙個屬性.grad, 預設是none值,如下:

print

(params.grad)

none
現在,我們來對params計算損失的梯度:使用pytorch提供的自動反向計算功能來計算params的梯度:

loss = loss_fn(model(x,

*params)

, y)

loss.backward(

)print

(params.grad)

tensor([-989.5273,  -82.6000])
上面**,首先對loss呼叫了.backward()方法,會在loss上對葉子節點上的變數(params)進行求導並累加,也就是說被設定了requires_grad=true的params張量上的grad屬性被賦值了,再列印params.grad就會有如上結果,即梯度。

要注意的是呼叫.backward()是將本次梯度「累加」導節點原有的梯度上,而不是「替換」,若進行下一次迭代時,梯度需要重新置零才行。

if params.grad is

notnone

: params.grad.zero_(

)

好啦,上面講述了一次迭代計算梯度的過程,若有多次迭代,我們整合如下:

def

training_loop

(n_epochs, learning_rate, params, x, y)

:for epoch in

range(1

, n_epochs+1)

:if params.grad is

notnone

: params.grad.zero_(

) y_p = model(x,

*params)

loss = loss_fn(y_p, y)

loss.backward(

)

params =

(params - learning_rate * params.grad)

.detach(

).requires_grad_(

)# 注意這裡,需要設定心params的requires_grad屬性

if epoch %

100==0:

print

('epoch %d, loss %f'

%(epoch,

float

(loss)))

return params

training_loop(

n_epochs =

1000

, learning_rate =1e-

2,params = torch.tensor(

[1.0

,0.0

], requires_grad=

true),

x = x,

y = y

)

epoch 100, loss 39.538250

epoch 200, loss 18.696901

epoch 300, loss 12.456582

epoch 400, loss 10.581183

epoch 500, loss 10.017575

epoch 600, loss 9.848182

epoch 700, loss 9.797276

epoch 800, loss 9.781981

epoch 900, loss 9.777378

epoch 1000, loss 9.776002

tensor([17.9473, 32.9443], requires_grad=true)

總結:

4 2 前向傳播和反向傳播

假設輸入 輸出 快取 從實現的角度來說快取 更容易在不同的環節呼叫函式。向量化實現過程可以寫成 前向傳播需要餵入資料 也就是x來初始化。對於多層神經網路,在計算從第1層到第l層時,只能使用for迴圈來實現。輸入 d 輸出 d d d 所以反向傳播的步驟可以寫成 前四個式子用於實現反向傳播,式子 5 ...

pytorch學習 反向傳播backward

pytorch學習 反向傳播backward backward函式屬於torch.autograd函式庫,在深度學習過程中對函式進行反向傳播,計算輸出變數關於輸入變數的梯度。其輸入變數自然應滿足autograd 的要求,為variable型別而不是tensor型別。常見的使用方法為 此時分為兩種情況...

pytorch梯度累加反向傳播

傳統的訓練函式,乙個batch是這麼訓練的 for i,images,target in enumerate train loader 1.input output images images.cuda non blocking true target torch.from numpy np.arr...