Deep learning 七 基礎知識 2

2022-03-23 00:46:14 字數 2937 閱讀 2011

前面的文章已經介紹過了2種經典的機器學習演算法:線性回歸和logistic回歸,並且在後面的練習中也能夠感覺到這2種方法在一些問題的求解中能夠取得很好的效果。現在開始來看看另一種機器學習演算法——神經網路。線性回歸或者logistic回歸問題理論上不是可以解決所有的回歸和分類問題麼,那麼為什麼還有其它各種各樣的機器學習演算法呢?比如這裡馬上要講的神經網路演算法。其實原因很簡單,在前面的一系列博文練習中可以發現,那些樣本點的輸入特徵維數都非常小(比如說2到3維),在使用logistic回歸求解時,需要把原始樣本特徵重新對映到高維空間中,如果特徵是3維,且指數最高為3時,得到的係數最高維數應該是20維。但是一般現實生活中的資料特徵非常大,比如一張小的可憐的灰度50*50,本身就只有2500個特徵,如果要採用logistic回歸來做目標檢測的話,則有可能達到上百萬的特徵了。這樣不僅計算量複雜,而且因為特徵維數過大容易是學習到的函式產生過擬合現象。總的來說,只有線性回歸和logistic回歸在現實生活中是遠遠不夠的,因此,神經網路由於它特有的優勢就慢慢被研究了。

神經網路模型的表達結構是比較清晰的,輸入值和對應的權重相乘然後相加最終加上個偏移值就是輸出了。只是數學公式比較繁瑣,容易弄錯。假設第j層網路有sj個節點,而第j+1層網路有s(j+1)個節點,則第j層的引數應該是個矩陣,矩陣大小為s(j+1)*(sj+1),當然了,此時是因為那個權值為1的那個網路節點沒有算進去。很顯然,為了方便公式的表達,神經網路中經常使用向量化的數學公式。為什麼神經網路最有學習功能呢?首先從生物上來講,它模擬了人的大腦的功能,而人的大腦就有很強大的學習機制。其次從神經網路的模型中也可以看出,如果我們只看輸出層已經和輸出層相連的最後一層可以發現,它其實就是乙個簡單的線性回歸方程(如果使輸出在0~1之間,則是logistic回歸方程),也就是說前面那麼多的網路只是自己學習到了一些新的特徵,而這些新的特徵是很適合作為問題求解的特徵的。因此,說白了,神經網路是為了學習到更適合問題求解的一些特徵。

表面上看,神經網路的前一層和當前層是直接連線的,前一層的輸出值的線性組合構成了當前層的輸出,這樣即使是有很多層的神經網路,不也只能學習到輸入特徵的線性組合麼?那為什麼說神經網路可以學習任意的非線性函式呢?其實是剛才我犯了乙個本質錯誤,因為前一層輸出的線性組合並不直接是本層的輸出,而是一般還通過乙個函式復合,比如說最常見的函式logistic函式(其它的函式比如雙曲正切函式也是很常用的),要不然可就真是只能學習到線性的特徵了。神經網路的功能是比較強大的,比如說單層的神經網路可以學習到」and」,」or」,,」not」以及非或門等,兩層的神經網路可以學習到」xor」門(通過與門和非或門構成的乙個或門合成),3層的神經網路是可以學習到任意函式的(不包括輸入輸出層)等,這些在神經網路的發展過程中有不少有趣的故事。當然了,神經網路也是很容易用來擴充套件到多分類問題的,如果是n分類問題,則只需在設計的網路的輸出層設定n個節點即可。這樣如果系統是可分的話則總有乙個學習到的網路能夠使輸入的特徵最終在n個輸出節點中只有乙個為1,這就達到了多分類的目的。

神經網路的損失函式其實是很容易確定的,這裡以多分類的神經網路為例。當然了,這裡談到損失函式是在有監督學習理論框架下的,因為只有這樣才能夠知道損失了多少(最近有發展到無監督學習框架中也是可以計算損失函式的,比如說autoencoder等)。假設網路中各個引數均已學到,那麼對於每個輸入樣本,就能夠得出乙個輸出值了,這個輸出值和輸入樣本標註的輸出值做比較就能夠得到乙個損失項。由於多分類中的輸出值是乙個多維的向量,所以計算它的損失時需要每一維都求(既然是多分類問題,那麼訓練樣本所標註的值也應該為多維的,至少可以轉換成多維的)。這樣的話,神經網路的損失函式表示式與前面的logistic回歸中損失函式表示式很類似,很容易理解。

有了損失函式的表示式,我們就可以用梯度下降法或者牛頓法來求網路的引數了,不管是哪種方法,都需要計算出損失函式對某個引數的偏導數,這樣我們的工作重點就在求損失函式對各個引數的偏導數了,求該偏導數中最著名的演算法就是bp演算法,也叫做反向傳播演算法。在使用bp演算法求偏導數時,可以證明損失函式對第l層的某個引數的偏導與第l層中該節點的誤差,以及該引數對應前一層網路編號在本層的輸出(即l層)的輸出值有關,那麼此時的工作就轉換成了每一層網路的每乙個節點的誤差的求法了(當然了,輸入層是不用計算誤差的)。而又可通過理論證明,每個節點的誤差是可以通過下一層網路的所以節點反向傳播計算得到(這也是反向傳播演算法名字的**)。總結一下,當有多個訓練樣本時,每次輸入乙個樣本,然後求出每個節點的輸出值,接著通過輸入樣本的樣本值反向求出每個節點的誤差,這樣損失函式對每個節點的誤差可以通過該節點的輸出值已經誤差來累加得到,當所有的樣本都經過同樣的處理後,其最終的累加值就是損失函式對應位置引數的偏導數了。bp演算法的理論**是乙個節點的誤差是由前面簡單的誤差傳遞過來的,傳遞係數就是網路的係數。

一般情況下,使用梯度下降法解決神經網路問題時是很容易出錯,因為求解損失函式對引數的偏導數過程有不少矩陣,在程式中容易弄錯,如果損失函式或者損失函式的偏導數都求錯了的話,那麼後面的迭代過程就更加錯了,導致不會收斂,所以很有必要檢查一下偏導數是否正確。andrew ng在課程中告訴大家使用gradient checking的方法來檢測,即當求出了損失函式的偏導數後,取乙個引數值,計算出該引數值處的偏導數值,然後在該引數值附近取2個引數點,利用損失函式在這個兩個點值的差除以這2個點的距離(其實如果這2個點足夠靠近的話,這個結果就是導數的定義了),比較這兩次計算出的結果是否相等,如果接近相等的話,則說明很大程度上,這個偏導數沒有計算出錯,後面的工作也就可以放心的進行了,這時候一定要記住不要再執行gradient checking,因為在執行gradient checking時會使用bp進行每層的誤差等計算,這樣很耗時(但是我感覺即使不計算gradient checking,不也要使用bp演算法進行反向計算麼?)。

在進行網路訓練時,千萬不要將引數的初始值設定成一樣的,因為這樣學習的每一層的引數最終都是一樣的,也就是說學習到的隱含特徵是一樣的,那麼就多餘了,且效果不好。因此明智的做法是對這些引數的初始化應該隨機,且一般是滿足均值為0,且在0左右附近的隨機。

如果採用同樣的演算法求解網路的引數的話(比如說都是用bp演算法),那麼網路的效能就取決於網路的結構(即隱含層的個數以及每個隱含層神經元的個數),一般預設的結構是:只取乙個隱含層,如果需要取多個隱含層的話就將每個隱含層神經元的個數設定為相同,當然了隱含層神經元的個數越多則效果會越好。

Deep learning系列(七)啟用函式

sigmoid將乙個實數輸入對映到 0,1 範圍內,如下圖 左 所示。使用sigmoid作為啟用函式存在以下幾個問題 因為上面兩個問題的存在,導致引數收斂速度很慢,嚴重影響了訓練的效率。因此在設計神經網路時,很少採用sigmoid啟用函式。tanh函式將乙個實數輸入對映到 1,1 範圍內,如上圖 右...

Deep learning系列(七)啟用函式

sigmoid將乙個實數輸入對映到 0,1 範圍內,如下圖 左 所示。使用sigmoid作為啟用函式存在以下幾個問題 因為上面兩個問題的存在,導致引數收斂速度很慢,嚴重影響了訓練的效率。因此在設計神經網路時,很少採用sigmoid啟用函式。tanh函式將乙個實數輸入對映到 1,1 範圍內,如上圖 右...

Deep learning 一 基礎知識 1

前言 最近打算稍微系統的學習下deep learing的一些理論知識,打算採用andrew ng的網頁教程ufldl tutorial,據說這個教程寫得淺顯易懂,也不太長。不過在這這之前還是複習下machine learning的基礎知識,見網頁 內容其實很短,每小節就那麼幾分鐘,且講得非常棒。教程...