1. 程式人生 > >簡單易懂的講解深度學習(入門系列之八)

簡單易懂的講解深度學習(入門系列之八)

神經網路也許是計算機計算的將來,一個瞭解它的好方法是用一個它可以解決的難題來說明。假設給出 500 個字元的程式碼段,您知道它們是C,C++,JAVA或Python。現在構造一個程式,來識別編寫這段程式碼的語言。一種解決方案是構造一個能夠學習識別這些語言的神經網路。

這篇分享就討論了神經網路的基本功能以及構造神經網路的方法,這樣就可以在編碼時應用它們了。根據一個簡化的統計,人腦由百億條神經組成 每條神經平均連結到其它幾千條神經。通過這種連結方式,神經可以收發不同數量的能量。神經的一個非常重要的功能是它們對能量的接受並不是立即作出響應,而是將它們累加起來,當這個累加的總和達到某個臨界閾值時,它們將它們自己的那部分能量傳送給其它的神經。大腦通過調節這些連結的數目和強度進行學習。儘管這是個生物行為的簡化描述。但同樣可以充分有力地被看作是神經網路的模型。

閾值邏輯單元(Threshold Logic UnitTLU

理解神經網路的第一步是從對抽象生物神經開始,並把重點放在閾值邏輯單元(TLU)這一特徵上。一個TLU是一個物件,它可以輸入一組加權係數的量,對它們進行求和,如果這個和達到或者超過了某個閾值,輸出一個量。讓我們用符號標註這些功能。

首先,有輸入值以及它們的權係數:X1, X2, ..., Xn W1, W2, ..., Wn。接著是求和計算出的Xi*Wi ,產生了激發層a,換一種方法表示:

a = (X1 * W1)+(X2 * W2)+...+(Xi * Wi)+...+ (Xn * Wn)

閾值稱為 theta。最後,輸出結果y。當

a >=theta y=1,反之y=0。請注意輸出可以是連續的,因為它也可以由一個squash 函式s(或sigma)判定,該函式的自變數是a,函式值在之間,y=s(a)

640?wx_fmt=png

圖 1. 閾值邏輯單元,帶有sigma 函式(頂部)和cutoff 函式(底部)

TLU 會分類,假設一個TLU 有兩個輸入值,它們的權係數等於1theta 值等於1.5。當這個TLU 輸入<0,0><0,1><1,0> <1,1> 時,它的輸出分別為0、0、0、1。TLU 將這些輸入分為兩組:組和組。就像懂得邏輯連線(布林運算AND)的人腦可以類似地將邏輯連線的句子分類那樣,

TLU 也懂得一點邏輯連線之類的東西。

TLU 能夠用幾何學上的解釋來闡明這種現象。它的四種可能輸入對應於笛卡爾圖的四個點。從等式X1*W1 + X2*W2 = theta,換句話說,也即TLU 轉換其分類行為的點開始,它的點都分佈在曲線X2 = -X1 + 1.5 上。這個方程的曲線將個可能的輸入分成了兩個對應於TLU 分類的區域。這是TLU 原理中更為普通的例項。在TLU 有任意數目的個輸入的情況下,一組可能的輸入對應於維空間中的一個點集。如果這些點可以被超平面———換句話說,對應於上面示例中的線的維的幾何外形切割,那麼就有一組權係數和一個閾值來定義其分類剛好與這個切割相匹配的TLU

TLU 的學習原理

既然 TLU 懂得分類,它們就知道素材。神經網路也可假定為可以學習。它們的學習機制是模仿大腦調節神經連結的原理。TLU 通過改變它的權係數和閾值來學習。實際上,從數學的觀點看,權係數閾值的特徵有點武斷。讓我們回想一下當SUM(Xi * Wi) >= theta TLU 在臨界點時輸出的是而不是0,這相當於說臨界點是出現在SUM(Xi * Wi)+ (-1 * theta) >= 0 的時候。所以,我們可以把-1 看成一個常量輸入,它的權係數theta 在學習(或者用技術術語,稱為培訓)的過程中進行調整。這樣,當SUM(Xi * Wi)+ (-1 * theta) >= 0 時,y=1,反之y=0
        在訓練過程中,神經網路輸入:一系列需要分類的術語示例 ;它們的正確分類或者目標 。這樣的輸入可以看成一個向量:<X1, X2, ..., Xn, theta, t>,這裡是一個目標或者正確分類。神經網路用這些來調整權係數,其目的使培訓中的目標與其分類相匹配。更確切地說,這是有指導的培訓,與之相反的是無指導的培訓。前者是基於帶目標的示例,而後者卻只是建立在統計分析的基礎上(請參閱本文隨後的參考資料)。權係數的調整有一個學習規則,一個理想化的學習演算法如下所示:

清單 1. 理想化的學習演算法

fully_trained = FALSE

DO UNTIL (fully_trained):

    fully_trained = TRUE

    FOR EACH training_vector = <X1, X2, ..., Xn, theta, target>::

                               # Weights compared to theta

        a = (X1 * W1)+(X2 * W2)+...+(Xn * Wn) - theta

        y = sigma(a)

        IF y != target:

            fully_trained = FALSE

        FOR EACH Wi:

        MODIFY_WEIGHT(Wi)      # According to the training rule

    IF (fully_trained):

        BREAK

您或許想知道,哪些培訓規則?有很多,不過有一條似乎合理的規則是基於這樣一種思想,即權係數和閾值的調整應該由分式(t - y) 確定。這個規則通過引入alpha (0 < alpha < 1) 完成。我們把alpha 稱為學習率。Wi 中的更改值等於(alpha * (t - y)* Xi)。當alpha 趨向於時,神經網路的權係數的調整變得保守一點;當 alpha 趨向於時,權係數的調整變得激進。一個使用這個規則的神經網路稱為感知器,並且這個規則被稱為 感知器學習規則。

Rosenblatt 1962 年(請參閱參考資料)下的結論是,如果維空間的點集被超平面切割,那麼感知器的培訓演算法的應用將會最終導致權係數的分配,從而定義了一個TLU,它的超平面會進行需要的分割。當然,為了記起Keynes,最終我們都切斷了與外界的聯絡,專心思考。但是在計算時間之外,我們仍瀕臨危險,因為我們需要自己的神經網路對可能輸入的空間進行不止一次的切割。

文章開始的難題舉例說明了這個,假設給您 個字元的程式碼段,您知道是CC++Java 或者Python。難的是構造一個程式來標識編寫這段程式碼的語言。用TLU 來實現需要對可能的輸入空間進行不止一次的分割。它需要把空間分成四個區域。每種語言一個區域。把神經網路培訓成能實現兩個切割就可完成這種工作。第一個切割將C/C++ Java/Python 分開來,另一個將C/Java C++/Python 分開。一個能夠完成這些切割的網路同樣可以識別原始碼樣本中的語言。但是這需要網路有不同結構,在描述這個不同之處之前,先來簡單地看一下實踐方面的考慮。

640?wx_fmt=png

圖 2. 初步的(不完整的)感知器學習模型

考慮到排除取得 個字元程式碼所需的計算時間,統計從ASCII 碼的32到127的範圍內可視ASCII 碼字元出現的頻率,並在這個統計以及關於程式碼語言的目標資訊的基礎上培訓神經網路。

我們的方法是將字元統計限制到CC++Java Python 程式碼字元庫中最常用的20 個非字母數字字元。由於關注浮點運算的執行,我們打算用一種規格化因素將這20 字元統計分開來,並以此培訓我們的網路。顯然,一個結構上的不同是我們的網路有20 個輸入節點,但這是很正常的,因為我們的描述已經暗示了這種可能性。一個更有意思的區別是出現了一對中間節點,N1 N2,以及輸出節點數量從兩個變成了四個(O1 O4)。

我們將訓練 N1,當它一看到C++,設定y1=1,看到Java或Python,它將設定y1=0。同理訓練N2,當它看到Java,設定y2=1,看到C++ Python,設定y2=0。此外,N1 N2 將輸出Oi。現在如果N1 看到C++,而且N2 看到或者Java,那麼難題中的程式碼是C。而如果N1 看到C++N2 看到C++ Python,那麼程式碼就是C++。這個模式很顯而易見。所以假設Oi 已被培訓並根據下面表格的情況輸出0

對映到輸出(作為布林函式)的中間節點。

640?wx_fmt=png

如果這樣可行的話,我們的網路就可以從程式碼示例中識別出語言了。這個想法很好。但是在實踐上卻有些難以置信。不過這種解決方案預示了 C/C++ Java/Python 輸入被一個超平面切割了,同樣C/Java C++/Python 輸入被另一個切割。這是一個網路培訓的解決方案,迂迴地解決了這個輸入空間的設想。

關於 delta 規則

另一種訓練的規則叫做 delta 規則。感知器培訓規則是基於這樣一種思路——權係數的調整是由目標和輸出的差分方程表示式決定。而delta 規則是基於梯度降落這樣一種思路。這個複雜的數學概念可以舉個簡單的例子來表示。從給定的幾點來看,向南的那條路徑比向東那條更陡些。向東就像從懸崖上掉下來,但是向南就是沿著一個略微傾斜的斜坡下來,向西像登一座陡峭的山,而北邊則到了平地,只要慢慢的閒逛就可以了。所以您要尋找的是到達平地的所有路徑中將陡峭的總和減少到最小的路徑。在權係數的調整中,神經網路將會找到一種將誤差減少到最小的權係數的分配方式。

將我們的網路限制為沒有隱藏節點,但是可能會有不止一個的輸出節點,設 是一組培訓中的一個元素,t(p,n) 是相應的輸出節點的目標。但是,設y(p,n) 由以上提到的squash 函式決定,這裡a(p,n) 是與相關的的啟用函式,或者用(p,n) = s( a(p,n) ) 表示為與相關的節點squash 過的啟用函式。為網路設定權係數(每個Wi),也為每個建立t(p,n) y(p,n) 的差分,這就意味著為每個設定了網路全部的誤差。因此對於每組權係數來說有一個平均誤差。但是delta 規則取決於求平均值方法的精確度以及誤差。我們先不討論細節問題,只是說一些與某些相關的誤差:?* square( t(p,n) - y(p,n) )(請參閱參考資料)。現在,對於每個Wi,平均誤差定義如下:

清單 2. 查詢平均誤差

sum = 0

FOR p = 1 TO M:         # M is number of training vectors

    FOR n = 1 TO N:     # N is number of output nodes

        sum = sum + (1/2 * (t(p,n)-y(p,n))^2)

average = 1/M * sum

delta 規則就是依據這個誤差的定義來定義的。因為誤差是依據那些培訓向量來說明的,delta 規則是一種獲取一個特殊的權係數集以及一個特殊的向量的演算法。而改變權係數將會使神經網路的誤差最小化。

我們不需要討論支援這個演算法的微積分學,只要認為任何Wi 發生的變化都是如下所示就夠了:alpha * s'(a(p,n)) * (t(p,n) - y(p,n)) * X(p,i,n).

X(p,i,n) 是輸入到節點中的第個元素,alpha 是已知的學習率。最後s'( a(p,n) ) 是與相關的第個節點啟用的squashing 函式的變化(派生)率,這就是delta 規則,並且Widrow Stearns向我們展示了當alpha 非常小的時候,權係數向量接近某個將誤差最小化的向量。用於權係數調節的基於delta 規則的演算法就是如此。

梯度降落(直到誤差小到適當的程度為止)

step 1: for each training vector, p, find a(p)

step 2: for each i, change Wi by:

            alpha * s'(a(p,n)) * (t(p,n)-y(p,n)) * X(p,i,n)

這裡有一些與感知器演算法相區別的重要不同點。顯然,在權係數調整的公式下有著完全不同的分析。delta 規則演算法總是在權係數上調整,而且這是建立在相對輸出的啟用方式上。最後,這不一定適用於存在隱藏節點的網路。

反向傳播

反向傳播這一演算法把支援 delta 規則的分析擴充套件到了帶有隱藏節點的神經網路。為了理解這個問題,設想Bob Alice 講了一個故事,然後Alice 又講給了TedTed 檢查了這個事實真相,發現這個故事是錯誤的。現在Ted 需要找出哪些錯誤是Bob 造成的而哪些又歸咎於Alice。當輸出節點從隱藏節點獲得輸入,網路發現出現了誤差,權係數的調整需要一個演算法來找出整個誤差是由多少不同的節點造成的,網路需要問,是誰讓我誤入歧途?到怎樣的程度?如何彌補?這時,網路該怎麼做呢?

640?wx_fmt=png

圖 3程式碼識別反向傳播的神經網路

反向傳播演算法同樣來源於梯度降落原理,在權係數調整分析中的唯一不同是涉及到 t(p,n) y(p,n) 的差分。通常來說Wi 的改變在於:

alpha * s'(a(p,n)) * d(n) * X(p,i,n)

其中 d(n) 是隱藏節點的函式,讓我們來看(1對任何給出的輸出節點有多大影響;(2)輸出節點本身對網路整體的誤差有多少影響。一方面,影響一個輸出節點越多,造成網路整體的誤差也越多。另一方面,如果輸出節點影響網路整體的誤差越少,對輸出節點的影響也相應減少。這裡