深度學習教程:從感知器到深層網絡
來自: http://www.almosthuman.cn/2016/01/19/lpqau/
本文作者Ivan Vasilev是一名具有創業精神的高級開發人員。他的經驗范圍跨越多個領域和技術,但他的主要焦點在Java、JavaScript及機器學習上。
近些年來,人工智能重新興起。它已超出學術領域范疇, Google、Microsoft和非死book幾大玩家創建了自己的研發團隊,并取得了了一些令人矚目的成果。
這些可以歸功于社交網絡用戶產生的豐富原始數據(大多仍需要再分析)以及通過GPGPUs(通用計算圖形處理器)獲得的廉價計算能力。
但在這些現象之外,人工智能的重新興起很大程度上得力于AI的一種新趨勢,確切地說是在機器學習領域,被稱為「深度學習」。在這篇教程中,我將向你介紹深度學習背后一些關鍵性概念和算法,從最簡單的組成單元開始,以此為基礎構造Java中機器學習的概念。
(充分說明:我同時也是Java深度學習庫的作者,這篇文章中的例子也有使用到上述文庫。如果你喜歡它,你可以在GitHub上給它一顆星表示支持,我對此深表感激。主頁上有使用說明。)
機器學習30秒教程
如果你不太熟悉,你可以戳這里閱讀機器學習入門介紹。
一般的步驟如下:
1.我們有一些算法給定了少量帶標簽的素材,比如有10張有狗的圖片,為標簽1(「狗」),10張其他事物的照片,為標簽0(「非狗」)——請注意這篇文章中我們主要采用監督式兩類分類法。
2.算法學習去識別含有狗的圖片,當給它一張新圖片時,希望算法可以產生正確的標簽。(如果是含有狗的圖片標簽則為1,其他則為0)。
這種設定非常普遍:你的數據可以是疾病癥狀,標簽設為病態;或者數據是手寫字母的圖片,標簽為所寫的實際字母。
感知器:早期的深度學習算法
最早的一個監督式訓練算法就是感知器,是一個基本的神經網絡構造塊。
假設平面上有n個點,分別標記為「0」和「1」。給出一個新的點,我們想要猜出它背后的標簽(這類似于上面情景中的「狗」和「非狗」)。我們怎么做呢?
方法之一也許是觀察它的最鄰近區域,并得出這個點的標簽。但是略為聰明的一個方法是選擇一條可以最優隔開這些被標記過的數據的線,把它作為你的分類器。
在這種情況下,每條輸入的數據都可以用一個向量x = (x_1, x_2)來表示,而應變量為「0」(如果x在這條線以下)或「1」(x在線以上)。
如果在數學上表示,這個分類器可以用一個含有權重w的向量和垂直偏移(或偏差)量b來定義。然后,我們將輸入、權重和偏移結合可以得到一個如下的傳遞函數:
這個傳遞函數的結果將被輸入到一個激活函數中以產生一個標簽。在上述例子中,我們的激活函數是閥值中止的(即大于某個閾值后輸出1):
訓練感知器
感知器的訓練包括多個訓練樣本的輸入和計算每個樣本的輸出。每個樣本的權重w都要調整以便最小化輸出誤差,這個誤差由需求目標與實際輸出的差異得出。還有其他誤差計算方法,比如均方差,但是基本的訓練原則保持不變。
單個感知器缺陷
深度學習的這種單個感知器有一個明顯的缺陷:它只能學習線性可分函數。這個缺陷重要嗎?比如XOR(異或運算),這是一個相當簡單的函數,但它卻不能被線性分離器分類(如下圖,分類嘗試失敗):
為了解決這個問題,我們需要使用一個多層感知器,也就是前饋神經網絡:事實上,我們將把這些感知器組合在一起來創建一個更強大的學習機器。
深度學習中的前饋神經網絡
神經網絡實際上就是將感知器進行組合,用不同的方式進行連接并作用在不同的激活函數上。
對于初學者,讓我們看看前饋神經網絡,它有以下幾大特性:
1.一個輸入層、一個輸出層、一個或多個隱藏層。上圖中展示的神經網絡含有一個三神經元輸入層,一個四神經元隱藏層和一個二神經元輸出層。
2.每個神經元都是上文提到的感知器。
3.輸入層的神經元作為隱含層的輸入,同時隱含層的神經元也是輸出層的輸入。
4.每條建立在神經元之間的連接都有一個權重 w (與感知器的權重類似)。
5.在 t 層的每個神經元通常與前一層( t – 1層)中的每個神經元連接(盡管你可以通過將權重設為0來斷開這條連接)。
6.為了處理輸入數據,將輸入向量賦到輸入層中,把向量的值設為每個輸入神經元的輸出。在這個特例中,這個網絡可以處理一個3維輸入向量(因為有3個輸入神經元)。假如輸入向量是 [7, 1, 2],那么你將第一個輸入神經元輸入7,中間的輸入1,第三個輸入2。這些值將被傳播到隱含層,通過加權傳遞函數傳給每一個隱藏層神經元(這就是前向傳播),隱藏層神經元再計算輸出(激活函數)。
7.輸出層計算輸出的方式與隱藏層相同,輸出層的計算結果就是整個神經網絡的輸出。
超線性
如果我們的每個感知器都只允許使用線性激活函數會怎樣呢?那么,網絡的最后輸出值將仍是這些輸入量的線性函數,只是隨著整個網絡中與之相關的大量不同權重而有所調整。換句話說,一個線性函數的線性組合仍只是線性函數。如果我們受限于線性激活函數,那么前饋神經網路并不會比感知器更強大,無論它是多少層。
正是這個原因,大多數神經網絡都是使用的非線性激活函數,如對數函數、雙曲正切函數、階躍函數、整流函數等。不用這些非線性函數的神經網絡只能學習輸入數據的線性組合這種形式的函數。
訓練感知器
對于多層感知器的監督式訓練最常見的深度學習算法是反向傳播。基本的過程是 :
1、將訓練樣本通過神經網絡進行前向傳播計算。
2、計算輸出誤差,通常用均方差:
其中 t 是目標值, y 是實際的神經網絡輸出。其它的誤差計算方法也可以,但MSE(均方差)通常是一種比較好的選擇。
3.網絡誤差通過隨機梯度下降法來最小化。
梯度下降很常用,但在神經網絡中,它相當于是一條具有輸入參數功能的訓練誤差的曲線。每個權重的最佳值應該是誤差曲線中的全局最小值(上圖中的 global minimum)。在訓練過程中,權重以非常小的步幅改變(在每個訓練樣本或每小組樣本訓練完成后)以找到全局最小值,但這不是輕松的任務,訓練通常會結束在局部最小值上(上圖中的local minima)。舉例來說,如果權重值為0.6,那么它需要要向0.4方向移動。
這個圖表示的是最簡單的情況,在這種情況下誤差只依賴于單個參數。但是,網絡誤差依賴于每一個網絡權重,誤差函數非常、非常復雜。
幸運的是,反向傳播算法提供了一種通過利用輸出誤差來修正兩個神經元之間權重的方法。這樣的微分本身十分復雜,但對于一個給定結點的權重修正有如下(簡單)方法:
其中 E 是輸出誤差, w_i 是神經元輸入 i 的權重。
實質上這么做的目的是利用權重 i 來修正梯度的方向。關鍵的地方是誤差的導數,當然,這通常不那么容易計算:你如何能給一個大型網絡中一個隨機隱藏結點中的隨機權重求導呢?
答案是:通過反向傳播。誤差首次在公式很簡單的輸出神經元進行計算(計算預期值和目標值的差),然后通過一種巧妙的方法反向傳回至網絡,讓我們在訓練過程中有效地修正權重并(期望)得到一個最小值。
隱藏層
隱藏層十分有趣。根據通用逼近定理,含有有限數量神經元的單個隱層網絡可以被訓練為類似任意的隨機函數。換句話說,單個隱藏層強大到可以學習任何函數。這說明我們在多隱藏層(如深度網絡)的實踐中可以得到更好的結果。
隱藏層就是網絡存儲它的訓練數據的內部抽象表征的地方,類似于我們大腦(大大簡化的類比)有個對真實世界的內部表征。回到教程前面,我們將觀察玩味隱藏層的不同方式。
一個示例網絡
你可以在這里看到Java語言通過testMLPSigmoidBP方法,用一個簡單的(4-2-3層次)前饋式神經網絡對IRIS數據集(譯者注:經典的分類鳶尾花數據集)進行分類。IRIS數據集包括三個種類的鳶尾花的特征集合,比如葉萼長度,花瓣長度等等。網絡需要從每個種類的鳶尾花中抽取50個樣本,這些特征值被作為輸入元輸入網絡,而每個輸出元對應著數據集中一個單獨的種類:「1/0/0」表示這株植物的種類是Setosa,「0/1/0」表示為Versicolour種類,而[0/0/1]表示為Virginica種類。它的分類錯誤率為2/150(即,它在150個實例植株分類過程中出現了兩個分類錯誤)。
大型神經網絡的問題
一個神經網絡可以有不止一個隱藏層:這就是說,更加高級一些的層次會基于前一層「創建」新的抽象概念。正如之前提到過的,你總是可以用更大的網絡在實際應用中學習的更好。
然而,持續增長隱藏層的數目會帶來以下兩個顯著的問題:
1.梯度消失。當我們添加了一個又一個的隱藏層時,反向傳播將有用信息反向傳回前面層次起的作用就變得越來越小。實際上,當信息被反向傳回,梯度開始消失,并且與網絡的權重相關性也更加小。
2.過擬合。這可能也是機器學習的核心難題。簡單來說,過擬合描述了網絡模型過于貼近訓練數據的現象,這可能是模型太過復雜導致的。在這樣的例子下,你的學習模型最終確實能夠很好的擬合數據,但是會擬合地過了頭,在真實的測試實例上表現更加糟糕。
讓我們看一些深度學習算法如何解決這個問題的。
自編碼器
大多數引導性機器學習都停止在前饋神經網絡這一步。但是可能的網絡空間遠非如此——所以讓我們繼續。
自編碼器是典型的前饋型神經網絡,旨在學習一個經過壓縮的、分布表示(編碼)的數據集。
概念上來說,網絡被訓練成「重新生成」輸入,比如,輸入以及目標數據都是一樣的。換句話說:你嘗試著輸出跟你輸入的一模一樣的東西,但是在某種程度上經過了壓縮。這是個容易讓人迷糊的方法,所以讓我們來看一個實例。
壓縮輸入:灰度圖片
如果說訓練數據由像素28*28的灰度圖片組成而且每一個像素值都賦給一個輸入層的神經元中(即輸入層將有784個神經元)。之后,輸出層也將同輸入層一樣有784個單元,并且每個輸出元的目標值都將是圖像中每一個像素的灰度值。
這樣的結構背后是網絡將不會在它的訓練數據和標簽之間,學習建立一個「映射」關系,而是學習數據本身的內部結構和特征。(也因此,隱藏層也被叫做特征探測器)。通常,隱層神經元的個數要小于輸入/輸出層,這也就迫使神經網絡只學習那些最為重要的特征,同時實現一個維度的減少。
實際上,我們希望中間一些節點能在概念層次上學習數據,從而產生一個簡潔的表征,這樣在一定程度上能夠捕捉到我們輸入的關鍵特征。
流感疾病
為了更進一步驗證自編碼器,讓我們再來看一個應用。
在這個實例中,我們將使用一個簡單的數據集組成流感癥狀。如果你有興趣,這個實例的代碼可在testAEBackpropagation方法中找到。
如下就是這個數據集如何被分解的:
- 這里有六個二進制輸入特征。
- 前三個表示疾病的癥狀。比如,1 0 0 0 0 0指這名患者體溫過高,0 1 0 0 0 0代表咳嗽,1 1 0 0 0 0 暗示著咳嗽和高體溫,等等。
- 后三個特征是「相反」特征,當一名病人有其中一項癥狀,她或他就有更少的可能性患病。例如, 0 0 0 1 0 0暗示這名病人接種過流感疫苗,同時也存在將兩個數據集特征結合起來的情況:0 1 0 1 0 0 暗示著一個接種過疫苗的病人同時在咳嗽,諸如此類。
- 111000, 101000, 110000, 011000, 011100 = 生病
- 000111, 001110, 000101, 000011, 000110 = 健康
- 正相位:
- 負相位:
- 權值更新
- 注:這里a是學習速率,v,v’,h,h’都是向量。
- 使用反向傳播的方法及所有可用的訓練數據,單獨地訓練第一個自編碼器(t=1,或是上圖中的紅色連接,但需要一個額外的輸出層)。
- 訓練第二個自編碼器 t=2(綠色連接)。由于 t=2 的輸入層是t=1的隱藏層,我們對 t=1 的輸出層不再感興趣,將其從網絡中剔除。訓練開始于將輸入樣本賦到 t=1的輸入層,并向前傳播到 t=2的輸出層。接著 t=2的權重(輸入-隱藏及隱藏-輸出)通過反向傳播得到更新。與t=1相似,t=2使用所有訓練樣本。
- 所有層都重復前面的過程(即移除前一個自編碼器的輸出層,用另外一個自編碼器替換,然后用反向傳播進行訓練。)
- 步驟1-3被稱為預訓練(pre-training),并留下正確初始化的權重。然而,輸入數據和輸出標簽之間是沒有映射的。例如,如果一個網絡被訓練來識別手寫數字,它仍然無法將最后一個特征檢測器(即最后一個自編碼器的隱藏層)與圖像的數字類別做匹配。在這種情況下,最常見的解決方法是為最后一層(藍色連接)加上一個或以上的完全連接層。整個網絡可被看作是一個多層感知器,并使用反向傳播來訓練(這個步驟也稱為優化)。
- 利用所有的訓練樣本和對比分歧法訓練第一個RBM t=1。
- 訓練第二個RBM t=2。因為 t=2 的可見層是 t=1 的隱藏層,訓練始于將訓練樣本賦給 t=1 的可見層,接著向前傳播到t=1的隱藏層。這個數據可作為對比分歧法對于 t=2 的初始化訓練。
- 以此類推,為所有層重復前面的過程。
- 類似于堆疊式自編碼器,經過預訓練以后,我們可透過連接一個或多個完全連接層(fully connected layers)至最后一個RBM的隱藏層來擴充整個網絡。這形成了一個多層感知器,并且可使用反向傳播進行優化。
- 一個足以代表不同模型的常見架構(正如我們在以上看到的所有神經網絡的變種)。
- 使用不同訓練算法的能力(反向傳播,對比分歧等)。
- 具有不錯的表現。
- NeuralNetworkImpl 是所有神經網絡模型的基礎。
- 每個網絡都包含有一組層。
- 每層都具有一系列連接任意兩層的連接,使得所述的網絡成為一個有向非循環圖形(directed acyclic graph, or DAG)
- 確定層的順序。例如,為了從一個多層感知器獲得結果,數據會被「賦」到輸入層(因此,這成了要被計算的第一層),并傳播至輸出層。為了在反向傳播中可以更新權重,輸出誤差需要從輸出層開始被傳播,經過所有層,并以廣度作為優先順序被傳播。這可以通過使用 LayerOrderStrategy 的各種實施來取得,它利用了網絡圖像結構并應用了不同的圖像遍歷方法。這些方法包括廣度優先策略(breadth-first strategy)及特定層的定位(targeting of a specific layer)。順序實際上是由層與層之間的連接來決定的,所以這策略返回了一系列有序的連接。
- 計算激活值。每一層都有一個相關的連接計算器(ConnectionCalculator),連接計算器需要一系列的連接(來自之前的步驟)及輸入值(來自其它層)以計算激活值。例如在一個S形的前饋網絡中,隱藏層的連接計算器使用輸入值、偏移層的值(即輸入數據和1的陣列)?及單元之間的權重(當這些層在完全連接的情況下,權重實際上是以矩陣形式存儲在一個完全連接的連接中),以此計算出加權和,并將結果反饋給S形函數。連接計算器實現多種傳輸(例如加權和及卷積)及激活(例如邏輯斯蒂和正切的多層感知器,二進制RBM)。它們之間的大多數可以在GPU上使用Aparapi得到執行,還可以進行小批量訓練。
- 僅一維陣列(和變量)的基本數據類型是允許的。
- 只有Aparapi Kernel或類似方法(member-methods)是允許從GPU可執行代碼中被召集的。 </ul>
</ul> </ul>
我們將考慮如下情況,當一個患者擁有前三種患病癥狀中至少兩種癥狀時,他/她是患病的,同時如果有后三種「相反」癥狀里的兩種,我們認他/她是健康的,比如:
</ul> </ul>
我們將會利用6個輸入元忽和6個輸出元但僅2個隱藏元來訓練自編碼器(通過反向傳播)。
在經過數百次迭代之后,我們觀察到當每一個「生病」樣本被機器學習的網絡表示出來時,兩個隱層神經元中的一個(和每個「生病」樣本相同的單元)總是表現出比其他神經元更高的激活值。相反的,當一個「健康」樣本被表示,另一個隱藏神經元有更強的激活反應。
回到機器學習
本質上,我們的兩個隱層神經元都是從流感癥狀數據集中學到了數據的壓縮表示。為了看看這如何與學習相關聯,我們返回到過擬合的問題上來。通過訓練我們的網絡來進行數據的壓縮表示,我們更偏愛一個較為簡單的表示方法而不是一個十分復雜、有可能在訓練數據上過擬合的理論模型。
一定程度上,由于偏好這樣更為簡單的表示方法,我們也會嘗試從一個更加真實的意義上去學習數據。
有限玻爾茲曼機(RBM)
下一個邏輯步驟是看看有限玻爾茲曼機(RBM),一個可以從它自身輸入來學習概率分布的隨機生成神經網絡。
RBMS由隱藏層、可見層、以及偏移層所組成。不同于前饋神經網絡,在可見層和隱層之間的連接是無向的(值可以同時從隱層傳到可見層,反之亦然)同時還是全連接的(給定層的每個神經元都會和下一層的每個神經元相連接——如果我們允許任意層次的任意神經元來連接到其他任何層次,那么就是玻爾茲曼機(并非有限玻爾茲曼機))。
標準的RBM有二進制隱藏元和可見元:即是說在伯努利分布下神經元的激活值為0或者1,但是這里也有其他非線性的變量。
研究者們知曉RBMs已經有一定的年月,但最近關于對比分歧無監督訓練算法的介紹又重新挑起了研究者們的興趣。
對比分歧
單步對比分歧算法(CD-1)的運行原理如下:
1.一個輸入樣本v賦給輸入層
2.v以前饋神經網絡中相類似的規則被傳輸到了隱藏層,隱藏層最終激活的結果是h
1.將h反向傳播到可見層得到結果v’(在隱藏層與可見層之間的連接是無向的,所以兩個方向之間的移動都是可以進行的。)
2.將新的v’反向傳播給給隱藏層得到激勵結果h’
隱藏在這個算法之后的思想就是正相位傳播(h得到v)反映了網絡對真實數據的內部表達。同時,負相位代表了嘗試基于內部表達重構數據的過程(v’到h)。主要目的都是為了生成的數據能夠盡可能接近真實世界并且反映在權值更新的公式上。
換句話來講,這個網絡擁有一些如何將輸入數據表示出來的認知觀念,所以它嘗試重新生成基于這個表示的數據。如果重新生成的數據不能與實際情況足夠接近,這將使得它重新做出調整,再次嘗試學習。
再談流感
為了證明對比分歧,我們將使用之前那個癥狀數據集。用于測試的網絡是一個有著6個可見元與2個隱藏元的RBM。我們將運用對比分歧把癥狀v賦給可見層之中訓練網絡,測試過程中,癥狀再一次被賦予到可見層,之后,數據被傳播到隱藏層。隱藏元代表著生病/健康狀態,這是一個與自編碼器非常相似的結構(從可見層到隱藏層傳輸數據)。
在經過上百次的迭代之后,我們可以觀測到與自編碼器相同的結果。當任意一個「生病」樣本被賦予系統時,其中一個隱藏元有著比其他神經更加高的激活值,而另一些在面對「健康」樣本時顯得更加的積極。
你可以在testContrastiveDivergence 方法中看到它的具體行為。
深度網絡
我們已經展示了自編碼器隱藏層和RBMs如何作為有效的特征檢測器,但其實很少會直接使用這些特征。事實上,上面的數據集更多的只是個例,而不是規則。相反,我們需要找到一些間接使用這些特征的方法。
幸運的是,人們發現這些結構可以透過堆疊來形成深度網絡。這些網絡可被一層層的訓練以克服正在消失的梯度及與經典反向傳播引起的過適度問題。
由此產生的模型往往是相當強大的,并且有不錯的成績。舉例來說,谷歌著名的「貓」論文,他們使用特殊的深度自動編碼器基于無標簽數據來「學習」人類和貓臉檢測。
讓我們來仔細看一下。
堆疊式自編碼器
正如其名所暗示,這個網絡由多個堆疊式自編碼器所組成。
自編碼器的隱藏層 t 充當自編碼器 t+1的輸入層。第一個自編碼器的輸入層是整個網絡的輸入層。逐層貪婪訓練法是這樣運作的:
那么堆疊式自編碼器,完全是對網絡權重的初始化提供一個有效的預訓練,并留下了一個復雜、多層且隨時可以訓練(或優化)的感知器。
深度信念網絡
有了自編碼器,我們也可以堆疊玻爾茲曼機來創建一個稱之為深度信念網絡(deep belief networks ,DBNs)的類別。
在這種情況下,RBM 的隱藏層t充當其t+1層的可見層。第一個RBM的輸入層是整個網絡的輸入層,逐層貪婪欲訓練法(The greedy layer-wise pre-training )是這樣運作的:
這個過程類似于堆疊式自編碼器,不同的是RBMs代替了自編碼器,對比分歧算法代替了反向傳播。
(注:如果希望進一步了解創建及訓練堆疊式自編碼器及深度信念網絡,可在此查看樣本代碼。)
卷積網絡
在看卷積網絡的實際結構之前,讓我們先定義一個圖像過濾器,或是一個與權重相關的方形區域。這個過濾器被應用在整個輸入圖像當中,并且會經常應用多個過濾器。例如,你可能會在一個圖像輸入中應用四個 6×6 的過濾器。然后,一個坐標為(1,1)的輸出像素其實就是一個左上角為1,1的 6×6 的輸入像素加權和即過濾器的權重(也為6×6)。輸出像素(2,1)是產自于左上角為(2,1)的輸入方形,以此類推。
根據以上所述,我們可以這樣定義這些網絡:
卷積層將一定數量的過濾器應用于輸入上。例如,圖像的第一個卷積層有四個 6×6 的過濾器。一個過濾器應用在圖像上的結果被稱為特征圖(feature map, FM),并且特征圖的數量等于過濾器的數量。如果前一層也是卷積的,它就會被應用在其所有的特征圖上,并且有不同的權重。因此,每個輸入特征圖就與每個輸出特征圖相連接了。在圖像共享權重背后的是不論位置如何,特征都將被檢測到,而過濾器的多樣性允許它們之間的每一個去檢測不同的特征集。
子采樣層(subsampling layer)減少輸入的大小。例如,如果輸入包含了一個 32×32 的圖像,并且這個圖層有一個 2×2 的子采樣層區域,輸出值就會是一個 16×16 的圖像,也就是說:輸入圖像的4個像素(每個 2×2 的平方)被組合為單個輸出像素。子采樣的方法有不少,但最受歡迎的包括 max pooling, average pooling 及 stochastic pooling。
最后一個子采樣(或是卷積)層通常與一個或多個完全連接層相連接,其中最后一個代表著目標數據。
訓練使用改良的反向傳播進行,而這個反向傳播是以子采樣層作為考慮的,并基于應用過濾器時的所有值更新卷積過濾器的權重。
你可以在 MNIST 數據集里(手寫信件的灰階圖像)看到多個卷積網絡(使用反向傳播)被訓練的樣本,特別是在 testLeNet* 的方法里(我建議使用 testLeNetTiny2,因為它在一個相對較短的時間內實現了約2%的低誤差率的成果)。這兒還有一個類似的網絡,它有一個不錯的可視化 JavaScript。
實施
現在我們已經概述了最常用的神經網絡變種,我希望再寫一點有關落實這些深度學習模型時會遇到的困難。
概括地說,我的目標是創建一個以神經網絡為基礎架構的深度學習庫(Deep Learning library),并且滿足以下條件:
為了滿足這些要求,我使用了層次(或模塊)的方式來設計軟件。
結構
讓我們從基礎開始:
這種結構用于經典的前饋網絡足夠靈活,也可以用于RBMs和更復雜的結構,如 ImageNet。
它也允許一層作為多個網絡而不僅是一種網絡的一部分。例如,在深度信念網絡里的層也可以是與其相應的RBMs里的層。
此外,這種結構允許深度信念網絡在預訓練的階段中被視為一列堆疊的RBMs,也在優化的階段中被視為前饋網絡,這樣既直觀也便于編程的。
數據傳播
下一個模塊負責通過網絡傳播數據,這是一個兩步驟的過程:
Aparapi GPU計算與Aparapi
正如我前面提到的,神經網絡在近幾年取得復蘇的其中一個原因是他們的訓練方法非常有利于并行計算,使人們在使用GPGPU時顯著提高訓練速度。在這種情況下,為了增加對GPU的支持,我選擇了與 Aparapi 庫合作。
Aparapi強加在連接計算器上的一些重要限制:
因此,大部分的數據(權重、輸入與輸出數組)都被儲存在矩陣當中,其中在內部會使用一維浮點數組。所有Aparapi連接計算器要么使用 AparapiWeightedSum(用于完全連接層及加權和輸入函數),要么使用AparapiSubsampling2D(用于子取樣層),或者 AparapiConv2D(用于卷積層)。當中的一些限制可以在引入異質系統架構(Heterogeneous System Architechure)后被克服。Aparapi允許在CPU或GPU上運行一樣的代碼。
訓練
這個訓練模塊可實現各種訓練算法。它依賴于先前的兩個模塊。例如,反向傳播訓練器(BackPropagationTrainer,所有訓練器都在使用訓練器基類)使在前饋階段用前饋層計算器,在傳播誤差和更新權重時使用廣度優先層計算器。
我最新的作品關于支持 Java 8 及其他一些改善方法,這些都可以在這里查得到,并且很快會被融合到我主要的著作里面。
結論
這個Java深度學習教程旨在給你提供一個有關深度學習算法的簡單介紹,我們由最基本的組成單元(感知器)開始,進而介紹了幾個有效并流行的架構,如有限玻爾茲曼機(RBM)。
神經網絡背后的想法其實存在了很長一段時間,并且隨著 GPGPU 計算能力的提升及由Geoffrey Hinton, Yoshua Bengio, Yann LeCun 與 Andrew Ng等學者所做出的努力,此領域已經挺有成果。所以今天你不能只停留在機器學習的領域,而不對深度網絡及其他相關的課題有一些了解了。現在是最好的時機了。
本文選自toptal,作者: IVAN VASILEV,機器之心編譯出品,編譯:Ben、鄭勞蕾、Angulia、柒柒。