深度學習教程:從感知器到深度網絡

已發表: 2022-03-11

近年來,人工智能領域出現了復甦。 它已經擴展到學術界之外,谷歌、微軟和 Facebook 等主要參與者創建了自己的研究團隊並進行了一些令人印象深刻的收購。

部分原因可歸因於社交網絡用戶生成的大量原始數據(其中大部分需要分析)、高級數據科學解決方案的興起以及可通過 GPGPU 獲得的廉價計算能力。

但除了這些現象之外,這種複蘇在很大程度上是由人工智能的新趨勢推動的,特別是在機器學習領域,被稱為“深度學習”。 在本教程中,我將向您介紹深度學習背後的關鍵概念和算法,從最簡單的組合單元開始,然後構建 Java 中的機器學習概念。

(全面披露:我也是Java深度學習庫的作者,可在此處獲取,本文中的示例是使用上述庫實現的。如果您喜歡它,可以在GitHub上給它一個star 來支持它, 不勝感激。使用說明可在主頁上找到。)

機器學習 32 秒教程

如果您不熟悉,請查看此機器學習簡介:

一般程序如下:

  1. 我們有一些算法,它給出了一些帶標籤的示例,比如 10 張帶有標籤 1(“狗”)的狗圖像和 10 張帶有標籤 0(“非狗”)的其他事物的圖像——請注意,我們主要是堅持對這篇文章進行有監督的二元分類。
  2. 該算法“學習”識別狗的圖像,並在輸入新圖像時希望生成正確的標籤(如果是狗的圖像則為 1,否則為 0)。

這種設置非常普遍:您的數據可能是症狀,而您的標籤可能是疾病; 或者您的數據可能是手寫字符的圖像,而您的標籤則是它們所代表的實際字符。

感知器:早期的深度學習算法

最早的監督訓練算法之一是感知器,一種基本的神經網絡構建塊。

假設我們在平面上有n個點,分別標記為“0”和“1”。 我們得到了一個新點,我們想猜測它的標籤(這類似於上面的“狗”和“非狗”場景)。 我們該怎麼做呢?

一種方法可能是查看最近的鄰居並返回該點的標籤。 但是一種稍微更智能的方法是選擇一條最能分離標記數據的線並將其用作分類器。

與線性分類器相關的輸入數據描述是深度學習的基本方法。

在這種情況下,每條輸入數據都將表示為一個向量x = ( x_1, x_2 ),我們的函數將類似於“如果在線下方則為'0',如果在線上方則為'1'”。

為了在數學上表示這一點,讓我們的分隔符由權重w和垂直偏移(或偏差) b的向量定義。 然後,我們的函數將輸入和權重與加權和傳遞函數相結合:

加權和傳遞函數

然後將該傳遞函數的結果輸入激活函數以產生標記。 在上面的例子中,我們的激活函數是一個閾值截止(例如,如果大於某個值,則為 1):

這個傳遞函數的結果

訓練感知器

感知器的訓練包括為其提供多個訓練樣本併計算每個樣本的輸出。 在每個樣本之後,權重w以這樣的方式進行調整,以最小化輸出誤差,定義為期望(目標)和實際輸出之間的差異。 還有其他誤差函數,例如均方誤差,但訓練的基本原理保持不變。

單一感知器的缺點

深度學習的單一感知器方法有一個主要缺點:它只能學習線性可分函數。 這個缺點有多嚴重? 以 XOR,一個相對簡單的函數為例,注意它不能被線性分隔符分類(注意失敗的嘗試,下面):

這種深度學習方法的缺點是某些函數無法通過線性分隔符進行分類。

為了解決這個問題,我們需要使用多層感知器,也稱為前饋神經網絡:實際上,我們將這些感知器組合在一起,以創建更強大的學習機制。

用於深度學習的前饋神經網絡

神經網絡實際上只是感知器的組合,以不同的方式連接並在不同的激活函數上運行。

前饋中性網絡深度學習是一種比單個感知器更複雜的方法。

首先,我們將看看前饋神經網絡,它具有以下特性:

  • 輸入、輸出和一個或多個隱藏層。 上圖顯示了一個具有 3 個單元的輸入層、4 個單元的隱藏層和一個具有 2 個單元的輸出層的網絡(術語單元和神經元可以互換)。
  • 每個單元都是一個單一的感知器,就像上面描述的那樣。
  • 輸入層的單元作為隱藏層單元的輸入,而隱藏層單元是輸出層的輸入。
  • 兩個神經元之間的每個連接都有一個權重w (類似於感知器的權重)。
  • t每個單元通常連接到前一層t - 1的每個單元(儘管您可以通過將它們的權重設置為 0 來斷開它們)。
  • 為了處理輸入數據,您將輸入向量“箝制”到輸入層,將向量的值設置為每個輸入單元的“輸出”。 在這種特殊情況下,網絡可以處理 3 維輸入向量(因為有 3 個輸入單元)。 例如,如果您的輸入向量是 [7, 1, 2],那麼您可以將頂部輸入單元的輸出設置為 7,將中間單元的輸出設置為 1,依此類推。 然後使用每個隱藏單元的加權和傳遞函數將這些值向前傳播到隱藏單元(因此稱為前向傳播),進而計算它們的輸出(激活函數)。
  • 輸出層以與隱藏層相同的方式計算其輸出。 輸出層的結果就是網絡的輸出。

超越線性

如果我們的每個感知器只允許使用線性激活函數怎麼辦? 然後,我們網絡的最終輸出仍然是輸入的一些線性函數,只是通過在整個網絡中收集的大量不同權重進行調整。 換句話說,一堆線性函數的線性組合仍然只是一個線性函數。 如果我們僅限於線性激活函數,那麼前饋神經網絡並不比感知器強大,無論它有多少層。

一堆線性函數的線性組合仍然只是一個線性函數,因此大多數神經網絡使用非線性激活函數。

正因為如此,大多數神經網絡使用非線性激活函數,如邏輯、tanh、二進製或整流器。 沒有它們,網絡只能學習作為其輸入線性組合的函數。

訓練感知器

用於多層感知器的監督訓練的最常見的深度學習算法稱為反向傳播。 基本程序:

  1. 訓練樣本被呈現並通過網絡向前傳播。
  2. 計算輸出誤差,通常為均方誤差:

    均方誤差

    其中t是目標值, y是實際的網絡輸出。 其他誤差計算也是可以接受的,但 MSE 是一個不錯的選擇。

  3. 使用稱為隨機梯度下降的方法最小化網絡誤差。

    梯度下降

    梯度下降是通用的,但在神經網絡的情況下,這將是作為輸入參數函數的訓練誤差圖。 每個權重的最佳值是誤差達到全局最小值的那個值。 在訓練階段,權重會以小步驟更新(在每個訓練樣本或幾個樣本的小批量之後),以使它們總是試圖達到全局最小值——但這不是一件容易的事,因為你通常以局部最小值結束,如右邊的那個。 例如,如果權重的值為 0.6,則需要將其更改為 0.4。

    該圖代表最簡單的情況,即誤差取決於單個參數。 然而,網絡誤差取決於每個網絡權重,誤差函數要復雜得多。

    值得慶幸的是,反向傳播提供了一種更新兩個神經元之間關於輸出誤差的每個權重的方法。 推導本身相當複雜,但給定節點的權重更新具有以下(簡單)形式:

    示例表格

    其中E是輸出誤差, w_i是輸入i對神經元的權重。

    本質上,目標是在權重i的梯度方向上移動。 當然,關鍵術語是誤差的導數,它並不總是很容易計算:對於大型網絡中間的隨機隱藏節點的隨機權重,你如何找到這個導數?

    答案:通過反向傳播。 誤差首先在公式非常簡單的輸出單元計算(基於目標值和預測值之間的差異),然後以一種巧妙的方式通過網絡傳播回來,使我們能夠在訓練期間有效地更新權重和(希望)達到最低限度。

隱藏層

隱藏層特別有趣。 通過通用逼近定理,可以訓練具有有限數量神經元的單個隱藏層網絡來逼近任意隨機函數。 換句話說,一個隱藏層就足以學習任何功能。 也就是說,我們經常在實踐中通過多個隱藏層(即更深的網絡)學得更好。

隱藏層是網絡存儲訓練數據的內部抽象表示的地方。

隱藏層是網絡存儲其訓練數據的內部抽象表示的地方,類似於人腦(非常簡化的類比)具有現實世界的內部表示的方式。 在本教程中,我們將研究使用隱藏層的不同方法。

示例網絡

您可以看到一個簡單的(4-2-3 層)前饋神經網絡,它通過testMLPSigmoidBP方法對 Java 實現的 IRIS 數據集進行分類。 該數據集包含三類鳶尾植物,具有萼片長度、花瓣長度等特徵。網絡為每類提供 50 個樣本。 特徵被限制在輸入單元上,而每個輸出單元對應於數據集的一個類別:“1/0/0”表示植物屬於 Setosa 類,“0/1/0”表示 Versicolour,“ 0/0/1” 表示弗吉尼亞)。 分類誤差為 2/150(即,它對 150 個樣本中的 2 個樣本進行了錯誤分類)。

大型網絡的問題

一個神經網絡可以有多個隱藏層:在這種情況下,更高的層是在之前的層之上“構建”新的抽象。 正如我們之前提到的,您通常可以在更大的網絡中學習更好的實踐。

但是,增加隱藏層的數量會導致兩個已知問題:

  1. 梯度消失:隨著我們添加越來越多的隱藏層,反向傳播在將信息傳遞到較低層時變得越來越沒用。 實際上,隨著信息被傳回,梯度開始消失並相對於網絡的權重變小。
  2. 過度擬合:可能是機器學習的核心問題。 簡而言之,過度擬合描述了對訓練數據的擬合過於緊密的現象,可能是假設過於復雜。 在這種情況下,您的學習器最終會非常好地擬合訓練數據,但在真實示例上的表現會差很多。

讓我們看一些深度學習算法來解決這些問題。

自動編碼器

大多數介紹性機器學習課程往往會停止使用前饋神經網絡。 但是可能的網絡空間要豐富得多——所以讓我們繼續。

自編碼器通常是一種前饋神經網絡,旨在學習數據集的壓縮、分佈式表示(編碼)。

自編碼器是一種神經深度學習網絡,旨在學習數據集的特定表示。

從概念上講,網絡被訓練來“重新創建”輸入,即輸入和目標數據是相同的。 換句話說:您嘗試輸出與輸入相同的內容,但以某種方式壓縮。 這是一個令人困惑的方法,所以讓我們看一個例子。

壓縮輸入:灰度圖像

假設訓練數據由 28x28 灰度圖像組成,每個像素的值被箝制到一個輸入層神經元(即輸入層將有 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 = 健康

我們將訓練一個具有六個輸入和六個輸出單元但只有兩個隱藏單元的自動編碼器(使用反向傳播)。

經過數百次迭代,我們觀察到當每個“病態”樣本呈現給機器學習網絡時,兩個隱藏單元之一(每個“病態”樣本的相同單元)總是表現出比其他。 相反,當呈現“健康”樣本時,另一個隱藏單元的激活度更高。

回到機器學習

本質上,我們的兩個隱藏單元已經學習了流感症狀數據集的緊湊表示。 為了了解這與學習有何關係,我們回到過擬合問題。 通過訓練我們的網絡來學習數據的緊湊表示,我們傾向於更簡單的表示,而不是過度擬合訓練數據的高度複雜的假設。

在某種程度上,通過支持這些更簡單的表示,我們正試圖以更真實的方式學習數據。

受限玻爾茲曼機

下一個合乎邏輯的步驟是查看受限玻爾茲曼機 (RBM),這是一種生成隨機神經網絡,可以學習其輸入集的概率分佈

在機器學習中,受限的 Botlzmann Machines 由可見單元和隱藏單元組成。

RBM 由隱藏層、可見層和偏置層組成。 與前饋網絡不同,可見層和隱藏層之間的連接是無向的(值可以在可見到隱藏和隱藏到可見的方向上傳播)和全連接(給定層的每個單元都連接到下一個單元中的每個單元——如果我們允許任何層中的任何單元連接到任何其他層,那麼我們將擁有一個玻爾茲曼(而不是受限玻爾茲曼)機器)。

標準 RBM 具有二進制隱藏和可見單元:即在伯努利分佈下,單元激活為 0 或 1,但也有其他非線性的變體。

雖然研究人員已經了解 RBM 已有一段時間了,但最近引入的對比散度無監督訓練算法重新引起了人們的興趣。

對比分歧

單步對比散度算法 (CD-1) 的工作原理如下:

  1. 正相
    • 輸入樣本v被箝制到輸入層。
    • v以與前饋網絡類似的方式傳播到隱藏層。 隱藏層激活的結果是h
  2. 負相
    • 用結果v'h傳播回可見層(可見層和隱藏層之間的連接是無向的,因此允許雙向移動)。
    • 使用激活結果h'將新的v'傳播回隱藏層。
  3. 體重更新

    體重更新

    其中a是學習率, vv'hh'w是向量。

該算法背後的直覺是正相位( h給定v )反映了網絡對現實世界數據的內部表示。 同時,否定階段表示嘗試基於此內部表示(給定h的 v' )重新創建數據。 主要目標是生成的數據盡可能接近真實世界,這反映在權重更新公式中。

換句話說,網絡對如何表示輸入數據有一些感知,因此它試圖基於這種感知來再現數據。 如果它的再現不夠接近現實,它會進行調整併再次嘗試。

重返流感

為了證明對比分歧,我們將使用與以前相同的症狀數據集。 測試網絡是一個具有六個可見單元和兩個隱藏單元的 RBM。 我們將使用對比散度來訓練網絡,並將症狀v限制在可見層上。 在測試過程中,症狀再次呈現到可見層; 然後,數據被傳播到隱藏層。 隱藏單元代表生病/健康狀態,與自動編碼器非常相似的架構(將數據從可見層傳播到隱藏層)。

經過數百次迭代,我們可以觀察到與自動編碼器相同的結果:當出現任何“生病”樣本時,一個隱藏單元具有更高的激活值,而另一個對於“健康”樣本總是更活躍。

您可以在testContrastiveDivergence方法中看到這個示例。

深度網絡

我們現在已經證明了自動編碼器和 RBM 的隱藏層可以作為有效的特徵檢測器; 但我們很少能直接使用這些功能。 事實上,上面的數據集與其說是規則,不如說是例外。 相反,我們需要找到某種方法來間接使用這些檢測到的特徵。

幸運的是,人們發現這些結構可以堆疊形成深層網絡。 這些網絡可以一次一層地進行貪婪訓練,以幫助克服與經典反向傳播相關的梯度消失過擬合問題。

由此產生的結構通常非常強大,產生令人印象深刻的結果。 以穀歌著名的“貓”論文為例,他們使用特殊類型的深度自動編碼器來“學習”基於未標記數據的人和貓的面部檢測。

讓我們仔細看看。

堆疊自動編碼器

顧名思義,這個網絡由多個堆疊的自動編碼器組成。

堆疊式自動編碼器具有一系列有助於機器學習結果的輸入、輸出和隱藏層。

自編碼器t的隱藏層充當自編碼器t + 1的輸入層。 第一個自編碼器的輸入層是整個網絡的輸入層。 貪婪的逐層訓練過程是這樣工作的:

  1. 使用所有可用訓練數據的反向傳播方法單獨訓練第一個自動編碼器( t=1或上圖中的紅色連接,但帶有額外的輸出層)。
  2. 訓練第二個自動編碼器t=2 (綠色連接)。 由於t=2 的輸入層是 t=1的隱藏層,我們不再對t=1輸出層感興趣,我們將其從網絡中移除。 訓練首先將輸入樣本箝制到t=1的輸入層,然後將其向前傳播到t=2的輸出層。 接下來,使用反向傳播更新t=2的權重(輸入隱藏和隱藏輸出)。 t=2使用所有訓練樣本,類似於t=1
  3. 對所有層重複前面的過程(即,刪除前一個自動編碼器的輸出層,用另一個自動編碼器替換它,並使用反向傳播進行訓練)。
  4. 步驟 1-3 稱為預訓練,並正確初始化權重。 但是,輸入數據和輸出標籤之間沒有映射。 例如,如果網絡被訓練來識別手寫數字的圖像,它仍然不可能將來自最後一個特徵檢測器(即最後一個自動編碼器的隱藏層)的單元映射到圖像的數字類型。 在這種情況下,最常見的解決方案是將一個或多個全連接層添加到最後一層(藍色連接)。 整個網絡現在可以被視為一個多層感知器,並使用反向傳播進行訓練(此步驟也稱為微調)。

因此,堆疊式自動編碼器都是為了提供一種有效的預訓練方法來初始化網絡的權重,從而為您提供一個可以訓練(或微調)的複雜的多層感知器。

深度信念網絡

與自動編碼器一樣,我們也可以堆疊玻爾茲曼機來創建一個稱為深度信念網絡 (DBN)的類。

深度信念網絡由一堆玻爾茲曼機組成。

在這種情況下,RBM ​​t的隱藏層充當 RBM t+1的可見層。 第一個 RBM 的輸入層是整個網絡的輸入層,貪婪的逐層預訓練是這樣工作的:

  1. 使用所有訓練樣本的對比散度訓練第一個 RBM t=1
  2. 訓練第二個 RBM t=2 。 由於t=2 的可見層是 t=1隱藏層,因此訓練首先將輸入樣本箝制到t=1的可見層,然後向前傳播到t=1的隱藏層。 然後,該數據用於啟動t=2的對比散度訓練。
  3. 對所有層重複前面的過程。
  4. 與堆疊式自動編碼器類似,在預訓練之後,可以通過將一個或多個全連接層連接到最終的 RBM 隱藏層來擴展網絡。 這形成了一個多層感知器,然後可以使用反向傳播對其進行微調

這個過程類似於堆疊式自動編碼器,但自動編碼器被 RBM 取代,反向傳播被對比散度算法取代。

(注意:有關構建和訓練堆疊自動編碼器或深度信念網絡的更多信息,請查看此處的示例代碼。)

卷積網絡

作為最終的深度學習架構,讓我們看一下卷積網絡,這是一種特別有趣且特殊的前饋網絡,非常適合圖像識別。

卷積網絡是一類特殊的深度學習前饋網絡。
圖片來自 DeepLearning.net

在我們查看卷積網絡的實際結構之前,我們首先定義一個圖像過濾器,或者一個帶有相關權重的正方形區域。 過濾器應用於整個輸入圖像,您通常會應用多個過濾器。 例如,您可以將四個 6x6 過濾器應用於給定的輸入圖像。 然後,坐標為 1,1 的輸出像素是左上角為 1,1 的 6x6 平方輸入像素與濾波器的權重(也是 6x6 平方)的加權和。 輸出像素 2,1 是左上角為 2,1 的輸入正方形的結果,依此類推。

綜上所述,這些網絡由以下屬性定義:

  • 卷積層將許多過濾器應用於輸入。 例如,圖像的第一個卷積層可能有四個 6x6 濾波器。 在圖像上應用一個過濾器的結果稱為特徵圖(FM),特徵圖的數量等於過濾器的數量。 如果前一層也是卷積層,則濾波器將應用於所有具有不同權重的 FM,因此每個輸入 FM 都連接到每個輸出 FM。 圖像中共享權重背後的直覺是,無論它們的位置如何,都會檢測到特徵,而濾波器的多樣性允許它們中的每一個檢測不同的特徵集。
  • 二次採樣層減少了輸入的大小。 例如,如果輸入由 32x32 圖像組成,並且該層的子採樣區域為 2x2,則輸出值將是 16x16 圖像,這意味著輸入圖像的 4 個像素(每個 2x2 正方形)被組合成一個輸出像素。 有多種子採樣方式,但最流行的是最大池化、平均池化和隨機池化。
  • 最後一個子採樣(或卷積)層通常連接到一個或多個全連接層,其中最後一個代表目標數據。
  • 使用修改後的反向傳播執行訓練,該反向傳播將子採樣層考慮在內,並根據應用該過濾器的所有值更新卷積過濾器權重。

您可以在這裡看到在 MNIST 數據集(手寫字母的灰度圖像)上訓練(使用反向傳播)的捲積網絡的幾個示例,特別是在testLeNet*方法中(我推薦testLeNetTiny2 ,因為它實現了大約 2% 的低錯誤率在相對較短的時間內)。 這裡還有一個類似網絡的不錯的 JavaScript 可視化。

執行

既然我們已經介紹了最常見的神經網絡變體,我想我應該寫一些關於在實施這些深度學習結構過程中所面臨的挑戰。

從廣義上講,我創建深度學習庫的目標是(現在仍然是)構建一個滿足以下標準的基於神經網絡的框架:

  • 一種能夠表示不同模型的通用架構(例如,我們在上面看到的所有神經網絡變體)。
  • 使用多種訓練算法(反向傳播、對比散度等)的能力。
  • 體面的表現。

為了滿足這些要求,我採用分層(或模塊化)方法來設計軟件。

結構

讓我們從基礎開始:

  • NeuralNetworkImpl 是所有神經網絡模型的基類。
  • 每個網絡都包含一組層。
  • 每層都有一個連接列表,其中連接是兩層之間的鏈接,因此網絡是有向無環圖。

這種結構足夠靈活,可用於經典的前饋網絡,以及 RBM 和更複雜的架構,如 ImageNet。

它還允許一個層成為多個網絡的一部分。 例如,深度信念網絡中的層也是其相應 RBM 中的層。

此外,這種架構允許在預訓練階段將 DBN 視為堆疊 RBM 的列表,在微調階段將 DBN 視為前饋網絡,這既直觀又方便。

數據傳播

下一個模塊負責通過網絡傳播數據,這是一個兩步過程:

  1. 確定圖層的順序。 例如,為了從多層感知器中獲取結果,數據被“箝制”到輸入層(因此,這是要計算的第一層)並一直傳播到輸出層。 為了在反向傳播期間更新權重,輸出誤差必須以廣度優先順序傳播到每一層,從輸出層開始。 這是使用LayerOrderStrategy的各種實現來實現的,它利用網絡的圖結構,採用不同的圖遍歷方法。 一些示例包括廣度優先策略和特定層的定位。 順序實際上是由層之間的連接決定的,因此這些策略會返回一個有序的連接列表。
  2. 計算激活值。 每個層都有一個關聯的ConnectionCalculator ,它獲取它的連接列表(來自上一步)和輸入值(來自其他層)併計算結果激活。 例如,在一個簡單的 sigmoid 前饋網絡中,隱藏層的ConnectionCalculator獲取輸入層和偏置層的值(分別是輸入數據和1的數組)以及單元之間的權重(在完全連接的情況下)層,權重實際上作為Matrix存儲在完全連接的連接中,計算加權和,並將結果輸入 sigmoid 函數。 連接計算器實現了各種傳輸(例如,加權和、卷積)和激活(例如,多層感知器的邏輯和 tanh,RBM ​​的二進制)功能。 它們中的大多數可以使用 Aparapi 在 GPU 上執行,並可用於小批量訓練。

使用 Aparapi 進行 GPU 計算

正如我前面提到的,近年來神經網絡重新興起的原因之一是它們的訓練方法非常有利於並行性,可以讓您使用 GPGPU 顯著加快訓練速度。 在這種情況下,我選擇使用 Aparapi 庫來添加 GPU 支持。

Aparapi 對連接計算器施加了一些重要的限制:

  • 只允許原始數據類型的一維數組(和變量)。
  • 僅允許從 GPU 可執行代碼調用 Aparapi Kernel類本身的成員方法。

因此,大部分數據(權重、輸入和輸出數組)都存儲在Matrix實例中,這些實例在內部使用一維浮點數組。 所有 Aparapi 連接計算器都使用AparapiWeightedSum (用於全連接層和加權和輸入函數)、 AparapiSubsampling2D (用於子採樣層)或AparapiConv2D (用於卷積層)。 引入異構系統架構可以克服其中一些限制。 Aparapi 還允許在 CPU 和 GPU 上運行相同的代碼。

訓練

訓練模塊實現了各種訓練算法。 它依賴於前兩個模塊。 For example, BackPropagationTrainer (all the trainers are using the Trainer base class) uses feedforward layer calculator for the feedforward phase and a special breadth-first layer calculator for propagating the error and updating the weights.

My latest work is on Java 8 support and some other improvements, will soon be merged into master.

結論

The aim of this Java deep learning tutorial was to give you a brief introduction to the field of deep learning algorithms, beginning with the most basic unit of composition (the perceptron) and progressing through various effective and popular architectures, like that of the restricted Boltzmann machine.

The ideas behind neural networks have been around for a long time; but today, you can't step foot in the machine learning community without hearing about deep networks or some other take on deep learning. Hype shouldn't be mistaken for justification, but with the advances of GPGPU computing and the impressive progress made by researchers like Geoffrey Hinton, Yoshua Bengio, Yann LeCun and Andrew Ng, the field certainly shows a lot of promise. There's no better time to get familiar and get involved like the present.

Appendix: Resources

If you're interested in learning more, I found the following resources quite helpful during my work:

  • DeepLearning.net: a portal for all things deep learning. It has some nice tutorials, software library and a great reading list.
  • An active Google+ community.
  • Two very good courses: Machine Learning and Neural Networks for Machine Learning, both offered on Coursera.
  • The Stanford neural networks tutorial.
Related: Schooling Flappy Bird: A Reinforcement Learning Tutorial