前饋神經網絡基本原理及兩層ReLU網絡的Pytorch實現(xiàn)

1 神經元

神經元是構成神經網絡的基本單元,接受一組輸入信號并產生輸出

1.1 基本機制

接收一個列向量輸入X=[x_1, x_2,\cdot\cdot\cdot, x_d]^T,通過下列表達式產生凈輸出z

z =W^TX + b

  • 行向量\omega = [\omega_1,\omega_2, \cdot\cdot\cdot,\omega_d]為權重向量
  • b為偏置

凈輸入z通過激活函數f(\cdot),得到輸入為X時該神經元的活性值a

a = f(z)
圖示

神經元的基本結構圖示

1.2 激活函數

1.2.1 為什么需要激活函數?

神經網絡屬于非線性分類。當輸入X與權重W及偏置b經過線性組合之后得到凈輸出z,如果沒有激活函數對凈輸出z的處理,那么不管有多少神經元最后得到的輸出仍然是線性輸出,這也就是為什么感知機無法處理XOR(異或)問題的原因。而經非線性的激活函數的處理之后,神經網絡得以解決這一問題。

1.2.2 激活函數的特征
  • 連續(xù)并可導的非線性函數,連續(xù):每一個凈輸入則產生對應的活性值;可導:只有有限個點不可導,則可以使用數值優(yōu)化的方法(如梯度下降)訓練網絡。
  • 激活函數的導數的值域要處于一個合適的區(qū)間,因為這將影響訓練的效率及穩(wěn)定性。
1.2.3 兩種典型的激活函數

Logistic函數

\sigma(x) = \frac{1}{1+e^{(-x)}}

  • 輸入越小,越接近于0;輸入越大,越接近1
  • 輸出值直接可以視作概率分布

ReLU函數

ReLU(x)=\left\{\begin{array}{l}{x,x \geqslant 0} \\ {0,else}\end{array}\right.

  • x \geqslant 0時,導數為1,有利于加速梯度下降的收斂
  • 一定程度上緩解了神經網絡的梯度消失問題

2 網絡結構

網絡中各個神經元根據接受信息的先后分為不同的組別,每一組視為一個神經層。每一層的神經元接受前一層神經元的輸出,并輸出到下一層神經元。整個網絡的信息從輸入端朝輸出端傳播,不存在反向的信息傳播。網絡結構可使用一個有向無環(huán)圖表示,整個網絡可以視作一個非線性函數,實現(xiàn)從輸入到輸出的復雜映射。

2.1 結構組成

共分為三大層,第0層:輸入層;最后一層:輸出層;其他中間層:隱藏層

一個三層的前饋神經網絡
  • L:神經網絡的層數
  • m^{(l)}:第l層神經元的個數
  • f_{l}(\cdot):第l層神經元的激活函數
  • W^{(l)} \in \mathbb{R}^{m^{(l)} \times m^{l-1}}l ? 1 層到第 l 層的權重矩陣
  • \mathbf^{(l)} \in \mathbb{R}^{m^{l}}l 層神經元的凈輸入
  • \mathbf{a}^{(l)} \in \mathbb{R}^{m^{l}}:表示 l 層神經元的輸出(活性值)

3 反向傳播算法

為了訓練參數,最小化損失函數\mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})??刹捎锰荻认陆担ㄍㄟ^計算損失函數\mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})對參數的偏導數,不斷迭代使得損失函數最小化)等算法。而梯度下降需要對每一個參數求解偏導,效率低下。故誕生了反向傳播算法

3.1 算法思路

  1. 前饋計算每一層的凈輸入與輸出(活性值)
  2. 反向傳播計算每一層的誤差項\frac{\partial \mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})}{\partial \mathbf{z}^{(l)}}(表示第l層的神經元對損失函數的影響)
  3. 計算每一層關于參數的偏導數,并更新參數

3.2 數學原理

根據鏈式求導法則,可令損失函數\mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})對權重及偏置的偏導數分別如下

\frac{\partial \mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})}{\partial W^{(l)}}=\frac{\partial \mathbf{z}^{(l)}}{\partial W^{(l)}} \delta^{(l)}
\frac{\partial \mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})}{\partial \mathbf^{(l)}}=\frac{\partial \mathbf{z}^{(l)}}{\partial \mathbf^{(l)}} \delta^{(l)}

  • 其中\frac{\partial \mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})}{\partial \mathbf^{(l)}}=\delta^{(l)}

由上列表達式可只,想要求損失函數對于第l層的神經元的偏導可以通過求解\frac{\partial \mathbf{z}^{(l)}}{\partial W^{(l)}}, \frac{\partial \mathbf{z}^{(l)}}{\partial \mathbf^{(l)}}\delta^{(l)}可一次性求得。

  • \frac{\partial \mathbf{z}^{(l)}}{\partial W^{(l)}} = \left(\mathbf{a}^{(l-1)}\right)^{\mathrm{T}}
  • \frac{\partial \mathbf{z}^{(l)}}{\partial \mathbf^{(l)}}=\mathbf{I}_{m^{(l)}} \in \mathbb{R}^{m^{(l)} \times m^{(l)}}
  • \delta^{(l)}=f_{l}^{\prime}\left(\mathbf{z}^{(l)}\right) \odot\left(\left(W^{(l+1)}\right)^{\mathrm{T}} \delta^{(l+1)}\right)

\mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})關于第 l 層權重 W^{(l)}的梯度為
\frac{\partial \mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})}{\partial W^{(l)}}=\delta^{(l)}\left(\mathbf{a}^{(l-1)}\right)^{\mathrm{T}}
\mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})關于第 l 層權重 \mathbf^{(l)}的梯度為\frac{\partial \mathcal{L}(\mathbf{y}, \hat{\mathbf{y}})}{\partial \mathbf^{(l)}}=\delta^{(l)}
其中\delta^{(l)}=f_{l}^{\prime}\left(\mathbf{z}^{(l)}\right) \odot\left(\left(W^{(l+1)}\right)^{\mathrm{T}} \delta^{(l+1)}\right)\odot代表點積)


4 自動微分

在以計算機中,一種求解導數的精確且方便的計算方式。通過鏈式法則將復雜的表達式拆分成更簡單而精確的形式。

f(x;\omega,b) = \frac{1}{e^{-(\omega x+b)}+1}
求解過程:

  • h_{1}=x \times w
  • h_{2}=h_{1}+b
  • h_{3}=h_{2} \times-1
  • h_{4}=e^ \left(h_{3}\right)
  • h_{5}=h_{4}+1
  • h_{6}=1 / h_{5}
  1. 求得上述表達式偏導數
  • \frac{\partial h_{1}}{\partial w}=x \qquad \frac{\partial h_{1}}{\partial x}=w
  • \frac{\partial h_{2}}{\partial h_{1}}=1 \qquad \frac{\partial h_{2}}{\partial b}=1
  • \frac{\partial h_{3}}{\partial h_{2}}=-1
  • \frac{\partial h_{4}}{\partial h_{3}}=e^ \left(h_{3}\right)
  • \frac{\partial h_{5}}{\partial h_{4}}=1
  • \frac{\partial h_{6}}{\partial h_{5}}=-\frac{1}{h_{5}^{2}}

\begin{aligned} \frac{\partial f(x ; w, b)}{\partial w} &=\frac{\partial f(x ; w, b)}{\partial h_{6}} \frac{\partial h_{6}}{\partial h_{5}} \frac{\partial h_{5}}{\partial h_{4}} \frac{\partial h_{4}}{\partial h_{3}} \frac{\partial h_{3}}{\partial h_{2}} \frac{\partial h_{2}}{\partial h_{1}} \frac{\partial h_{1}}{\partial w} \\ \frac{\partial f(x ; w, b)}{\partial b} &=\frac{\partial f(x ; w, b)}{\partial h_{6}} \frac{\partial h_{6}}{\partial h_{5}} \frac{\partial h_{5}}{\partial h_{4}} \frac{\partial h_{4}}{\partial h_{3}} \frac{\partial h_{3}}{\partial h_{2}} \frac{\partial h_{2}}{\partial b} \end{aligned}


5 優(yōu)化

在訓練神經網絡時,有兩大問題難以解決:

  • 非凸優(yōu)化(容易陷入局部最優(yōu)解)
  • 梯度消失(參數學習停止)

6 兩層ReLU網絡的Pytorch實現(xiàn)

6.1 Code

導入Pytorch框架
import torch
import torch.nn as nn
import torch.nn.functional as F

from matplotlib import pyplot as plt
網絡實現(xiàn)
class Net(nn.Module):
    
    def __init__(self, n_input, n_hidden, n_output):
        super(Net, self).__init__()
        # 定義層的形式
        self.hidden = torch.nn.Linear(n_input, n_hidden)
        self.output = torch.nn.Linear(n_hidden, n_output)
    
    def forward(self, x):
        # 隱藏層輸出
        hidden = F.relu(self.hidden(x))
        # 輸出層
        y_predict = self.output(hidden)
        return y_predict
    
    def train(self, x, y, learning_rate, train_num):
        # 優(yōu)化器
        optimizer = torch.optim.SGD(self.parameters(), learning_rate)
        # 損失函數,均方差
        loss_func = torch.nn.MSELoss()
        # 迭代訓練
        for i in range(train_num):
            # 預測
            y_predict = self(x)
            # 計算誤差
            loss = loss_func(y_predict, y)
            # 情況上一次參與更新值
            optimizer.zero_grad()
            # 計算反向傳播
            loss.backward()
            # 更新參數
            optimizer.step()
            print(str(i) + "----->" + "loss:" + str(loss.data.numpy()))

6.2 擬合曲線y=\sin x效果(學習率:0.1)

訓練數據擬合
測試數據擬合
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容