Deep learning:七(基礎知識_2)


  

  前面的文章已經介紹過了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算法),那么網絡的性能就取決於網絡的結構(即隱含層的個數以及每個隱含層神經元的個數),一般默認的結構是:只取一個隱含層,如果需要取多個隱含層的話就將每個隱含層神經元的個數設置為相同,當然了隱含層神經元的個數越多則效果會越好。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM