1. 程式人生 > >用Numpy實現一個簡單的神經網路

用Numpy實現一個簡單的神經網路

本示例來自於PyTorch的官網上的一個warm-up小示例, 覺得很有代表性, 所有這裡單獨記錄一下.
對於numpy來說, 它對計算圖, 深度學習, 梯度等等概念幾乎是不知道的, 但是, 如果我們瞭解簡單神經網路的具體結構, 那麼我們就可以很輕易的用numpy來實現這個簡單網路, 對此, 我們通常需要自己來實現前向計算和反向計算的邏輯, 下面我們來實現一個具有兩層隱藏層的簡單網路:

import numpy as np

# N 為batch size, D_in 為輸入維度
# H 為隱藏層的維度, D_out 為輸出的維度
N, D_in, H, D_out = 64, 1000, 100, 10
# 建立隨機的輸入和輸出資料 x = np.random.randn(N, D_in) # N × D_in 的矩陣 y = np.random.randn(N, D_out) # N × D_out 的矩陣 # 對兩個隱藏層w1,w2進行初始化 w1 = np.random.randn(D_in, H) w2 = np.random.randn(H, D_out) # 設定學習率 learning_rate = 1e-6 for t in range(500): # 前向傳播: 計算預測結果 y_pred h = x.dot(w1) # x維度為64 × 1000, w1維度為 1000 × 100, 計算完以後, h維度為 64 × 100
h_relu = np.maximum(h,0) y = h_relu.dot(w2) # h_relu維度為 64×100, w2維度為100×10, y的維度為64×10 # 計算損失 loss = np.square(y_pred - y).sum() print(t, loss) # 反向傳播根據loss更新w1和w2的值 grad_y_pred = 2.0*(y_pred - y) # 對y_pred求導 grad_w2 = h_relu.T.dot(grad_y_pred) # 對w2求導, 微分矩陣應該與w2的size相同 grad_h_relu =
grad_y_pred.dot(w2.T) # 對h_relu求導 grad_h = grad_h_relu.copy() grad_h[h < 0] = grad_h_relu # 經過relu, 將小於0的梯度歸0 grad_w1 = x.T.dot(grad_h) # Update weights w1 = w1 - learning_rate * grad_w1 w2 = w2 - learning_rate * grad_w2

在執行上述程式碼以後, w1w2的值會是的預測出來的pred_yy之間的平方損失越來越小.