使用numpy實現兩層神經網絡

1. 網絡結構及實現思路

以下爲次此依賴的的網絡結構,並且後邊的所有思路及編程都將遵循這個結構給出。
在這裏插入圖片描述
其中隱藏層、激活函數(採用Relu函數)、輸出層的內容如下:

  • h=xw1h=xw_1
  • a=max(0,h)a=max(0,h)
  • y^=aw2\hat{y}=aw_2

其整體實現思路如下:

1. 定義神經網絡參數
2. 實現前饋神經網絡 forward pass
3. 計算損失 loss
4. 實現反向傳播 backword pass

2.編程實現及公式推導

# @Time : 2020/5/7 23:25 
# @Author : kingback
# @File : model_practice.py 
# @Software: PyCharm

## 使用numpy實現兩層神經網絡

import torch
import numpy as np


#一個全連接的Relu神經網絡,一個隱藏層,沒有bias,用來從x預測y:
#這一實現的三大過程:
#1.前饋神經網絡 forword pass
#2.計算損失 loss
#3.反向傳播 backword pass


#神經網絡參數定義:
N,D_in,D_out,H=64,1000,10,100
# N:代表64個人
# D_in:代表每個人輸入到神經網絡1000個數據點
# D_out:代表每個人從神經網絡輸出10個數據點
# H:代表該神經網絡含有100個隱藏層

x=np.random.randn(N,D_in)
#定義輸入到神經網絡之前的數據矩陣,大小爲64*1000
y=np.random.randn(N,D_out)
#定義從神經網絡輸出的的數據矩陣,大小爲64*10
w_1=np.random.randn(D_in,H)
#大小爲1000*100
w_2=np.random.randn(H,D_out)
#大小爲100*10

#定義學習率 learning rate
learning_rate=1e-06
for it in range(500):
    #forword pass
    h=x.dot(w_1)
    #numpy中的點乘np.dot是數學意義上的向量內積
    #print(h.shape)
    #打印矩陣維度信息
    h_relu=np.maximum(h,0)
    #定義relu 函數,是目前深度神經網絡中經常使用的激活函數。
    y_hat=h_relu.dot(w_2)
    #大小爲64*10

    #計算損失compute loss
    loss=np.square(y_hat-y).sum()
    #估計值與真實值之間差值的平方和再取和
    print(it,loss)

    #計算梯度,主要是對(y_hat-y)^2求各項偏導
    y_hat_grad=2*(y_hat-y)
    w_2_grad=h_relu.T.dot(y_hat_grad)
    h_relu_grad=y_hat_grad.dot(w_2.T)
    h_grad=h_relu_grad.copy()
    h_grad[h<0]=0
    w_1_grad=x.T.dot(h_grad)

    #更新w_1和w_2的權值
    w_1=w_1-learning_rate*w_1_grad
    w_2=w_2-learning_rate*w_2_grad

這裏需要說明的一點就是在計算各參數的梯度問題時,是在估計值與真實值之間差值的平方的基礎上進行求偏導的,我們令其爲A,則有:
A=(y^y)2 A=(\hat{y}-y)^2
易得:
Ay^=2(y^y) \frac{\partial{A}}{\partial{\hat{y}}}=2\cdot(\hat{y}-y)
後面幾個偏導的計算就很容易寫錯了:
Aw2=aTAy^ \frac{\partial{A}}{\partial{w_2}}=a^T\cdot\frac{\partial{A}}{\partial{\hat{y}}}
Aa=Ay^w2T \frac{\partial{A}}{\partial{a}}=\frac{\partial{A}}{\partial{\hat{y}}}\cdot w_2^T
因爲a=max(0,h)a=max(0,h),則有:
a=max(0,h)={hh00h<0 a=max(0,h)=\left\{\begin{aligned}h \qquad h\geq0 \\ 0 \qquad h<0\\ \end{aligned}\right.
所以對h求偏導則有:
Ah={Aa1h0Aa0h<0 \frac{\partial{A}}{\partial{h}}=\left\{\begin{aligned} {\frac{\partial{A}}{\partial{a}} } \cdot1 \qquad h\geq0 \\ {\frac{\partial{A}}{\partial{a}} }\cdot0 \qquad h<0\\ \end{aligned}\right.
最後我們再對w_1求偏導:
Aw1=xTAh \frac{\partial{A}}{\partial{w_1}}=x^T\cdot\frac{\partial{A}}{\partial{h}}
有了上邊的推導,相信大家很容易就理解代碼了吧。嘿嘿嘿

3.結果測試

在這裏插入圖片描述
在結果中我們可以看到,在程序剛開始時和程序結束時的loss值有了明顯減小:

程序開始時loss值 程序結束時loss值
在這裏插入圖片描述 在這裏插入圖片描述

可以看到程序在訓練了500次的情況下,我們的這個兩層的神經網絡效果還是比較不錯的。接下來我也將會繼續將該模型改寫爲torch版本的。

4.參考文章

1.【Code】numpy、pytorch實現全連接神經網絡

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章