Pytorch強化練習之手動實現前向和反向傳播

2021-10-09 05:02:30 字數 2737 閱讀 8563

pytorch的兩個核心特徵:

1.提供n維張量tensor,類似於numpy,但可以在gpu上執行。

2.提供搭建和訓練神經網路時的自動微分/求導機制。

本章節我們將使用全連線的relu網路作為執行示例。該網路將有乙個單一的隱藏層,並將使用梯度下降訓練,通過最小化網路輸出和真正 結果的歐幾里得距離,來擬合隨機生成的資料。

以下內容分別用numpy和torch實現。

import numpy as np

import torch

# numpy進行資料處理(定義陣列,前向、反向傳播等)

defnpbp()

:# n為批量大小;d_in為輸入維度;h為隱藏層維度;d_out為輸出維度

n, d_in, h, d_out =64,

1000

,100,10

# 建立隨機輸入、輸出資料

x = np.random.randn(n, d_in)

y = np.random.rand(n, d_out)

# 隨機初始化權重

w1 = np.random.rand(d_in, h)

w2 = np.random.rand(h, d_out)

# 學習率

learning_rate =1e-

6for i in

range

(500):

# 前向傳播,計算**值。

h = x.dot(w1)

h_relu = np.maximum(h,0)

y_pred = h_relu.dot(w2)

# 計算和列印損失

loss = np.square(y_pred - y)

.sum()

print

(i, loss)

# 反向傳播,計算loss對w1的梯度。注:列出鏈式求導公式

grad_y_pred =2*

(y_pred - y)

grad_w2 = h_relu.t.dot(grad_y_pred)

# 反向傳播,計算loss對w2的梯度

grad_h_relu = grad_y_pred.dot(w2.t)

grad_h = grad_h_relu.copy(

) grad_h[h <0]

=0grad_w1 = x.t.dot(grad_h)

# 更新權重

w1 -= learning_rate * grad_w1

w2 -= learning_rate * grad_w2

# torch實現**

defptbp()

: dtype = torch.

float

device = torch.device(

"cpu"

)# device = torch.device("cuda: 0")# 解除注釋可以在gpu上執行

# 定義變數

n, d_in, h, d_out =64,

1000

,100,10

# 建立隨機輸入輸出資料

x = torch.randn(n, d_in, device=device, dtype=dtype)

y = torch.randn(n, d_out, device=device, dtype=dtype)

# 隨機初始化權重

w1 = torch.randn(d_in, h, device=device, dtype=dtype)

w2 = torch.randn(h, d_out, device=device, dtype=dtype)

learning_rate =1e-

6for i in

range

(500):

# 前向傳播

h = x.mm(w1)

# (n, h)

h_relu = h.clamp(

min=0)

# 取大於0的值,小於0的值取0 (n, h)

y_pred = h_relu.mm(w2)

# (n, d_out)

# 計算列印損失

loss =

(y_pred - y)

.pow(2

).sum(

).item(

)print

(i, loss)

# 反向傳播

grad_y_pred =

2.0*

(y_pred - y)

# (n, d_out)

grad_w2 = h_relu.t(

).mm(grad_y_pred)

# (h, d_out)

grad_h_relu = grad_y_pred.mm(w2.t())

# (n, h)

grad_h = grad_h_relu.clone(

)# (n, h)

grad_h[h <0]

=0grad_w1 = x.t(

).mm(grad_h)

# (d_in, h)

# 梯度下降更新權重

w1 -= learning_rate * grad_w1

w2 -= learning_rate * grad_w2

if __name__ ==

'__main__'

: npbp(

) ptbp(

)

參考:

Qt之手動布局

手動布局,可以實現和水平布局 垂直布局 網格布局等相同的效果,也可實現屬於自己的自定義布局,當窗體縮放時,控制項可以隨之變化。其對於座標系的建立有嚴格要求,純 思維,使用複雜,不易維護,所以一般不建議使用。下面我們以簡單的例子來講解如何使用。水平布局總結 在qt之布局管理器一節中,我們介紹了對於手動...

ios之手動記憶體管理

在建立物件的時候,回生成retaincount變數,alloc,new,retain都會使這個值 1,對應的release方法則會使這個值 1。當retaincount 0時系統會呼叫dealloc方法使系統銷毀改物件。所以我們在使用手動記憶體管理時,要注意一下問題 1.原則 記憶體管理原則 配對原...

iOS之手動記憶體管理

objective c採用了一種被稱為引用計數 reference counting 的機制來追蹤物件狀態,每個物件都有乙個與之關聯的整數,被稱為引用計數器。當乙個物件的引用計數為0時,表明程式不再需要該物件,物件會被銷毀。若是物件還持有其他物件的引用,必須重寫dealloc方法,在方法中釋放該物件...