0
本文作者: 林少宏 | 2017-02-05 11:52 |
雷鋒網(wǎng)按:本文為Cookie Engineer寫就,主要對(duì)機(jī)器學(xué)習(xí)進(jìn)行了簡(jiǎn)單的介紹,雷鋒網(wǎng)編譯,未經(jīng)許可不得轉(zhuǎn)載。
經(jīng)常有人問我如何開始學(xué)習(xí)機(jī)器學(xué)習(xí),他們面臨的最大困難就是機(jī)器學(xué)習(xí)背后的數(shù)學(xué)原理。我承認(rèn)其實(shí)我也不喜歡數(shù)學(xué)。數(shù)學(xué)是對(duì)事物的一種抽象描述,用數(shù)學(xué)來(lái)描述機(jī)器學(xué)習(xí),會(huì)過于抽象,且不容易理解。因此在這個(gè)系列的文章中,我嘗試使用偽代碼或者JavaScript來(lái)描述我所講述的內(nèi)容。
我在GitHub上創(chuàng)建了項(xiàng)目倉(cāng)庫(kù),我會(huì)將一些實(shí)驗(yàn)代碼同步到代碼庫(kù)中,以便您可以跟隨我的步驟,或者在這些實(shí)驗(yàn)代碼之上實(shí)現(xiàn)自己的東西。這些代碼運(yùn)行時(shí)可能會(huì)時(shí)不時(shí)報(bào)錯(cuò),所以我稱之為實(shí)驗(yàn)代碼 J
你必須知道的第一個(gè)事情是同一個(gè)問題會(huì)有不同的解決方案。同一個(gè)問題可能會(huì)有3個(gè)解決方案,當(dāng)你已經(jīng)學(xué)會(huì)基本概念后,我會(huì)深入探討更復(fù)雜的解決方案。我也試圖將描述的內(nèi)容盡量與語(yǔ)言無(wú)關(guān)、和框架無(wú)關(guān)。本文將介紹的第一個(gè)解決方案是遺傳編程和進(jìn)化算法。
神經(jīng)網(wǎng)絡(luò)不是很難理解。對(duì)新手來(lái)說比較難描述。因?yàn)槊總€(gè)人都在使用數(shù)學(xué)來(lái)解釋神經(jīng)網(wǎng)絡(luò),那我想在這里會(huì)用不同的方法來(lái)描述它。下面我們談?wù)撘粋€(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò),它的結(jié)構(gòu)包括三個(gè)不同的“類別”:輸入層,隱藏層和輸出層。
圖1 神經(jīng)網(wǎng)絡(luò)基本架構(gòu)
輸入層通常代表傳感器,其中輸入數(shù)組的每個(gè)值的范圍是從0.0到1.0。輸出層代表對(duì)問題的解,取值可能為真假二值,也可能是位置矢量(例如游戲中,操作對(duì)象的x/y/z坐標(biāo)值)。
神經(jīng)網(wǎng)絡(luò)可以用來(lái)擬合復(fù)雜函數(shù),已經(jīng)復(fù)雜的分類決策問題(達(dá)到Bayesian解決方案的限制,但以后會(huì)出現(xiàn))。神經(jīng)網(wǎng)絡(luò)是無(wú)知的,他們只能理解從0.0到1.0的值,這意味著我們必須為其編寫適配器,以便它能夠理解它的含義,適配器在現(xiàn)實(shí)世界中通常稱為“策略”,它除了將值轉(zhuǎn)換為0和1之外,不會(huì)做其他事情。例如,當(dāng)我們想要在乒乓球游戲中預(yù)測(cè)槳的移動(dòng)位置時(shí),我們可以使用這樣的代碼:
let input = [ 0, 0, 0 ]; // x,y,z
input[0] = entity.position.x / screen.width;
input[1] = entity.position.y / screen.height;
input[2] = 0; // we don't have a z position, have we?
let answer = neural_network.compute(input);
if (answer[0] > 0.5) {
entity.moveUpwards();
} else {
entity.moveDownwards();
}
現(xiàn)在我們知道一個(gè)神經(jīng)網(wǎng)絡(luò)可以計(jì)算輸入,輸出是/否離散結(jié)果,或者連續(xù)值。神經(jīng)網(wǎng)絡(luò)每層包含多個(gè)神經(jīng)元。簡(jiǎn)單的前饋網(wǎng)絡(luò)以每個(gè)神經(jīng)元與前一層中的每個(gè)神經(jīng)元(從左到右走)相連接的方式建立。
這些連接使用用來(lái)描述數(shù)據(jù)流的流向,每個(gè)連接線對(duì)應(yīng)一個(gè)權(quán)重。這里的重要部分是輸入神經(jīng)元沒有連接到上一層,因此compute( )函數(shù)必須對(duì)輸入神經(jīng)元做出反饋,根據(jù)輸入數(shù)組的值直接獲得結(jié)果。所謂的激活函數(shù),是用來(lái)描述前后兩層中,互相聯(lián)系的神經(jīng)元的轉(zhuǎn)換關(guān)系。這里激活函數(shù)的概念有點(diǎn)模糊,因?yàn)槊總€(gè)人都有自己的見解。當(dāng)然,你需要知道的是,它只是一個(gè)簡(jiǎn)單的函數(shù),其響應(yīng)形式如下:
圖2激活函數(shù)Sigmoid的響應(yīng)
const _sigmoid = function(value) {
return (1 / (1 + Math.exp((-1 * value) / 1)));
};
總之,你只需要知道激活函數(shù)是模擬神經(jīng)元如何工作的一種方法。激活函數(shù)在現(xiàn)實(shí)中只是取一個(gè)值并將其轉(zhuǎn)換為另一個(gè)值。它的行為方式類似于動(dòng)畫世界中的每一幀之間的轉(zhuǎn)換。
快速進(jìn)步首先意味著神經(jīng)元可以快速學(xué)習(xí),緩慢步進(jìn)意味著神經(jīng)元過度擬合收斂更慢。過度擬合和討論是一個(gè)更復(fù)雜的話題,但我直截了當(dāng)?shù)睾雎运?,以?jié)省時(shí)間和混亂。
1.遺傳編程和進(jìn)化
遺傳編程的核心思想是使用基因組的形式來(lái)表示網(wǎng)絡(luò)結(jié)構(gòu)。遺傳編程的巨大優(yōu)勢(shì)是,當(dāng)遺傳編程與進(jìn)化算法相結(jié)合時(shí),它可以非??斓孬@得很好的網(wǎng)絡(luò)結(jié)構(gòu)。一個(gè)基本的進(jìn)化算法總是包含三個(gè)不同的周期:訓(xùn)練、評(píng)價(jià)、繁殖,重復(fù)以上過程。
圖3 進(jìn)化算法過程
進(jìn)化算法的執(zhí)行過程如下:
STEP1 種群初始化:對(duì)種群的個(gè)體賦隨機(jī)值,這樣您就可以快速獲得一個(gè)結(jié)果。當(dāng)然,使用隨機(jī)值來(lái)求最優(yōu)解是有點(diǎn)漫無(wú)目的。
STEP2 適應(yīng)度評(píng)價(jià):適應(yīng)度是評(píng)估循環(huán)過程中每個(gè)個(gè)體過程值,用來(lái)評(píng)估個(gè)體接近最優(yōu)解的程度。例如,在超級(jí)馬里奧游戲中,與左的距離、分?jǐn)?shù)、殺敵數(shù)等可以用作適應(yīng)度。
STEP3 個(gè)體選擇,種群中適應(yīng)度高的個(gè)體被選入交配池,獲得與其他適應(yīng)度高的個(gè)體交叉繁殖的機(jī)會(huì),從而產(chǎn)生新的個(gè)體,加入子代種群。交叉算子的操作類似于人類繁殖的過程,父、母兩條染色體相互交換基因片段,當(dāng)然“兒子”個(gè)體會(huì)更像父親,而“女兒”個(gè)體更像母親。變異算子的主要作用是保持種群的多樣性,防止種群陷入局部最優(yōu),所以其一般被設(shè)計(jì)為一種隨機(jī)變換。
圖4 個(gè)體交叉示意圖
STEP4 判斷是否達(dá)到最大迭代次數(shù),若否,則跳至STEP2。
交叉算法通常在兩個(gè)基因的截?cái)帱c(diǎn)處進(jìn)行交換,子個(gè)體各獲得一部分,如女兒獲得父母基因的比例分別為70% / 30%,兒子獲得父母基因的比例分別是30% /70%。
let dna_split = (Math.random() * mum_genome.length) | 0;
let daughter = new Genome();
let son = new Genome();for (let d = 0; d < mum_genome.length; d < dl; d++) {
if (d > dna_split) {
son[d] = mum_genome[d];
daughter[d] = dad_genome[d];
} else {
daughter[d] = mum_genome[d];
son[d] = dad_genome[d];
}}
我們可以用1個(gè)基因的取值代表神經(jīng)網(wǎng)絡(luò)權(quán)重的值。這意味著神經(jīng)網(wǎng)絡(luò)的權(quán)重中的每個(gè)可能的取值可以看做是對(duì)等的基因個(gè)體。
圖5用基因來(lái)表示神經(jīng)網(wǎng)絡(luò)中神經(jīng)元的權(quán)重
進(jìn)化算法的典型問題是,當(dāng)在時(shí)間尺度上進(jìn)行觀察時(shí),會(huì)出現(xiàn)即使迭代時(shí)間再長(zhǎng),求解的結(jié)果并不會(huì)改善太多,趨近于飽和狀態(tài)。這主要是因?yàn)橥蛔兟侍?,無(wú)法求得最優(yōu)解。高變異率雖然可以讓收斂速度更快,然而,迭代時(shí)間長(zhǎng)了之后,高變異率可能會(huì)導(dǎo)致丟失全局最優(yōu)解。
如果你想做一個(gè)簡(jiǎn)單的基于進(jìn)化算法的人工智能演示,你可以用流行的瀏覽器打開下面的鏈接,是一個(gè)叫Flappy Plane演示程序。
圖6 Flappy Plane演示程序
正如你可能看到的,總會(huì)有一個(gè)時(shí)間點(diǎn),進(jìn)化算法會(huì)收斂,適應(yīng)度趨于飽和,神經(jīng)網(wǎng)絡(luò)不會(huì)再進(jìn)化到一個(gè)更完美的狀態(tài)。沒有反向傳播法的話,單純靠隨機(jī)化序列是無(wú)法得到最優(yōu)解的,除非有足夠多的時(shí)間來(lái)迭代,可能至死我們也無(wú)法得到最優(yōu)解。
NEAT(基于增強(qiáng)拓?fù)渖窠?jīng)網(wǎng)絡(luò))和HyperNEAT解決這個(gè)問題的思路是通過迭代過程中,通過分析網(wǎng)絡(luò)的表現(xiàn)和突變來(lái)改變網(wǎng)絡(luò)。例如,每個(gè)基因組可以自我評(píng)估適應(yīng)度,只有“更好”的基因組存活,而較差適應(yīng)度的基因會(huì)被記下來(lái),用于隨機(jī)化。
2.NEAT
NEAT是一個(gè)利器,很難用一種簡(jiǎn)單的方式解釋。如果你看過SethBling的Mari/o演示,你可能已經(jīng)知道了這個(gè)概念。我可以推薦現(xiàn)在觀看這段視頻,以便您能更好地理解我在下面的解釋。
需要了解的基本概念是:NEAT是一個(gè)用來(lái)觀察神經(jīng)網(wǎng)絡(luò)的性能和分析他們的行為的算法。如果行為分析認(rèn)為該神經(jīng)網(wǎng)絡(luò)的表現(xiàn)更好,那么該基因被選擇,進(jìn)入交配池。如果表現(xiàn)不好的話,基因(或基因組)將被標(biāo)記為失活。
NEAT更多應(yīng)用用于ANNS(自適應(yīng)神經(jīng)網(wǎng)絡(luò)),而不是典型的神經(jīng)網(wǎng)絡(luò),因?yàn)锳NNS能在外部信息的基礎(chǔ)上改變內(nèi)部結(jié)構(gòu)。ANN的思路是白手起家,從0個(gè)神經(jīng)元開始,讓算法找到神經(jīng)網(wǎng)絡(luò)的完美結(jié)構(gòu),由于神經(jīng)元的連接可以被隨機(jī)去除和創(chuàng)建,所以通過觀察網(wǎng)絡(luò)表現(xiàn),我們可以得知在哪里產(chǎn)生神經(jīng)元,會(huì)加快便我們獲得最優(yōu)解的速度。
圖7 自適應(yīng)神經(jīng)網(wǎng)絡(luò)示意圖
NEAT使用CPPN (組成模式生成網(wǎng)絡(luò)) 作為行為評(píng)估模塊,它基本上是一個(gè)(可能是加強(qiáng)的)神經(jīng)網(wǎng)絡(luò),學(xué)習(xí)輸入和神經(jīng)網(wǎng)絡(luò)性能的關(guān)系,它的優(yōu)點(diǎn)是可以記住ANN的結(jié)構(gòu),在給定足夠時(shí)間的條件下,總能找到解。
行為分析可以減少不必要的隨機(jī)化結(jié)構(gòu),我們能更好地自動(dòng)猜測(cè)未來(lái)“最可能的”值。
圖8 CPPN分析神經(jīng)網(wǎng)絡(luò)/個(gè)體,并將行為類似的分為一類
在典型的NEAT場(chǎng)景中,交配池由代表網(wǎng)絡(luò)結(jié)構(gòu)的基因個(gè)體組成,它是一個(gè)多個(gè)體的概念。這些個(gè)體總是相互競(jìng)爭(zhēng),總是試圖用“適者生存”的規(guī)則來(lái)選選擇子代的個(gè)體,讓他們的DNA能延續(xù),成為神經(jīng)網(wǎng)絡(luò)權(quán)重。
圖9 多個(gè)體系統(tǒng)通過適應(yīng)度排序代理,并確定優(yōu)勢(shì)個(gè)體
多個(gè)體系統(tǒng)中的優(yōu)勢(shì)個(gè)體是可以進(jìn)入交配池,以填充下一個(gè)進(jìn)化循環(huán)的種群。下一個(gè)循環(huán)的交配池通常包含以下三種類型:
1. 20%幸存者(最高適應(yīng)度個(gè)體的交叉繁育得到的子代);
2. 20%突變體(在原個(gè)體基礎(chǔ)上隨機(jī)突變神經(jīng)網(wǎng)絡(luò));
3. 60%子代個(gè)體(最高適應(yīng)度的個(gè)體與其他個(gè)體的交配繁育得到的子代);
下一篇文章可能會(huì)介紹反向傳播和增強(qiáng)學(xué)習(xí),以及將這兩種算法與進(jìn)化算法進(jìn)行比較。請(qǐng)記?。核鼈儾皇仟?dú)立互斥的概念,進(jìn)化算法是可以結(jié)合增強(qiáng)型神經(jīng)網(wǎng)絡(luò)一起使用。
via Machine Learning for Dummies: Part 1,雷鋒網(wǎng)編譯
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。