1. 程式人生 > >神經網路二之神經網路反向傳播原理與python程式設計實現

神經網路二之神經網路反向傳播原理與python程式設計實現

技術交流qq群: 659201069

誤差

  樣本資料的真實值與神經網路的輸出值之間的差值稱為誤差,當然一般不會直接使用直接的差值,常用的有迴歸演算法的均方差、分類的交叉熵,這方面不影響我們來討論神經網路的反向傳播原理與過程,所以不做過多討論。

梯度下降

  目前的神經網路層數可達百層以上,啟用函式又是非線性的,很難用一個數學表示式來表達整個神經網路的輸出,即使能夠找一個數學表示式也是非常複雜,如果能夠找到一個數學表示式我們就可以用求解方程的形式推匯出引數矩陣W(每個一個,可以多達百個),當然這是不太可能實現的。我們看下下面的一個簡單的三層神經網路:
  這裡寫圖片描述
  第三層第k個節點的輸出表達式如下(自己可以根據前向傳播原理推導下,可以參考我的上一篇文章講的很清楚

https://blog.csdn.net/zhaojianting/article/details/80541732):
這裡寫圖片描述
  感覺是不是太複雜了,這只是三層的,按照目前百層網路,輸出如果用一個表示式來表達我相信沒有能看懂,或者說不可能用計算機來實現。所以後來人就改變了思路,神經網路的訓練(或者說優化)就是找到各層引數矩陣讓樣本的經過神經網路的輸出儘可能得接近真實值。這樣問題就轉變成了差誤最小化問題(理想誤差為0)。上面已經說了神經網路的輸出不可能通過求解方程的方法獲得,那麼我們也不可能通過令誤差等於0,然後求方程來獲得。這樣數學家(我猜得也可能是計算機專家)發明的類似於列舉的梯度下降演算法(其它應該是貪心演算法),梯度下降演算法的原理大致是:首先隨機初始化每層的引數矩陣w,然後可以算得與真實值的誤差(第一次誤差應該很大,當然也可能你運氣好,初始化的W就達到了你的要求),因為是求最小值,我們就沿著梯度下降的方向加一個小步長(求偏導乘以一個常,在二維平面上w有可能左移或右移)*△w*
,用新的w+△w再計算誤差值,如此迭代下去就可以得到區域性最優解(為什麼是局總而不是全域性最優,下面會討論),看下面的一個例子假設誤差y=(x-1)**2+1,影象如下:
  這裡寫圖片描述

  上面的只有一個谷底可以接近全域性最優,如果有兩個(當然可是以多個)谷底的情況,這個能不能得到全域性最優和初化始值及每次變動的△w(這個是學習率,也就是設定的一個常數,此處不做過多討論)有關,第一種情部如果初始化值落在較低的谷底附近而學習率不是很大,每次變動都跳不出谷底就可以快速接近全域性最優(下圖左),第二種情況如果初始化值落在較高的谷底附近而學習率不是很大,每次變動都跳不出谷底,那隻能得到區域性最優(下圖中),第三種情況如果初始化值落在較低的谷底附近而學習率較大,其中有一次變動跳出了較高的谷底,那麼也是可以接近全域性最優(下圖右)
  這裡寫圖片描述

誤差的反向傳播

  上面討論的根據誤差,用梯度下降的方法也只能適應於更新一個引數的值,多層神經網路只有最後一層有誤差,中間隱藏層的w引數矩陣如衛生間更新呢,這就是要討論的重點,誤差的反向傳播,慢慢來不要急,我們先看下面最簡單的一個神經網路(先不考慮啟用函式,其原理是一樣的):
  這裡寫圖片描述
  根據上面的原理我們很容易求很每次更新的△w=L(E/x) 其中E是樣本產生的誤差,L是上面提到的學習率。下面看稍微複雜點的情況:

這裡寫圖片描述

  我們上面只有一個誤差E,怎麼根據公式△w=L(E/x) 更新兩個引數呢,如果都採用E來計算,顯然不合理,一般的做法的就是按照W1和W2的比例分隔誤差(這是誤差反向傳播的第一步),如下圖所示:
  這裡寫圖片描述
  這樣就有:
  △w1=L(E1/x1)
  △w2=L(E2/x2)

  下面我們看多層神經網路誤差的反向傳播過程:
這裡寫圖片描述
  根據上面的討論我們很容易得到隱藏層到輸出層的引數矩陣
這裡寫圖片描述
  要想計算輸入層到到隱藏層的誤差我們需要隱藏層的輸出誤差,但隱藏層實際上是沒有輸出誤差的,這就需要我們造出來,也就是從輸出層先分隔再重組,計算公式如下(一看就能明白)
這裡寫圖片描述
  這樣我們就得了隱藏層的誤差,接下來我們就可以按照上面介紹計算輸入層到隱藏層的引數更新步長了:
這裡寫圖片描述
  上面就是神經網路模型優化的核心思想,反向傳播,也就是誤差的反向傳播來更新各個引數。根據上面的反向傳播原理,無論神經網路有多少層,每層有多少個結點都是適用的。

向矩陣運算的轉化(將計算向量化)

  還是利用上面的神經網路舉例,但計算方式可以推廣到多層神經網路:

  第一步:誤差向量化
這裡寫圖片描述
  第二步:隱藏層誤差向量化

  自己按照矩陣乘法算一下,正好可以得到下面的一個1行2列的矩陣(就是這麼巧合,如果沒有巧合百層神經網也就不會出現了)
  這裡寫圖片描述
  到現在我們可以根據上面的公式計算隱藏層的誤差的,但是上面的表示式可以進一步簡化(能把複雜問題簡單化的都是創舉,在工作中遇到過不少裝B貨,明明很簡單的幾行程式碼就可以解決的問題非要寫得上成百上千行結果BUG也是成百上千。鄙人追求的目標就是用最單的方式解決複雜的問題,因為越簡單越容易受控,自然而然就越穩定,扯遠了…………這年頭生活壓力都不小,很少有機會發發牢騷!),其它我們分析下分母只是起到了歸一化的作用我們完全可以捨棄,最後就變成了如下的形式
  這裡寫圖片描述
 最終隱藏層的誤差表示式:
 這裡寫圖片描述
 到目前為止我們已經完成了一大半,我們已經把輸出層誤差、引數、隱藏層誤差實現了向量化,但是我們還沒有完成最重要最核心的目標就是求得各個引數矩陣的更新步長:△W

  第三步:偏導公式推導,完成最終求解這裡寫圖片描述,這裡W是大代表的是第j層和k層的引數矩陣,我們上面的推導為了徹底講解原理,都是用的三層神經網路,而且每個節點的輸出沒有應用啟用函式。從現在開始我們的推導基於多層,帶啟用函式的神經網路,最後形成的公式對所有的全連線神經網路都適用。
  對只有一層且只有一個神經元的網路,我們有△w=L(E/x) ,這裡L是設定的學習率,而E/x是誤差函式對w的導數,現在我們就自然而然的推廣到一般情況(這裡我們的誤差採用輸出結點誤差的平方和,其它的也是一樣的),我們先只考慮輸出層的公式推導:
  這裡寫圖片描述
  我們的偏導就可以寫出來了:
  這裡寫圖片描述
  這個是輸出層各個節點的誤碼差的平方各。這個表示式是需要求和的,我們能不能簡化下呢,我們再看下神經網路的結構圖,節點k的輸出這裡寫圖片描述只取決於連線到這個節點的權重,也就是隻取決於這裡寫圖片描述,不依賴於這裡寫圖片描述,因為b和k之間沒有連線,因此b與k無關聯,這裡寫圖片描述是輸出層第b個節點的連線權重。這樣我們就可以捨棄除了這裡寫圖片描述所連線的這裡寫圖片描述外的所有其它的這裡寫圖片描述,於是我們得到了下面的公式,也就是根本不用求和:
這裡寫圖片描述
  我們利用微積分進行分解(這個如果你不懂我也沒辦法,當然也不需要懂,因為根本不用推導,我們只是看懂原理使用罷了):
  這裡寫圖片描述
  我們再把E的表示式這裡寫圖片描述代入上式可以得到:
  這裡寫圖片描述
  根據前向傳播原理,我們把這裡寫圖片描述代入上式可以得到:
  這裡寫圖片描述
  現在只剩下一個sigmoid微分函式,這個函式的微分我們自己是推不出來的,可以說現在常用的啟用函式我們基本上也都是求不微分的(因為一個微分函式可能是一個數學家一輩子的成果),但是數學家們幫我們推導好的,我們直接查表拿來用就是了:
  ,這裡寫圖片描述
  於是我們得到下面的公式:
這裡寫圖片描述
  別忘了我們要求的是斜率,最前面的2是可以去除的,因為我們自己會設定一個學習率的,於是得到下面的結果:
這裡寫圖片描述
  上面的公式可以直接用來更新隱藏層到輸出層的引數,那麼前面的引數怎麼更新呢?其實很簡單,我們只要把輸出和引數換成前一層的就可以的,也就是上面所討論的反向傳播,把誤差就成隱藏層誤差就可以了,現在要把這個計算過程轉化為矩陣運算,推導過程和上面的誤差傳播是一樣的,最後可以得到如一下矩陣運算公式:
  
  這裡寫圖片描述
  到此就全部講解了神經網張的反向傳播過程,神經網路訓練的過程就是通多次迭代更新引數的過程。下面我們看下ptyhon實現反向傳的程式碼:
  

    # 神經網路模型訓練
    def train(self, inputs_list, targets_list):

        #注意維度,輸入是[[1],[2]],還是[[1,2]]引數矩的寫法也是不一親的,
        #這個可以自己定,只要保證輸放和引數矩陣的維度對應即可,一般的寫法是第二種
        inputs = numpy.array(inputs_list, ndmin=2).T
        targets = numpy.array(targets_list, ndmin=2).T

        # 計算隱藏層輸出
        hidden_inputs = numpy.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)#啟用函式,現在用的較多的是relu

        # 隱藏層到輸出層的傳播
        final_inputs = numpy.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)

        # 下面兩行就是計算隱藏層的誤差,也就是上面討論的誤差的反向傳播
        output_errors = targets - final_outputs
        hidden_errors = numpy.dot(self.who.T, output_errors)

        # 下面兩步是最重要的也就是實現我們上面推導的最後的公式,自己對比下,正好是對應的
        self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)),
                                        numpy.transpose(hidden_outputs))

        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),
                                        numpy.transpose(inputs))

        pass

相關推薦

神經網路神經網路反向傳播原理python程式設計實現

技術交流qq群: 659201069 誤差   樣本資料的真實值與神經網路的輸出值之間的差值稱為誤差,當然一般不會直接使用直接的差值,常用的有迴歸演算法的均方差、分類的交叉熵,這方面不影響我們來討論神經網路的反向傳播原理與過程,所以不做過多討論。

吳恩達機器學習筆記-神經網路的代價函式和反向傳播演算法

代價函式 在神經網路中,我們需要定義一些新的引數來表示代價函式。 L = total number of layers in the network $s_l$ = number of units (not counting bias unit) in layer

神經網路反向傳播演算法(backpropagation)的pytorch實現,pytorch教程中的程式碼解讀以及其他一些疑問解答

pytorch的官網上有一段教程,是使用python的numpy工具實現一個簡單的神經網路的bp演算法。下面先貼上自己的程式碼: import numpy as np N,D_in,H,D_out = 4,10,8,5 x = np.random.randn(N,D_i

神經網路神經網路結構原理以及python實戰

技術交流qq群: 659201069   本系列埔文由淺入深介紹神經網路相關知識,然後深入神經網路核心原理與技術,最後淺出python神經網路程式設計實戰。通過本系列博文,您將徹底理解神經網路的原理以及如何通過python開發可用於生產環境的程式。本博

機器學習神經網路):感知器的介紹和Python程式碼實現

前言:本篇博文主要介紹感知器的相關知識,採用理論+程式碼實踐的方式,進行感知器的學習。本文首先介紹感知器的模型,然後介紹感知器學習規則(Perceptron學習演算法),最後通過Python程式碼實現單層感知器,從而給讀者一個更加直觀的認識。 1.單層感知器模型 單層感知器

神經網路模型CNN網路架構

CNN網路架構 神經網路架構發展縱覽 從1998年開始,近18年來深度神經網路的架構發展情況如下: 上圖,橫座標是操作的複雜度,縱座標是精度。 模型設計一開始的時候模型權重越

機器學習數學系列()邏輯迴歸反向傳播數學推導

一、簡介   在深度學習領域,我們往往採用梯度下降(或上升)法來優化訓練函式模型,梯度下降法尤其是在優化凸函式上表現極佳。模型優化涉及到反向傳播過程,反向傳播過程需要先推匯出梯度計算公式然後利用機器進行代數運算。這篇博文的工作是詳細推導了邏輯迴歸反向傳播梯度計算公式(什麼是梯度?簡單來講

Android HTTP協議請求網路()HttpClient方式

1 package com.example.m04_http01; 2 3 import org.apache.http.HttpEntity; 4 import org.apache.http.HttpResponse; 5 import org.apache.http.client.HttpC

Volley網路框架快取載入圖片、Postget的資料請求

         前言:Volley作為主流網路框架之一,必然有它的優點。Volley可是說是把AsyncHttpClient和Universal-Image-Loader的優點集於了一身, 它的常用在資料量不大,但網路通訊頻繁,而且有圖片快取

網路請求urllib網路請求庫

urllib庫是Python中一個最基本的網路請求庫。可以模擬瀏覽器的行為,向指定的伺服器傳送一個請求,並可以儲存伺服器返回的資料。 urlopen函式: 在Python3的urllib庫中,所有和網路請求相關的方法,都被集到urllib.request模組下面了,以先來看下ur

無線通訊網路學習LTE網路架構篇(20141208)

今天來學習一下LTE的網路架構: 1.LTE網路架構簡化了既有通訊網路架構,並可以與其他IP網路進行通訊的無縫整合,使其成為扁平化的全IP網路架構(Falt-All-IP); 2.改網路主要由EPC(核心網)與E-UTRAN組成,通過其他傳輸介質接入其他通訊網路,如下圖所示

網路虛擬化FlowVisor—網路虛擬層(上)

概念解釋:切片:虛擬網路的一個例項 一. 網路虛擬化(虛擬網路) 人類社會的發展在很大方面得益於自然界,飛機受益於鳥,雷達受益於蝙蝠等等,所以專門有個學科為仿生學就是研究和模仿生物的特殊本質,利用生物的結構和功能原理來研製機械或各種新技術的科學技術。而人類社會已經發展

深度學習模型網路學習分類網路學習

1. VGG 作者團隊,發表時間 University of Oxford, ICLR-2015 文章解決的問題 提高分類準確率 解決的方案 只使用3x3的卷

網路攻防——常用網路掃描工具

netenum工具:一個很好用的IP段生成工具。可以用來檢視有哪些主機線上(這個工具的第二個功能的查詢結果不是特別準確,所以它的主要功能還是用來生成IP列表)。使用截圖如下 fping工具:常用格式:fping -g 123.58.180.0/24,用來進

深度學習:概率和反向傳播的變種

# 概率 ## 高斯分佈 ### 高斯分佈(Gaussian Distribution) 又叫**正態分佈(Normal Distribution)**, 記作$N(μ,σ^2)$,概率密度和為 1。 $$ P(x)=\frac{1}{\sqrt{2 \pi} \sigma} e^{-\frac{1}{

卷積層,池化層等,前向/反向傳播原理講解

簡單 代碼 構建 range expand 使用場景 神經網絡 右下角 body 今天閑來無事,考慮到以前都沒有好好研究過卷積層、池化層等等的前向/反向傳播的原理,所以今天就研究了一下,參考了一篇微信好文,講解如下: 參考鏈接:https://www.zybuluo.co

圖文+程式碼分析:caffe中全連線層、Pooling層、Relu層的反向傳播原理實現

1.全連線層反向傳播 設CC為loss 全連線層輸入:(bottom_data) aa 全連線層輸出:(top_data) zz 假設 aa維度K_, zz維度N_,則權值矩陣維度為N_行*K_列,batchsize=M_ 全連線層每個輸出zi=b+∑

最小乘法多項式曲線擬合原理實現 zz

博客 del p s 並且 多項式 聯網 python mar 程序 概念 最小二乘法多項式曲線擬合,根據給定的m個點,並不要求這條曲線精確地經過這些點,而是曲線y=f(x)的近似曲線y= φ(x)。 原理 [原理部分由個人根據互聯網上的資料進行總結,希望對大

【Unity遊戲開發】toluawrap文件的原理使用

nop 微信 attr hiera n) 接下來 system 作者 prim   本文內容轉載自:https://www.cnblogs.com/blueberryzzz/p/9672342.html 。非常感謝原作者慷慨地授權轉載,比心!@blueberryzzz

分享《深度學習TensorFlow:入門、原理進階實戰》PDF+源代碼

image pro 源代碼 代碼 復制 進階 com nag 分享圖片 下載:https://pan.baidu.com/s/1zI-pblJ5dEwjGVe-QQP9hQ 更多資料:http://blog.51cto.com/3215120 《深度學習之TensorFlo