最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

最簡單的人工神經(jīng)網(wǎng)絡(luò)

2021-08-27 19:00 作者:HelloGitHub  | 我要投稿


導(dǎo)言

我不會機器學(xué)習(xí),但上個月我在 GitHub 上發(fā)現(xiàn)了一個極簡、入門級的神經(jīng)網(wǎng)絡(luò)教程。它簡潔易懂能用一行公式說明白的道理,不多寫一句廢話,我看后大呼過癮。


這么好的東西得讓更多人看到,但原文是英文的無法直接分享,所以得先聯(lián)系作者拿到翻譯的授權(quán),然后由小熊熊翻譯了這個項目,最后才有您看到的這篇文章。過程艱辛耗時一個月實屬不易,如果您看完覺得還不錯,歡迎點贊、分享給更多人。

內(nèi)容分為兩部分:

  • 第一部分:最簡單的人工神經(jīng)網(wǎng)絡(luò)
  • 第二部分:最基礎(chǔ)的反向傳播算法

人工神經(jīng)網(wǎng)絡(luò)是人工智能的基礎(chǔ),只有夯實基礎(chǔ),才能玩轉(zhuǎn) AI 魔法!

溫馨提示:公式雖多但只是看起來唬人,實際耐下心讀并不難懂。下面正文開始!

一、最簡單的人工神經(jīng)網(wǎng)絡(luò)

通過理論和代碼解釋和演示的最簡單的人工神經(jīng)網(wǎng)絡(luò)。

理論

模擬神經(jīng)元

受人腦工作機制的啟發(fā),人工神經(jīng)網(wǎng)絡(luò)有著相互連接的模擬神經(jīng)元,用于存儲模式和相互溝通。一個模擬神經(jīng)元最簡單的形式是有一個或多個輸入值xi和一個輸出值y ,其中每個xi 有一個權(quán)重wi 。


拿最簡單的來說,輸出值就是輸入值乘以權(quán)重之后的總和。

y=i=1∑nwixi

一個簡單的例子

網(wǎng)絡(luò)的作用在于通過多個參數(shù)w 模擬一個復(fù)雜的函數(shù),從而可以在給定一系列輸入值x 的時候得到一個特定的輸出值y ,而這些參數(shù)w 通常是我們自身難以擬定的。

假設(shè)我們現(xiàn)在的一個網(wǎng)絡(luò)有兩個輸入值x1=0.2 ,x2=0.4,它們對應(yīng)兩個權(quán)重值w1 和w2 。

現(xiàn)在我們需要調(diào)整權(quán)重值,從而使得它們可以產(chǎn)生我們預(yù)設(shè)的輸出值。

在初始化時,因為我們不知曉最優(yōu)值,往往是對權(quán)重隨機賦值,這里我們?yōu)榱撕唵?,將它們都初始化?1 。


這種情況下,我們得到的就是

y=x1w1+x2w2=0.2?1+0.4?1=0.6

誤差值

如果輸出值y 與我們期望的輸出值不一致,那就有了誤差。

例如,如果我們希望目標(biāo)值是t=0.5 ,那么這里相差值就是

y?t=0.6?0.5=0.1

通常我們會采用方差(也就是代價函數(shù))來衡量誤差:

E=21(y?t)2

如果有多套輸入輸出值,那么誤差就是每組方差的平均值。

E=2n1(yi?ti)2

我們用方差來衡量得到的輸出值與我們期望的目標(biāo)值之間的差距。通過平方的形式就可以去除負偏離值的影響,更加凸顯那些偏離較大的偏差值(不管正負)。

為了糾正誤差,我們需要調(diào)整權(quán)重值,以使得結(jié)果趨近于我們的目標(biāo)值。在我們這個例子中,將w1 從 1.0 降到 0.5 就可以達到目標(biāo),因為

y=t=0.2?0.5+0.4?1.0=0.5

然而,神經(jīng)網(wǎng)絡(luò)往往涉及到許多不同的輸入和輸出值,這種情況下我們就需要一個學(xué)習(xí)算法來幫我們自動完成這一步。

梯度下降

現(xiàn)在是要借助誤差來幫我們找到應(yīng)該被調(diào)整的權(quán)重值,從而使得誤差最小化。但在這之前,讓我們了解一下梯度的概念。

什么是梯度?

梯度本質(zhì)上是指向一個函數(shù)最大斜率的矢量。我們采用 ▽ 來表示梯度,簡單說來,它就是函數(shù)變量偏導(dǎo)數(shù)的矢量形式。

對于一個雙變量函數(shù),它采用如下形式表示:

f(x,y)=[fx,fy]=[exef(x,y),eyef(x,y)]

讓我們用一些數(shù)字來模擬一個簡單的例子。假設(shè)我們有一個函數(shù)是f(x,y)=2x2+3y3,那么梯度將是

f(x,y)=[4x,9y2]

什么是梯度下降?

下降則可以簡單理解為通過梯度來找到我們函數(shù)最大斜率的方向,然后通過反方向小步幅的多次嘗試,從而找到使函數(shù)全局(有時是局部)誤差值最小的權(quán)重。

我們采用一個稱為學(xué)習(xí)率的常量來表示這個反方向的小步幅,在公式中我們用ε 來進行表征。

如果ε 取值太大,那有可能直接錯過最小值,但如果取值太小,那我們的網(wǎng)絡(luò)就會花費更久的時間來學(xué)習(xí),而且也有可能陷入一個淺局部最小值。


對于我們例子中的兩個權(quán)重值w1 和w2 ,我們需要找到這兩個權(quán)重值相較于誤差函數(shù)的梯度

wE=<ew1eE,ew2eE>

還記得我們上面的公式E=21(y?t)2 和y=x1w1+x2w2 嗎?對于w1 和w2 ,我們可以將其帶入并通過微積分中的鏈?zhǔn)角髮?dǎo)法則來分別計算其梯度

ewieE=eyeEewiey=eye(21(y?t)2)ewie(xiwi)=(y?t)xi

簡潔起見,后面我們將采用δ 這個術(shù)語來表示 eyeE=y?t 。

一旦我們有了梯度,將我們擬定的學(xué)習(xí)率ε 帶入,可以通過如下方式來更新權(quán)重值:

w1=w1?εw1E=w1?εδx1

w2=w2?εw2E=w2?εδx2

然后重復(fù)這個過程,直到誤差值最小并趨近于零。

代碼示例

附帶的示例采用梯度下降法,將如下數(shù)據(jù)集訓(xùn)練成有兩個輸入值和一個輸出值的神經(jīng)網(wǎng)絡(luò):

x=[1.01.01.00.0]y′=[0.01.0]

一旦訓(xùn)練成功,這個網(wǎng)絡(luò)將會在輸入兩個 1 時輸出 ~0,在輸入 1 和 0 時,輸出 ~1 。

怎么運行?

Go

PS D:\github\ai-simplest-network-master\src> go build -o bin/test.exePS D:\github\ai-simplest-network-master\bin> ./test.exeerr: 1.7930306267024234err: 1.1763080417089242……err: 0.00011642621631266815err: 0.00010770190838306002err: 9.963134967988221e-05Finished after 111 iterationsResults ----------------------[1 1] => [0.007421243532258703][1 0] => [0.9879921757260246]

Docker

docker build -t simplest-network .docker run --rm simplest-network

二、最基礎(chǔ)的反向傳播算法

反向傳播(英語:Backpropagation,縮寫為 BP)是“誤差反向傳播”的簡稱,是一種與最優(yōu)化方法(如梯度下降法)結(jié)合使用的,用來訓(xùn)練人工神經(jīng)網(wǎng)絡(luò)的常見方法。

反向傳播技術(shù)可以用來訓(xùn)練至少有一個隱藏層的神經(jīng)網(wǎng)絡(luò)。下面就來從理論出發(fā)結(jié)合代碼拿下反向傳播算法。

理論

感知機介紹

感知機是這樣一個處理單元:它接受輸入x, 采用激活函數(shù)f 對其進行轉(zhuǎn)換,并輸出結(jié)果y 。

在一個神經(jīng)網(wǎng)絡(luò),輸入值是前一層節(jié)點輸出值的權(quán)重加成總和,再加上前一層的誤差:

xj=i=1∑Ixiwij+bi

如果我們把誤差當(dāng)作層中另外的一個常量為 -1 的節(jié)點,那么我們可以簡化這個公式為

xj=i=1∑I+1xiwij


激活函數(shù)

為什么我們需要激活函數(shù)呢?如果沒有,我們每個節(jié)點的輸出都會是線性的,從而讓整個神經(jīng)網(wǎng)絡(luò)都會是基于輸入值的一個線性運算后的輸出。因為線性函數(shù)組合仍然是線性的,所以必須要引入非線性函數(shù),才能讓神經(jīng)網(wǎng)絡(luò)有區(qū)別于線性回歸模型。

針對x=∑xw,典型的激活函數(shù)有以下形式:

Sigmoid 函數(shù) :y=1+e?x1

線性整流函數(shù):y=max(0,x)

tanh 函數(shù):y=tanh(x)

反向傳播

反向傳播算法可以用來訓(xùn)練人工神經(jīng)網(wǎng)絡(luò),特別是針對具有多于兩層的網(wǎng)絡(luò)。

原理是采用 forward pass 來計算網(wǎng)絡(luò)輸出值和誤差,再根據(jù)誤差梯度反向更新輸入層的權(quán)重值。

術(shù)語

  • xi,xj,xk 分別是 I, J, K 層節(jié)點的輸入值。
  • yi,yj,yk 分別是 I, J, K 層節(jié)點的輸出值。
  • yk′ 是 K 輸出節(jié)點的期望輸出值。
  • wij,wjk 分別是 I 到 J 層和 J 到 K 層的權(quán)重值。
  • t 代表 T 組關(guān)聯(lián)中當(dāng)前的一組關(guān)聯(lián)。

在下面的示例中,我們將對不同層節(jié)點采用以下激活函數(shù):

  • 輸入層 -> 恒等函數(shù)
  • 隱藏層 -> Sigmoid 函數(shù)
  • 輸出層 -> 恒等函數(shù)

The forward pass

在 forward pass 中,我們在輸入層進行輸入,在輸出層得到結(jié)果。

對于隱藏層的每個節(jié)點的輸入就是輸入層輸入值的加權(quán)總和:

xj=i=1∑Iwijyi

因為隱藏層的激活函數(shù)是 sigmoid,那么輸出將會是:

yj=fj(xj)=1+e?xj1

同樣,輸出層的輸入值則是

xk=j=1∑Jwjkyj

因為我們賦予了恒等函數(shù)做為激活函數(shù),所以這一層的輸出將等同于輸入值。

yk=fk(xk)=xk

一旦輸入值通過網(wǎng)絡(luò)進行傳播,我們就可以計算出誤差值。如果有多套關(guān)聯(lián),還記得我們第一部分學(xué)習(xí)的方差嗎?這里,我們就可以采用平均方差來計算誤差。

E=i=1∑IEt=2T1t=1∑T(ykt?ykt′)2

The backward pass

現(xiàn)在我們已經(jīng)得到了誤差,就可以通過反向傳輸,來用誤差來修正網(wǎng)絡(luò)的權(quán)重值。

通過第一部分的學(xué)習(xí),我們知道對權(quán)重的調(diào)整可以基于誤差對權(quán)重的偏導(dǎo)數(shù)乘以學(xué)習(xí)率,即如下形式

Δwjk=?ε?wjk?E

我們通過鏈?zhǔn)椒▌t計算出誤差梯度,如下:

?wjk?E=?xk?E?wjk?xk

?xk?E=?yk?E?xk?yk=?yk?(21(yk?yk′)2)?xk?(xk)=yk?yk′=δk

?wjk?xk=?wjk?(yjwjk)=yj

因此,對權(quán)重的調(diào)整即為 Δwjk=?εδkyj

對于多個關(guān)聯(lián),那么對權(quán)重的調(diào)整將為每個關(guān)聯(lián)的權(quán)重調(diào)整值之和 Δwjk=?εt=1Tδkyjt

類似地,對于隱藏層之間的權(quán)重調(diào)整,繼續(xù)以上面的例子為例,輸入層和第一個隱藏層之間的權(quán)重調(diào)整值為

Δwij=?ε?wij?E

?wij?E=?xj?E?wij?xj=δjyi

那么,基于所有關(guān)聯(lián)的權(quán)重調(diào)整即為每次關(guān)聯(lián)計算得到的調(diào)整值之和 Δwij=?εt=1Tδjtyit

δj計算

這里, 我們對δj 可以再做進一步的探索。上文中,我們看到 ?wij?E=?xj?E?wij?xj

對前半部分的 ?xj?E ,我們可以有

?xj?E=?yj?Edxjdyj

?yj?E=k=1∑K?xk?E?yj?xk=k=1∑Kδkwjk

對后半部分的dxjdyj ,因為我們在這一層采用了 sigmoid 函數(shù),我們知道,sigmoid 函數(shù)的導(dǎo)數(shù)形式是f(x)(1?f(x)) ,因此,有

dxjdyj=f′(xj)=f(xj)(1?f(xj))=yj(1?yj)

綜上,便可以得到δj 的計算公式如下

δj=yj(1?yj)k=1∑Kδkwjk

算法總結(jié)

首先,對網(wǎng)絡(luò)權(quán)重值賦予一個小的隨機值。

重復(fù)以下步驟,直到誤差為0 :

  • 對每次關(guān)聯(lián),通過神經(jīng)網(wǎng)絡(luò)向前傳輸,得到輸出值
    • 計算每個輸出節(jié)點的誤差 (δk=yk?yk′)
    • 疊加計算每個輸出權(quán)重的梯度 (▽wjkE=δkyj
    • 計算隱藏層每個節(jié)點的δδj=yj(1?yj)∑k=1Kδkwjk
    • 疊加計算每個隱藏層權(quán)重的梯度 (▽wijE=δjyj
  • 更新所有權(quán)重值,重置疊加梯度 (w=w?εE

圖解反向傳播

在這個示例中,我們通過真實數(shù)據(jù)來模擬神經(jīng)網(wǎng)絡(luò)中的每個步驟。輸入值是[1.0, 1.0],輸出期望值為 [0.5]。為了簡化,我們將初始化權(quán)重設(shè)為 0.5 (雖然在實際操作中,經(jīng)常會采用隨機值)。對于輸入、隱藏和輸出層,我們分別采用恒等函數(shù)、 sigmoid 函數(shù) 和恒等函數(shù)作為激活函數(shù),學(xué)習(xí)率ε 則定為 0.01 。

Forward pass

運算一開始,我們將輸入層的節(jié)點輸入值設(shè)為x1=1.0,x2=1.0 。

因為我們對輸入層采用的是恒等函數(shù)作為激活函數(shù),因此有yi=xi=1.0 。


接下來,我們通過對前一層的加權(quán)總和將網(wǎng)絡(luò)向前傳遞到 J 層,如下

xj=i=1∑Iyiwij=1.0?0.5+1.0?0.5=1.0


然后,我們將 J 層節(jié)點的值輸入到 sigmoid 函數(shù)(f(x)=1+e?x1,將x=1 代入,得到 0.731)進行激活。


最后,我們將這個結(jié)果傳遞到最后的輸出層。

xk=0.731?0.5+0.731?0.5=0.731

因為我們輸出層的激活函數(shù)也是恒等函數(shù),因此yk=xk=0.731


Backward pass

反向傳播的第一步,是計算輸出節(jié)點的δ ,

δk=yk?yk′=0.731?0.5=0.231


采用δ 計算 J 和 K 兩層節(jié)點間的權(quán)重梯度:▽wjkE=δkyj=0.231?0.731=0.168861


接下來,以同樣的方法計算每個隱藏層的δ 值(在本示例中,僅有一個隱藏層):

δj=yj(1?yj)k=1∑Kδkwjk=0.731?(1?0.731)?(0.5?0.231)≈0.0227


針對 I 和 J 層節(jié)點權(quán)重計算其梯度為:

wijE=δjyi=0.0227?1=0.0227


最后一步是用計算出的梯度更新所有的權(quán)重值。注意這里如果我們有多于一個的關(guān)聯(lián),那么便可以針對每組關(guān)聯(lián)的梯度進行累計,然后更新權(quán)重值。

wij=wij?εwijE=0.5?0.01?0.0227=0.499773

wjk=wjk?εwjkE=0.5?0.01?0.168861=0.49831139


可以看到這個權(quán)重值變化很小,但如果我們用這個權(quán)重再跑一遍 forward pass,一般來說將會得到一個比之前更小的誤差。讓我們現(xiàn)在來看下……

第一遍我們得到的y1=0.731,采用新的權(quán)重值計算得到y2≈0.7285。

由此,y1?y1′=0.231,而y2?y2′=0.2285。

可見,誤差得到了減??!盡管減少值很小,但對于一個真實場景也是很有代表性的。按照該算法重復(fù)運行,一般就可以將誤差最終減小到0,那么便完成了對神經(jīng)網(wǎng)絡(luò)的訓(xùn)練。

代碼示例

本示例中,將一個 2X2x1 的網(wǎng)絡(luò)訓(xùn)練出 XOR 運算符的效果。

x=[1.01.01.00.00.01.00.00.0]

y′=[0.01.01.00.0]


這里,f 是針對隱藏層的 sigmoid 激活函數(shù)。

注意,XOR 運算符是不能通過第一部分中的線性網(wǎng)絡(luò)進行模擬的,因為數(shù)據(jù)集分布是非線性的。也就是你不能通過一條直線將 XOR 的四個輸入值正確劃分到兩類中。如果我們將 sigmoid 函數(shù)換為恒等函數(shù),這個網(wǎng)絡(luò)也將是不可行的。

講完這么多,輪到你自己來動手操作啦!試試采用不同的激活函數(shù)、學(xué)習(xí)率和網(wǎng)絡(luò)拓撲,看看效果如何?

最后

恭喜看完本文!你學(xué)會了嗎?

最簡單的人工神經(jīng)網(wǎng)絡(luò)的評論 (共 條)

分享到微博請遵守國家法律
巴塘县| 浮山县| 吉安县| 南华县| 吕梁市| 化德县| 大宁县| 阿荣旗| 巍山| 融水| 镇原县| 洛南县| 灵武市| 柯坪县| 广南县| 云阳县| 佛山市| 临洮县| 阿坝县| 白山市| 莎车县| 沐川县| 罗源县| 永新县| 来宾市| 大荔县| 瑞丽市| 郑州市| 咸丰县| 无棣县| 霞浦县| 古蔺县| 长岭县| 绵竹市| 昆明市| 昌吉市| 越西县| 常宁市| 稷山县| 凤翔县| 淮阳县|