作為開發(fā)人員,我們習(xí)慣從用命令或函數(shù)的角度來思考問題。程序由任務(wù)組成,每個任務(wù)都包含一些編程結(jié)構(gòu)。神經(jīng)網(wǎng)絡(luò)不同于這種編程方法,因為它加入了自動任務(wù)改進(jìn)的概念,或者類似于大腦的學(xué)習(xí)和改進(jìn)的能力。換句話說,神經(jīng)網(wǎng)絡(luò)在沒有特定任務(wù)編程的情況下主動學(xué)習(xí)新的活動。
本教程不是教你從頭開始編寫神經(jīng)網(wǎng)絡(luò)的教程,而是介紹結(jié)合Java代碼的神經(jīng)網(wǎng)絡(luò)。本文主要內(nèi)容是首先介紹神經(jīng)網(wǎng)絡(luò)的發(fā)展從McCulloch和Pitt的神經(jīng)元開始,然后通過Hebb的發(fā)現(xiàn),實現(xiàn)了Rosenblatt的感知器來增強它,并說明了它為什么不能解決XOR問題。其次介紹了通過連接神經(jīng)元,生成一個多層感知器,并通過應(yīng)用反向傳播算法進(jìn)行學(xué)習(xí),從而實現(xiàn)XOR問題的解決方案。最后在演示神經(jīng)網(wǎng)絡(luò)實現(xiàn)、訓(xùn)練算法和測試之后,介紹利用一些致力于深度學(xué)習(xí)的開源Java ML框架如Neuroph、Encog和Deeplearning4j來快速實現(xiàn)神經(jīng)網(wǎng)絡(luò):
早期的人造神經(jīng)元模型是由神經(jīng)生理學(xué)家Warren McCulloch和邏輯學(xué)家Walter Pitts在1943年引入的。他們的論文名為“神經(jīng)活動的邏輯微積分”,通常被認(rèn)為是神經(jīng)網(wǎng)絡(luò)研究的開始。mcculloch - pitts神經(jīng)元工作原理是對每一個輸入輸入1或0,其中1為真,0為假,然后給神經(jīng)元分配一個二元閾值激活函數(shù)來計算神經(jīng)元的輸出。
該閾值給定一個實際值,比如1,如果閾值達(dá)到或超過閾值,則允許輸出0或1。此外,為了表示AND函數(shù),我們設(shè)置2.0的閾值,如下表所示:
如果我們將閾值切換到1,那么這個方法也可以應(yīng)用于OR函數(shù)。到目前為止,我們具有如表所示的典型的線性可分離數(shù)據(jù),我們可以使用直線來劃分?jǐn)?shù)據(jù)。 然而,McCulloch-Pitts神經(jīng)元有一些嚴(yán)重的局限性。它既不能解決“異或”功能(XOR)也不能解決不是線性分離的“排他性”功能(XNOR)。 唐納德·赫布(Donald Hebb)提出下一次革命,他以關(guān)于Hebbian學(xué)習(xí)的理論而聞名。在他1949年出版的《行為的組織》一書中這樣寫道:
當(dāng)細(xì)胞A的軸突足夠接近細(xì)胞B,不斷反復(fù)持續(xù)的激活細(xì)胞B,兩個細(xì)胞之間就會產(chǎn)生生長過程或代謝變化,這樣A的效率提高了,就像燃燒了細(xì)胞B一樣”。
換句話說,當(dāng)一個神經(jīng)元不停地觸發(fā)另一個神經(jīng)元時,第一個神經(jīng)元的軸突/連接就會形成突觸小結(jié),如果它們已經(jīng)與第二個神經(jīng)元連接,就會放大它們。Hebb不僅提出,當(dāng)兩個神經(jīng)元一起點燃神經(jīng)元之間的連接時,神經(jīng)元之間的聯(lián)系就會增強——這被稱為神經(jīng)元之間連接的權(quán)重——還提出這個活動是學(xué)習(xí)和記憶所必需的基本操作之一。因此必須改變McCulloch-Pitts神經(jīng)元,以便為每個輸入分配權(quán)重。 此外,相對于總閥值量,1的輸入或多或少都被被賦予了權(quán)重。
后來,在1962年,由Frank Rosenblatt在他的《神經(jīng)動力學(xué)原理》一書中定義并描述了感知器。這是一個神經(jīng)元的模型,它可以通過輸入的權(quán)重在Hebbean Sense 中學(xué)習(xí),并為后來神經(jīng)網(wǎng)絡(luò)的發(fā)展奠定了基礎(chǔ)。感知器學(xué)習(xí)使用隨機權(quán)重初始化感知器,在激活后反復(fù)檢查答案是否正確。如果不正確,神經(jīng)網(wǎng)絡(luò)可以從錯誤中學(xué)習(xí)并調(diào)整它的權(quán)重。
盡管感知器對原始McCulloch-Pitts神經(jīng)元進(jìn)行了許多改變,但感知器仍然局限于解決某些功能。1969年,Minsky與Seymour Papert,合著了” 感知器:計算幾何的介紹”,在文章中攻擊了感知器的局限性。文章中表明,感知器只能解決線性可分函數(shù),并沒有打破這點的限制。直到20世紀(jì)80年代以前,這方面的研究還很少?,F(xiàn)在解決這些困難的方法之一就是建立神經(jīng)網(wǎng)絡(luò)。這些網(wǎng)絡(luò)將人工神經(jīng)元的輸入與其他人工神經(jīng)元的輸出連接起來。因此,網(wǎng)絡(luò)能夠解決更困難的問題,但它們也會變得相當(dāng)復(fù)雜。但感知器沒有解決的XOR問題。如果我們仔細(xì)觀察真值表,我們可以看到XOR函數(shù)變成等價于單個神經(jīng)元可表示的OR和NOT AND函數(shù)。
讓我們再來看看真值表:
但是我們可以將代表NOT和AND的兩個神經(jīng)元結(jié)合起來,并構(gòu)建一個神經(jīng)網(wǎng)絡(luò)來解決類似于下圖所示的XOR問題:
這個圖表示多層感知器,它有一個輸入層,一個隱藏層和一個輸出層。神經(jīng)元之間的連接與圖片中沒有顯示的權(quán)重有關(guān)。與單一感知器類似,每個處理單元都有一個summing和激活組件。它看起來很簡單,但我們也需要一個訓(xùn)練算法來調(diào)整各個層次的權(quán)重,并讓它學(xué)習(xí)。通過簡單的感知器,我們可以很容易地根據(jù)誤差計算變化權(quán)重。從而訓(xùn)練多層感知器實現(xiàn)計算神經(jīng)網(wǎng)絡(luò)的整體錯誤。
1986年,Geoffrey Hinton,David Rumelhart和Ronald Williams發(fā)表了一篇論文,“通過反向傳播錯誤學(xué)習(xí)表示”,描述了一個新的學(xué)習(xí)過程,反向傳播。該過程反復(fù)調(diào)整網(wǎng)絡(luò)中連接的權(quán)重,從而最小化網(wǎng)絡(luò)實際輸出向量和所需輸出向量之間的差值。作為權(quán)重調(diào)整的結(jié)果,內(nèi)部隱藏的單元(不是輸入或輸出的一部分)被用來表示重要的特征,并且這些單元通過交互捕獲規(guī)律性任務(wù)。
現(xiàn)在我們已經(jīng)能夠編寫使用Java學(xué)習(xí)XOR函數(shù)的多層感知器。這需要創(chuàng)建一些類,比如名為ProcessingUnit的神經(jīng)元接口,連接類,一些更活躍的函數(shù),以及一個能夠?qū)W習(xí)的單層神經(jīng)網(wǎng)絡(luò)。在我的GitHub存儲庫中你可以在項目中找到這些接口和類。
其中NeuralNet類負(fù)責(zé)對層的構(gòu)造和初始化。它還提供了訓(xùn)練和評估激活結(jié)果的功能。 如果運行NeuralNet類來解決典型的XOR問題,它將激活,評估結(jié)果,應(yīng)用反向傳播算法和輸出訓(xùn)練結(jié)果。
如果你仔細(xì)查看代碼,你會發(fā)現(xiàn)它在可重用性方面并不是非常靈活。如果我們將NeuralNet結(jié)構(gòu)從訓(xùn)練部分分離出來,變成把各種學(xué)習(xí)算法應(yīng)用在各種神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)上,那就更好了。此外,我們想要更深入的學(xué)習(xí)結(jié)構(gòu)和各種激活函數(shù),則必須改變數(shù)據(jù)結(jié)構(gòu)。因為到目前為止,只有一個隱藏層被定義。為了確保不產(chǎn)生任何bug,反向傳播計算必須經(jīng)過仔細(xì)的測試。一旦完成了所有的重構(gòu),我們就必須開始考慮深層神經(jīng)網(wǎng)絡(luò)的性能。
我想說的是,如果我們進(jìn)行實際開發(fā),那么首先需要看看現(xiàn)有的神經(jīng)網(wǎng)絡(luò)庫。雖然從頭開始實現(xiàn)神經(jīng)網(wǎng)絡(luò)有助于理解整個網(wǎng)絡(luò)的細(xì)節(jié),但是如果一個真實的解決方案必須從頭開始實施,那么將要付出很大的努力。在本文中,我只選擇了純Java神經(jīng)網(wǎng)絡(luò)庫。盡管Deeplearning4j得到了商業(yè)支持,但所有這些都是開源的。網(wǎng)上都有大量的參考文檔和例子。其中Deeplearning4j也支持CUDA。維基百科也提供了一份關(guān)于各種語言的深度學(xué)習(xí)軟件的綜合列表。
如何使用神經(jīng)網(wǎng)絡(luò)庫的示例也被包含在關(guān)于使用XOR NeuralNet的GitHub中。很明顯,在開發(fā)中利用現(xiàn)成的函數(shù)庫與自己編寫java代碼相比工作量要少很多。其中Neuroph是為數(shù)據(jù)集提供的API,它更容易初始化訓(xùn)練數(shù)據(jù),學(xué)習(xí)規(guī)則的層次結(jié)構(gòu),進(jìn)行神經(jīng)網(wǎng)絡(luò)串行化/持久性和反序列化,并帶有GUI。Encog是一種先進(jìn)的機器學(xué)習(xí)框架,支持多種高級算法,也支持規(guī)范化類和處理數(shù)據(jù)。然而,它的主要優(yōu)勢在于神經(jīng)網(wǎng)絡(luò)算法。Encog包含創(chuàng)建各種網(wǎng)絡(luò)的類,以及支持這些神經(jīng)網(wǎng)絡(luò)的規(guī)范化和處理數(shù)據(jù)的支持類。Deeplearning4j是一個非常強大的庫,支持多種算法,包括與Apache Hadoop和Spark集成的分布式并行版本。對于有經(jīng)驗的開發(fā)人員和軟件架構(gòu)師來說,這絕對是正確的選擇。這里作為神經(jīng)網(wǎng)絡(luò)庫的一部分提供了一個XOR示例。
想在要利用現(xiàn)有的眾多神經(jīng)網(wǎng)絡(luò)庫,開發(fā)人員需要熟悉各種各樣的參數(shù),從而讓他們的神經(jīng)網(wǎng)絡(luò)進(jìn)行學(xué)習(xí)。本文演示了一個非常簡單的例子,它包含神經(jīng)元和反向傳播。然而,今天使用的許多人工神經(jīng)網(wǎng)絡(luò)仍然來使用mcculloch - pitts神經(jīng)元和Rosenblatt感知器的早期版本。作為構(gòu)建現(xiàn)代深層神經(jīng)網(wǎng)絡(luò)的基石,重要的是要理解神經(jīng)元的根,并在庫中利用好現(xiàn)成的神經(jīng)元、層、激活函數(shù)和學(xué)習(xí)算法。
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4798瀏覽量
102420 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4365瀏覽量
63916 -
神經(jīng)元
+關(guān)注
關(guān)注
1文章
368瀏覽量
18718
發(fā)布評論請先 登錄
神經(jīng)網(wǎng)絡(luò)教程(李亞非)
labview BP神經(jīng)網(wǎng)絡(luò)的實現(xiàn)
全連接神經(jīng)網(wǎng)絡(luò)和卷積神經(jīng)網(wǎng)絡(luò)有什么區(qū)別
卷積神經(jīng)網(wǎng)絡(luò)如何使用
【案例分享】ART神經(jīng)網(wǎng)絡(luò)與SOM神經(jīng)網(wǎng)絡(luò)
人工神經(jīng)網(wǎng)絡(luò)實現(xiàn)方法有哪些?
如何構(gòu)建神經(jīng)網(wǎng)絡(luò)?
matlab實現(xiàn)神經(jīng)網(wǎng)絡(luò) 精選資料分享
基于BP神經(jīng)網(wǎng)絡(luò)的PID控制
神經(jīng)網(wǎng)絡(luò)移植到STM32的方法
卷積神經(jīng)網(wǎng)絡(luò)模型發(fā)展及應(yīng)用
三個最流行神經(jīng)網(wǎng)絡(luò)

評論