日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

机器学习之五:神经网络、反向传播算法推导

發布時間:2024/6/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习之五:神经网络、反向传播算法推导 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、邏輯回歸的局限

在邏輯回歸一節中,使用邏輯回歸的多分類,實現了識別20*20的圖片上的數字。

但所使用的是一個一階的模型,并沒有使用多項式,為什么?

可以設想一下,在原有400個特征的數據樣本中,增加二次、三次、四次多項式,會是什么情形?

很顯然,訓練樣本的特征數量將會拔高多個數量級,而且,更重要的,要在一個式子中擬合這么多的特征,其難度是非常大的,可能無法收斂到一個比較理想的狀態。

也就是說,邏輯回歸沒法提供很復雜的模型。

因為其本質上是一個線性的分類器,擅長解決的是線性可分的問題。

那么非線性可分問題,要怎么解決?

解決思路

如果有一種方法,將非線性可分問題先進行特征提取,變為接近線性可分,那么再應用一次邏輯回歸,是否就能解決非線性問題了?

這便是神經網絡的思想。

二、神經網絡

1、結構

神經網絡的結構,如下圖所示




上面是一個最簡單的模型,分為三層:輸入層、隱藏層、輸出層。

其中,隱藏層可以是多層結構,通過擴展隱藏層的結構,可以構建更得雜的模型,例如下面的模型:




每一層的輸出,皆是下一層的輸出,層層連接而成,形成一個網絡。

網絡中的節點,稱為神經元。每個神經元,其實就是進行一次類似邏輯回歸的運算(之所以說是"類似",是因為可以使用邏輯回歸,也有別的算法代替,但可以使用邏邏回歸來理解它的運算機理)。

根據上面前言中的分析,顯然,隱藏層是進行特征的提取,而輸出層,其實就是進行邏輯回歸。

為何說隱藏層是進行特征提取?

為方便理解,這里假設所有神經元執行邏輯回歸。

一次邏輯回歸,可以將平面一分為二。神經網絡中,執行的是 N 多個邏輯回歸,那么可以將平面切割為 N 多個區域,這些區域最后由輸出層進行綜合后做為結果。

如果只關注輸出層,那么這些前面切割出來的區域,其實可以當作是一種特征,是一種更高級的特征,由原始樣本提取出來的。這就是特征的提取。

2、計算原理

2.1 前向傳播,計算輸出

下面求解當一個樣本從輸入層輸入時,如何得到最終結果。

假設每個神經元,都執行邏輯回歸的計算,則第 \(i\) 層網絡的輸出為:\[a^{(i)} = g(z^{(i)}) = g(\Theta^Ta^{(i-1)}) \tag{1}\]

以如下三層網絡為例:




各層的輸入輸出如下:

Input layer:

\[ a^{(1)} = x \]
Hidden layer:

\[ \begin{split} z^{(2)} &= \Theta^{(1)}a^{(1)} \\ a^{(2)} &= g(z^{(2)}) \end{split} \]
Output layer:

\[ \begin{split} z^{(3)} &= \Theta^{(2)}a^{(2)} \\ a^{(3)} &= g(z^{(2)}) \end{split} \]

即整個網絡的最終結果為:

\[ h_\theta(x) = a^{(3)} \]

上述流程:以上一層的輸出,作為下一層的輸入,一層一層疊加運算后,得到最終的輸出,這個計算方法,稱為“前向傳播”

2.2 反向傳播,求theta矩陣

訓練算法的目的是“求取使得誤差函數最小化的參數矩陣”,用梯度下降法處理最小化誤差,需要計算誤差函數J、以及J對theta的偏導數。

2.2.1 誤差函數J

\[ J(\Theta) = -\frac{1}{m} \sum_{i=1}^{m}\sum_{k=1}^{K}[y_k^{(i)}log(h_\Theta(x^{(i)}))_k + (1-y_k^{(i)})log(1-h_\theta(x^{(i)}))_k] + \frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{S_l}\sum_{j=1}^{S_l+1}(\Theta_{ji}^{(l)})^2 \tag{2} \]

其中 \(K\) 為輸出層的單元數,即類別數。在計算誤差的時候,需要將每一類都計算進去。后面的正則項是整個神經網絡中所有的參數 \(\Theta\) 的值之和。

2.2.2 J對theta偏導數

這里先給結果,后面再做推導:

\[ \frac{\partial}{\partial\Theta_{ij}^{(l)}}J(\Theta) = \frac{1}{m}\sum_{t=1}^{m}\delta_i^{(t)(l+1)}a_j^{(t)(l)} + \frac{\lambda}{m}\sum_{l=1}^{L-1}\sum_{i=1}^{S_l}\sum_{j=1}^{S_l+1}(\Theta_{ji}^{(l)}) \tag{3} \]

其中

\[ \begin{cases} \delta^{(L)} &=& a^{(L)}-y \\ \\ \delta^{(l)} &=& \delta^{(l+1)}*(\Theta^{(l+1)})^T*g'(z^{(l)}) \\ \\ \delta^{(0)} &=& 0 \\ \end{cases} \tag{4} \]

上述公式描述的內容

\(l\) 層的誤差,可以通過第 \(l+1\) 層的誤差計算出來,而最后一層的誤差,就是系統通過前向傳播計算出的值與樣本 \(Y\) 值的差。
也就是說,從輸出層開始,各層誤差能通過一層一層反向迭代的方式得到,確定誤差之后,偏導數便也隨之計算出來,進而可進行模型的調整。這就是,“反向傳播算法”

而反向傳播的內容,其實是誤差。

  • 關于誤差的直觀理解:

輸出層的誤差,即為系統的總誤差;

中間層的誤差,即為每一層對總誤差的貢獻值(所以,\(\theta\) 矩陣,在前向傳播中,是特征權重,而在反向傳播中,就是誤差權重);

而輸入層,其輸出即為原始數據,即無誤差。

2.2.3 反向傳播算法的推導過程

(1) 第一部分,推導偏導數

上面給出了反向傳播的結論,以下進行推導。

矩陣形式計算第 \(l\) 層的偏導數:

\[ \begin{split} \frac{\partial J(\Theta)}{\partial\Theta^{(l)}} &= \frac{\partial J(\Theta)}{\partial z^{(l+1)}} * \frac{\partial z^{(l+1)}}{\partial \Theta^{(l)}} \\ \\ &= \frac{\partial J(\Theta)}{\partial z^{(l+1)}} * \frac{\partial (\Theta^{(l)}*a^{(l)})}{\partial \Theta^{(l)}} \\ \\ &= \frac{\partial J(\Theta)}{\partial z^{(l+1)}} * a^{(l)} \end{split} \tag{5} \]

\[\delta^{(l)} = \frac{\partial J(\Theta)}{\partial z^{(l)}} \tag{6}\]

則有

\[ \begin{split} \frac{\partial J(\Theta)}{\partial\Theta^{(l)}} &=& \frac{\partial J(\Theta)}{\partial z^{(l+1)}} * a^{(l)} \\ \\ &=& \delta^{(l+1)} * a^{(l)} \\ \end{split} \tag{7} \]

(2) 第二部分,推導誤差delta

上面推導過程中,有這個式子:

\[ \delta^{(l)} = \frac{\partial J(\Theta)}{\partial z^{(l)}} \]

表示了什么意思?下面分別從輸出層、及中間層來推導、解釋這個式子。

  • 輸出層

因誤差函數如下(這里省略掉正則項)

\[ J(\Theta) = -\frac{1}{m} \sum_{i=1}^{m}\sum_{k=1}^{K}[y_k^{(i)}log(h_\Theta(x^{(i)}))_k + (1-y_k^{(i)})log(1-h_\theta(x^{(i)}))_k] \]

此式表達的是總誤差,那么,對于輸出層的每個神經元的誤差,可用矩陣表示為:

\[ C = - [ylog(h_\Theta(x)) + (1-y)log(1-h_\theta(x))] \tag{8} \]

故輸出層的誤差為:

\[ \begin{split} \delta^{(L)} &=& \frac{\partial J(\Theta)}{\partial z^{(L)}} = \frac{\partial C}{\partial z^{(L)}} \\ \\ &=& \frac{\partial }{\partial z^{(L)}} [ylog(h_\Theta(x)) + (1-y)log(1-h_\theta(x))] \\ \\ &=& -\frac{y}{g(z^{(L)})}g'(z^{(L)}) - \frac{1-y}{1-g(z^{(L)})}(-g'(z^{(L)})) \\ \\ &=& \frac{g(z^{(L)})-y}{g(z^{(L)})(1-g(z^{(L)}))}(g'(z^{(L)})) \\ \\ &=& g(z^{(L)})-y \\ \\ &=& a^{(L)}-y \end{split} \tag{9} \]

這個結果,有點意思了,表示出輸層的 \(\delta\) 值,就是系統輸出值與樣本 \(Y\) 值的差。所以,我們稱 \(\delta\) 為神經系統各層結構的各個神經元的誤差。

  • 中間層誤差推導

對于第 \(l\)

\[ \begin{split} \delta^{(l)} &=& \frac{\partial J(\Theta)}{\partial z^{(l)}} \\ \\ &=& \frac{\partial J(\Theta)}{\partial z^{(l+1)}} * \frac{\partial z^{(l+1)}}{\partial z^{(l)}} \\ \\ &=& \delta^{(l+1)} * \frac{\partial [(\Theta^{(l+1)})^T*g(z^{(l)})]}{\partial z^{(l)}} \\ \\ &=& \delta^{(l+1)} * (\Theta^{(l+1)})^T*g'(z^{(l)}) \\ \end{split} \tag{10}\]

即第 \(l\) 層的誤差,能用第 \(l+1\) 層的誤差計算得到,與先前所定的結論完全一致。

這就是反向傳播的所有推導的內容。

三、程序實現

例子來源于,吳恩達的機器學習編程題。樣本與邏輯回歸中的多分類的數字識別相同。

1、計算損失函數、及梯度

function [J grad] = nnCostFunction(nn_params, ...input_layer_size, ...hidden_layer_size, ...num_labels, ...X, y, lambda) Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...hidden_layer_size, (input_layer_size + 1));Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...num_labels, (hidden_layer_size + 1));% Setup some useful variables m = size(X, 1);% You need to return the following variables correctly J = 0; Theta1_grad = zeros(size(Theta1)); Theta2_grad = zeros(size(Theta2));% ------ 前向傳播計算輸出 ------% input layer a1 = [ones(m, 1) X]; %add +1 to X; % hidden layer a2 = sigmoid(a1 * Theta1'); a2 = [ones(m, 1) a2]; % output layer a3 = sigmoid(a2 * Theta2');% ------ 樣本的Y值 ------ % [1 0 0 0 0 0 0 0 0 0] -- the value is 1 % [0 1 0 0 0 0 0 0 0 0] -- the value is 2 Y = zeros(m,num_labels); for i = 1 : mY(i,y(i)) = 1; end% ------ 損失函數J ------ J = (sum(sum(-Y .* log(a3))) - sum(sum((1-Y) .* log(1-a3)))) / m ; % remove theta0 t1 = Theta1(:,2:end); t2 = Theta2(:,2:end); regularize = lambda / 2 / m * (sum(sum(t1.^2)) + sum(sum(t2.^2))); J = J + regularize;% ------ 反向傳播計算各層誤差 ------ delta3 = a3 - Y; delta2 = delta3 * Theta2 .* a2 .* (1 - a2); delta2 = delta2(:,2:end);% ------ 計算梯度 ------ Theta1_grad = ( delta2' * a1 + [zeros(size(t1,1),1) t1] * lambda) / m; Theta2_grad = ( delta3' * a2 + [zeros(size(t2,1),1) t2] * lambda) / m;% Unroll gradients grad = [Theta1_grad(:) ; Theta2_grad(:)];end

2、前向傳播及計算delta中,需要用到sigmoid函數及其導數

2.1 sigmoid函數

function g = sigmoid(z) g = 1.0 ./ (1.0 + exp(-z)); end

2.2 sigmoid函數的導數

function g = sigmoidGradient(z) g = sigmoid(z) .* (1 - sigmoid(z)); end

3、訓練過程

3.1、隨機初始化theta參數矩陣

initial_Theta1 = randInitializeWeights(input_layer_size, hidden_layer_size); initial_Theta2 = randInitializeWeights(hidden_layer_size, num_labels);% Unroll parameters initial_nn_params = [initial_Theta1(:) ; initial_Theta2(:)];

邏輯回歸中,theta矩陣可以初始化為同一個值,如全0或全1。但神經網絡中卻不行。

原因在于:神經網絡中,神經元是以全連接的形式組織起來的,即n-1層的任意一個節點,都與第n層所有節點相連接。

若是初始化時theta矩陣初始化為同一個值,同一個層的每一個神經元都進行相同的運算,多個神經元進行相同的運算,這對于數據的擬合沒有任何用處,只是浪費資源,造成冗余。此為對稱現象。

隨機初始化參數的實現如下:

function W = randInitializeWeights(L_in, L_out) W = zeros(L_out, 1 + L_in); epsilon_init = 0.12; W = rand(L_out, 1 + L_in) * 2 * epsilon_init - epsilon_init; end

3.2、初始化參數

options = optimset('MaxIter', 100);% 正則項參數 lambda = 1;% 損失函數 costFunction = @(p) nnCostFunction(p, ...input_layer_size, ...hidden_layer_size, ...num_labels, X, y, lambda); % 梯度下降計算參數 [nn_params, cost] = fmincg(costFunction, initial_nn_params, options);% 獲取兩層神經網絡的參數 Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...hidden_layer_size, (input_layer_size + 1));Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...num_labels, (hidden_layer_size + 1));

4、預測

pred = predict(Theta1, Theta2, X);fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);

可以看到,其預測結果,比邏輯回歸準確率高接近3個點。

原因在于:神經網絡所能構建的模型,比邏輯回歸更為復雜,其對數據的擬合能力也更強。

predict函數,使用訓練得到的參數矩陣,前向傳播計算得到結果即為輸出層,輸出層表示一個輸入樣本經過經神網絡計算之后,其可能屬于各個分類的概率值。與邏輯回歸類似,取最大值即為最終的結果。

function p = predict(Theta1, Theta2, X)m = size(X, 1); num_labels = size(Theta2, 1);p = zeros(size(X, 1), 1);h1 = sigmoid([ones(m, 1) X] * Theta1'); h2 = sigmoid([ones(m, 1) h1] * Theta2'); [dummy, p] = max(h2, [], 2);end

轉載于:https://www.cnblogs.com/Fordestiny/p/8819978.html

總結

以上是生活随笔為你收集整理的机器学习之五:神经网络、反向传播算法推导的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。