国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用JavaScript實現(xiàn)機器學(xué)習(xí)和神經(jīng)學(xué)網(wǎng)絡(luò)

tunny / 2629人閱讀

摘要:我會使用一個先進的神經(jīng)網(wǎng)絡(luò)和機器學(xué)習(xí)框架這個框架,并向你們展示如何用這個框架來實現(xiàn)光學(xué)字符辨識,模擬退火法,遺傳算法和神經(jīng)網(wǎng)絡(luò)。歐氏距離我們從歐氏距離開始談起,歐氏距離是一個非常簡單的概念,適用于不同的機器學(xué)習(xí)技術(shù)。

歡迎大家前往云+社區(qū),獲取更多騰訊海量技術(shù)實踐干貨哦~

下載 heaton-javascript-ml.zip - 45.1 KB

基本介紹

在本文中,你會對如何使用JavaScript實現(xiàn)機器學(xué)習(xí)這個話題有一些基本的了解。我會使用Encon(一個先進的神經(jīng)網(wǎng)絡(luò)和機器學(xué)習(xí)框架)這個框架,并向你們展示如何用這個框架來實現(xiàn)光學(xué)字符辨識,模擬退火法,遺傳算法和神經(jīng)網(wǎng)絡(luò)。Encog同時包括了幾個GUI窗體小部件,這些小部件可以更方便地顯示出一般機器學(xué)習(xí)任務(wù)的輸出。

運行環(huán)境

Encog是一個面向Java,C#,JavaScript和C/C++的高級機器學(xué)習(xí)平臺。除此之外,Encog還可以為http://www.heatonresearch.com...的實際案例生成對應(yīng)代碼,本文將重點介紹如何使用支持JavaScript的Encog框架,該框架允許你創(chuàng)建利用人工智能實現(xiàn)的交互式web應(yīng)用程序。訪問以下網(wǎng)址獲取有關(guān)Encog的更多信息。

http://www.heatonresearch.com...

代碼調(diào)用

本文介紹的所有示例代碼都可以在附帶的下載中找到。

這段代碼同時被托管在下面的GitHub庫中。

https://github.com/encog/enco...

你可以看到本文討論的所有示例都運行在下面的URL中:

http://www.heatonresearch.com...

Encog框架包含在兩個JavaScript文件中。第一個JavaScript文件包含了所有核心的機器學(xué)習(xí)函數(shù)。這個JavaScript文件被命名為encog-js-x.js。第二個文件包含了所有的GUI窗體小組件,并被命名為encog-widget.js。你可以在下面的引用路徑中閱讀這兩個文件。



歐氏距離

我們從歐氏距離開始談起,歐氏距離是一個非常簡單的概念,適用于不同的機器學(xué)習(xí)技術(shù)。歐氏距離提供的結(jié)果是一個數(shù)字,該數(shù)字決定了相同長度的兩個數(shù)組之間的相似性。思考下面三個數(shù)組:

Array 1: [ 1, 2, 3]
Array 2: [ 1, 3, 2]
Array 3: [ 3, 2, 1]

我們可以計算出上面任意兩個數(shù)組之間的歐氏距離,這對于確定數(shù)組之間的相似度是非常有用的。思考一下,假如我們想要確定一下數(shù)組2或者數(shù)組3哪個距離數(shù)組1更近。為了做到這一點,我們需要計算數(shù)組1和數(shù)組2之間的歐氏距離。然后再計算數(shù)組1和數(shù)組3之間的歐氏距離。兩相比較,最短的就是最相似的。

從數(shù)學(xué)角度來講,歐氏距離由以下方程式進行計算。

圖 1: 歐氏距離

使用這個公式,我們現(xiàn)在可以計算上文中的歐氏距離

d(a1,a2) = sqrt( (a2[0]-a1[0])^2 + (a2[1]-a1[1])^2 +  (a2[1]-a1[1])^2  )
d(a1,a2) = sqrt( (1-1)^2 + (3-2)^2 + (2-3)^2 )
d(a1,a2) = sqrt( 0+1+1 )
d(a1,a2) = sqrt(2) = 1.4
d(a1,a3) = sqrt( (a3[0]-a1[0])^2 + (a3[1]-a1[1])^2 +  (a3[1]-a1[1])^2  )
d(a1,a3) = sqrt( (3-1)^2 + (2-2)^2 + (1-3)^2 )
d(a1,a3) = sqrt( 4+0+4 )
d(a1,a3) = sqrt(8) = 2.3

從結(jié)果中我們可以看出數(shù)組2比數(shù)組1更為接近數(shù)組3。

下面的JavaScript代碼實現(xiàn)了歐氏距離的計算。

ENCOG.MathUtil.euclideanDistance = function (a1, a2, startIndex, len) {
    "use strict";
    var result = 0, i, diff;
    for (i = startIndex; i < (startIndex + len); i += 1) {
        diff = a1[i] - a2[i];
        result += diff * diff;
    }
    return Math.sqrt(result);
};

歐氏距離可以被用來創(chuàng)建一個簡單的光學(xué)字符辨識實例。你可以在下圖中看到應(yīng)用程序運行實例:

圖 2: JavaScript光學(xué)字符辨識

你可以在下面這個URL中查看程序的運行實例:

http://www.heatonresearch.com...

HTML5(啟用觸控設(shè)備)的JavaScript應(yīng)用程序可以通過簡單的歐氏距離來實現(xiàn)基本的光學(xué)字符辨識。為了使用這個示例,需要在下面這個大的矩形中繪制一個數(shù)字,然后點擊“Recognize”(識別)按鈕,程序會嘗試猜測你畫的這個數(shù)字。雖然準(zhǔn)確性并不是特別高,但它做的確實已經(jīng)很不錯了。

該程序已經(jīng)通過了數(shù)據(jù)訓(xùn)練,你可以移除這些數(shù)字條目中的任何一個,或者創(chuàng)建你自己的條目。如果需要訓(xùn)練一個新字符的OCR,只要簡單繪出那個字符,然后點擊“Teach”(教學(xué))按鈕。則該字符就會被增加到已知的字符列表中。

你會發(fā)現(xiàn),你所繪制的任何東西都是先剪裁然后向下采樣的。程序會對你所繪制的高分辨率字符向下采樣并將采樣點分配到5×8網(wǎng)格中。然后將這個通過向下采樣得到的網(wǎng)格與每個數(shù)字的向下采樣網(wǎng)格進行比較。如果要查看程序中經(jīng)訓(xùn)練后得到的網(wǎng)格,需要在字符列表中單擊你希望看到的字符。然后程序會將這個網(wǎng)格轉(zhuǎn)換成一個一維數(shù)組,而一個5×8的網(wǎng)格會有40個數(shù)組元素。

以下JavaScript代碼執(zhí)行了這個搜索,并且實現(xiàn)了一個歐氏距離的計算

var c, data, sum, i, delta;
for(c in charData )
{
 data = charData[c];
// 現(xiàn)在我們將會識別出這個畫出來的字母.
// 為此,我們需要利用歐氏距離來計算
// http://www.heatonresearch.com/wiki/Euclidean_Distance (這是歐氏距離運行實例的URL)
 sum = 0;
 for(var i = 0; i
蜂擁算法

這個例子展示一個名為flocking(蜂擁)的迷人的簡單算法。此處的粒子是成群存在的。起初的時候,它們各自隨機出現(xiàn)在某個位置,然而,這些粒子會很快地填充成各種形式的組,并以看似復(fù)雜的模式路線飛行。或者你也可以手動點擊(或者觸摸)一個位置,這些粒子會排斥并遠(yuǎn)離你的接觸點。

圖3:flocking(蜂擁算法)

你可以在線運行以下URL的實例程序:

http://www.heatonresearch.com...

這個實例可能需要一分鐘(大約),才能讓成熟的蜂擁集群出現(xiàn)。即使這些集群出現(xiàn)了,它們也經(jīng)常會再次分裂和重組。重啟時點擊“Clear”(清除),或者也可以點擊“Big Bang”(大爆炸模式),該模式不會使用任何隨機的初始化,而是將粒子統(tǒng)一放置在面板中央,并且以粒子設(shè)定的“復(fù)雜模式”迅速向外移動。

克雷格·雷諾茲在1986年首次用他的模擬程序Boids在計算機上成功模擬出了蜂擁算法。蜂擁集群是一種非常復(fù)雜的行為。他在不同種類的動物中有各自表現(xiàn)形式,各自使用了很多不同的名字。比如一群小鳥,一群昆蟲,一個學(xué)校的魚群,一群牛等等。其實就是用不同的名字來描述本質(zhì)相同的行為。

初看上去,蜂擁算法可能看似復(fù)雜。因為我們需要創(chuàng)建一個對象來處理集群中的個體、需要定義一個蜂擁對象來容納集群成員、需要為確定蜂擁集群應(yīng)該向哪個方向移動而制定常規(guī)行為。我們還必須確定如何將蜂擁集群分成兩群或者更多的群。那么問題是什么樣的標(biāo)準(zhǔn)可以決定某個群體可以得到成員數(shù)量?新成員如何被確認(rèn)是屬于哪一個集群?你可以在下面內(nèi)容中看到一些真實的蜂擁集群例子。

蜂擁算法其實很簡單,它只有三條規(guī)則:

分離 :遠(yuǎn)離擁擠的鄰居(短距離相互排斥)

對齊 :趨近于鄰居的平均方向

內(nèi)聚 :轉(zhuǎn)向鄰居的平均距離位置(長距離相互吸引)

這三個基本規(guī)則是必需的。蜂擁算法其實就是“簡單的復(fù)雜”的典型例子。

我希望這個例子能夠盡可能的簡單,但是仍然表現(xiàn)出看似復(fù)雜的行為方式。其實這些粒子都是以恒定的速度運行的,每個粒子都有一個角度屬性來定義粒子運動的方向。所以這些粒子不可以加速或者減速,唯一可以做到是轉(zhuǎn)向。

上述的三種規(guī)則其實是分別為粒子的運動設(shè)定好了一個“理想的角度”,遵守這三種規(guī)則的期望被特定的百分比屬性所抑制。這些抑制因子是你在底部看到的三個數(shù)字。你可以嘗試填入一些數(shù)字,看看它們是如何影響集群粒子的運動軌跡的。其實有很多的數(shù)字組合不會產(chǎn)生集群的行為,而我在實例中填入的默認(rèn)值是比較合適的。

如果你想多帶帶查看這三種規(guī)則中多帶帶一條生效時的結(jié)果,那么可以將該規(guī)則設(shè)置為1.0,其它的規(guī)則設(shè)置為0.0。例如當(dāng)內(nèi)聚的規(guī)則多帶帶生效時,你會所有的粒子會聚集在面板區(qū)域中少數(shù)的幾個位置。

在這個區(qū)域中不存在任何隨機性。除了粒子最初出現(xiàn)的位置是隨機的之外,不會產(chǎn)生更多的隨機數(shù)。你甚至可以點擊“Big Bang”(大爆炸模式)按鈕,來消除系統(tǒng)中所有的隨機性。如果你點擊了“Big Bang”按鈕,則所有的粒子都會被放置到區(qū)域的中心位置,并以同樣的方向運動。如此一來,要形成一幅復(fù)雜的運動模式并不會花費很長時間。所以對于用非常簡單的規(guī)則來實現(xiàn)非常復(fù)雜的系統(tǒng)來說,蜂擁算法是一個非常典型的例子。

理解歐氏距離對于例子很重要。因為每個粒子都有兩個維度,分別是x坐標(biāo)和y坐標(biāo)。利用歐氏距離的計算方法,我們就可以很快找到最近的鄰居。由此即引入了另一種重要的機器學(xué)習(xí)算法,即“K-鄰近算法”。這個K就是你希望找到的鄰居的數(shù)量。

這三種規(guī)則可以很容易的用JavaScript實現(xiàn)。首先,我們計算出理想的分離角度。

// 1. 隔離-避免擁擠的鄰居
(短距離的排斥力) 
separation = 0;
if (nearest.length > 0) {
  meanX = ENCOG.ArrayUtil.arrayMean(nearest, 0);
  meanY = ENCOG.ArrayUtil.arrayMean(nearest, 1);
  dx = meanX - this.agentsi;
  dy = meanY - this.agentsi;
  separation = (Math.atan2(dx, dy) * 180 / Math.PI) - this.agentsi;
  separation += 180;
}

首先,我們需要計算出所有鄰居粒子的x坐標(biāo)的平均值和y坐標(biāo)的平均值,這個平均坐標(biāo)點就是鄰近集群的中心點。然后,借用一些三角函數(shù)中的知識,計算出我們和鄰近集群中心點之間的夾角值。對這個夾角值加上180,因為我們是希望遠(yuǎn)離這個鄰近的鄰居的(進而我們就不會撞到它們)。這個才是我們應(yīng)該努力爭取的理想分離角度。

緊接著,我們會計算出理想的對齊角度。如下代碼所示。

// 2. 對齊-轉(zhuǎn)向鄰居的平均方向
alignment = 0;
if (neighbors.length > 0) {
  alignment = ENCOG.ArrayUtil.arrayMean(neighbors, 2) - this.agents[i][7];
}

對齊非常簡單,其實就是所有鄰居的平均角度。

接下來我們計算內(nèi)聚力。為此我們再來看看鄰居,不過這回考慮的是一個更大的集合,幾乎包括了所有的粒子。

// 3. 內(nèi)聚-轉(zhuǎn)向鄰居的平均位置(長距離的吸引力)
cohesion = 0;
if (neighbors.length > 0) {
  meanX 
= ENCOG.ArrayUtil.arrayMean(this.agents, 0); 
  meanY = ENCOG.ArrayUtil.arrayMean(this.agents, 1);
  dx = meanX - this.agents[i][0];
  dy = meanY - this.agents[i][8];
  cohesion = (Math.atan2(dx, dy) * 180 / Math.PI) - this.agents[i][9];
}

現(xiàn)在我們從這個規(guī)則中得到了理想的角度,那么必須要開始轉(zhuǎn)動粒子(或者說是代理)了。

// 執(zhí)行轉(zhuǎn)向操作
// 這三種規(guī)則的參數(shù)應(yīng)用值是可以配置的
// 我提供的這三個默認(rèn)值比例的運行表現(xiàn)很好
turnAmount = (cohesion * this.constCohesion) + (alignment * this.constAlignment) + (separation * this.constSeparation);
this.agents[i][10] += turnAmount;

到目前為止,我們研究的技術(shù)并不是隨機性的,而是可以被認(rèn)定為決定性的。也就是說得到的結(jié)果總是可以預(yù)測的。對于本文的內(nèi)容的排版,我們會做出180度的調(diào)整,剩下的技術(shù)都是研究隨機性的。也就是用隨機性來解決問題。

旅行推銷員問題(TSP問題)

旅行推銷員問題(TSP)意為存在一名“推銷員”,他必須經(jīng)過一定數(shù)量的城市,而這條最短的旅行路線就是我們尋找的目標(biāo)。其中允許推銷員從任意一個城市開始或者結(jié)束。唯一的要求是“推銷員”必須經(jīng)過每一個城市并且只能經(jīng)過一次。

如果用一般的迭代程序?qū)崿F(xiàn),這似乎是一個簡單的任務(wù)。思考一下隨著城市數(shù)量的增加,可能的排列組合數(shù)量會增加多少。如果只有一兩個城市,那只需要一步迭代就夠了。如果是三個城市呢,迭代步驟就變成了6步。表格8-1列舉出了迭代步驟的增長速度。

表1:用常規(guī)程序解決TSP問題的步驟數(shù)目

表格中的計算公式就是階乘。步驟數(shù)目n的數(shù)量就是用階乘符號!計算的。任意n值的階乘計算方式是n×(n?1) ×(n?2).......3×2×1

由這個公式不難看出當(dāng)一個程序必須使用“暴力”方式進行搜索時,這些數(shù)值會變得非常大。在下一節(jié)的討論中,我們使用的示例程序會在幾分鐘內(nèi)找到一個能解決50個城市問題的解決方案,這個程序用到是模擬退火法的思路,而不是使用普通的暴力搜索。

模擬退火法

模擬退火法是一種模擬退火的物理過程的編程方法,退火是指將某種材料(比如鋼鐵或者玻璃)加熱后再冷卻的方法,通常用來軟化材料以及降低材料硬度。由此可知,模擬退火法就是將一個“解決方案”暴露在“熱處理”的環(huán)境中,然后進行冷卻處理進而產(chǎn)生一個更好的解決方案。你可以在下面的URL中運行模擬退火法的示例程序。

http://www.heatonresearch.com...

模擬退火法是通過從起始溫度到結(jié)束溫度的多次迭代進行實現(xiàn)的。循環(huán)計數(shù)允許你指定溫度下降的粒度。溫度越高,系統(tǒng)引入的隨機性就越高。你可以配置這三個參數(shù)的值。

下面的JavaScript代碼實現(xiàn)了模擬退火法

anneal.randomize = function(path, temperature) {
 var length = path.length - 1;
 // 調(diào)整路徑上城市的次序(即模擬退火)
 for (var i = 0; i < temperature; i++) {
 var index1 = Math.floor(length * Math.random());
 var index2 = Math.floor(length * Math.random());
 var d = universe.pathDistance(path, index1, index1 + 1)
 + universe.pathDistance(path, index2, index2 + 1)
 - universe.pathDistance(path, index1, index2)
 - universe.pathDistance(path, index1 + 1, index2 + 1);
 if (d > 0) {
 // 如果需要的話對index1 和 index2進行排序
 if (index2 < index1) {
 var temp = index1;
 index1 = index2;
 index2 = temp;
 }
 for (; index2 > index1; index2--) {
 var temp = path[index1 + 1];
 path[index1 + 1] = path[index2];
 path[index2] = temp;
 index1++;
 }
 }
 }
}

上面的隨機化函數(shù)是專門為TSP問題定義的。在Encog框架中模擬退火法是通用的,相對于TSP獨立。所以你必須為你希望解決的問題提供一個隨機函數(shù)。

基本來說,隨機化函數(shù)會根據(jù)溫度對城市的旅行路線進行修正。上面的函數(shù)只是簡單地根據(jù)溫度將旅行路線中的路線上經(jīng)過城市次序進行對換。溫度越高,對換的次數(shù)越多。

隨機城市

這個程序的常見用法是將隨機幾個城市放置地圖上,這些城市出現(xiàn)在地圖上的隨機的幾個位置。隨機城市問題的排列組合相比于其他的固定城市組合要更困難一些。在下圖中你可以看到包含了50個隨機的城市的地圖。

圖 4:隨機城市

一旦解決了這組隨機城市TSP問題,結(jié)果就如下圖所示。

圖 5:可能的解決方案

你可能想要通過改變參數(shù)來評估模擬退火法的實際效果,為此需要重新運行該程序,并且你應(yīng)該隨機化旅行路線。這樣你就可以用相同的城市配置重新開始。

城市圈

你可以將城市位置以橢圓的形狀進行排列,這樣就更容易理解模擬退火法是如何演化出最佳解決方案的。圍繞一個橢圓的最優(yōu)路徑與它的周長形狀類似。在這里你可以利用模擬退火法,找到一條幾乎就是最優(yōu)的路徑。

圖6:城市圈

遺傳算法

利用遺傳算法(GA)可以得到TSP問題的潛在解決方案。GA是通過簡單的進化操作來創(chuàng)建一個能夠不斷改進的解決方案。這整個過程就相當(dāng)于生物遺傳進化的精簡版。進化其實就是通過交叉和突變實現(xiàn)的,所以當(dāng)兩個解決方案“交配”并產(chǎn)生后代時,就相當(dāng)于發(fā)生了交叉。而當(dāng)單一的解決方案稍微有所改變時就相當(dāng)于引發(fā)了突變。

類似于模擬退火法,GA(遺傳算法)也是隨機的。在交叉過程中會由隨機性來決定父本和母本會遺產(chǎn)什么樣的特征給子代。

你可以在下面的URL中在線查看TSP(旅行推銷員問題)的遺傳算法應(yīng)用程序:

http://www.heatonresearch.com...

為了使用Encog框架中自帶的遺傳算法,你必須定義變異和交叉這兩個操作,它們的實現(xiàn)取決于你正在尋找的解決方案的類型。

下面的代碼定義了TSP問題的突變操作。

genetic.mutate = function performMutation(data)
{
  var iswap1 = Math.floor(Math.random() * data.length);
  var iswap2 = Math.floor(Math.random() * data.length);
  // 不相等時
  if (iswap1 == iswap2)
  {
    // 繼續(xù)下一步
    // 但是,不要出界
    if (iswap1 > 0)
    {
      iswap1--;
    } else {
      iswap1++;
    }
  }
  var t = data[iswap1];
  data[iswap1] = data[iswap2];
  data[iswap2] = t;
}

這段代碼與模擬退火法的隨機化操作非常類似。本質(zhì)上,程序?qū)α斜碇械膬蓚€城市進行了交換操作。所以我們必須保證這兩個隨機城市是不相同的,因為一旦相同,這兩個城市就不會發(fā)生交換。

交叉操作比較復(fù)雜。下面的代碼實現(xiàn)了交叉函數(shù)。

genetic.crossover = function performCrossover(motherArray, fatherArray, child1Array, child2Array)
{
  // 染色體(此處泛指遺傳特性)必須在兩個位置被切割,并確定他們。
  var cutLength = motherArray.length / 5;
  var cutpoint1 = Math.floor(Math.random() * (motherArray.length - cutLength));
  var cutpoint2 = cutpoint1 + cutLength;
  // 記錄這兩個子代中每一個染色體中所帶的基因,默認(rèn)為false
  var taken1 = {};
  var taken2 = {};
  // 處理削減的染色體部分
  for (var i = 0; i < motherArray.length; i++)
  {
    if (!((i < cutpoint1) || (i > cutpoint2)))
    {
      child1Array[i] = fatherArray[i];
      child2Array[i] = motherArray[i];
      taken1[fatherArray[i]] = true;
      taken2[motherArray[i]] = true;
    }
  }
  // 處理外部的染色體部分
  for (var i = 0; i < motherArray.length; i++)
  {
    if ((i < cutpoint1) || (i > cutpoint2))
    {
      child1Array[i] = getNotTaken(motherArray,taken1);
      child2Array[i] = getNotTaken(fatherArray,taken2);
    }
  }
};

上面代碼的原理如下:在城市的道路上取兩個“切點”,這就意味著把父本和母本的特性都各自分割成了三份,父本和母本有著相同的切點。這些切割的規(guī)模是隨機的,然后通過交換父輩的三份來創(chuàng)建兩個子代。例如,觀察下面的父本和母本。

[m1, m2, m3 ,m4, m5, m6, m7, m8, m9, m10]
[f1, f2, f3 ,f4, f5, f6, f7, f8, f9, f10]

現(xiàn)在我們將這些切點加進去。

[m1, m2] [m3 ,m4, m5, m6] [m7, m8, m9, m10]
[f1, f2] [f3 ,f4, f5, f6] [f7, f8, f9, f10]

如此會產(chǎn)生下面兩個子代。

[m1, m2] [f3 ,f4, f5, f6] [m7, m8, m9, m10]
[f1, f2] [m3 ,m4, m5, m6] [f7, f8, f9, f10]

根據(jù)另一個隨機事件,每個解決方案都可能會發(fā)生突變。突變就是將“新產(chǎn)生的信息”添加到種群遺傳的過程。否則就是簡單的傳遞已經(jīng)存在的遺傳特征。

XOR神經(jīng)網(wǎng)絡(luò)

神經(jīng)網(wǎng)絡(luò)是另外一種基于生物學(xué)的機器學(xué)習(xí)方法,它非常松散地建立在人腦的基礎(chǔ)上。神經(jīng)網(wǎng)絡(luò)是由神經(jīng)突觸連接的神經(jīng)元組成的,每一個突觸本身都具有權(quán)重,眾多突觸的權(quán)重構(gòu)成了神經(jīng)網(wǎng)絡(luò)的記憶。如下所示的神經(jīng)網(wǎng)絡(luò)示意圖。

圖 7:一個神經(jīng)網(wǎng)絡(luò)

如圖所示的結(jié)構(gòu),其實就是我們下一節(jié)要創(chuàng)建的神經(jīng)網(wǎng)絡(luò),你可以在上面的神經(jīng)網(wǎng)絡(luò)中看到有一個輸入層和一個輸出層。神經(jīng)網(wǎng)絡(luò)接收來自輸入層的刺激,并交由輸出層進行相應(yīng)輸出。神經(jīng)網(wǎng)絡(luò)內(nèi)部也可能存在隱藏層,該層中同樣包含有神經(jīng)元。隱藏層也有助于信息的處理。XOR神經(jīng)網(wǎng)絡(luò)(異或神經(jīng)網(wǎng)絡(luò)),有兩個輸入和一個輸出。兩個輸入端接收布爾值(0或者1),輸出神經(jīng)元也輸出布爾值。其目的就是讓神經(jīng)網(wǎng)絡(luò)實現(xiàn)和XOR(異或運算)操作符相同的功能。

0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0

當(dāng)兩個輸入不一致時,異或XOR操作符的輸出必為1。

你可以在下面看到異或XOR的示例輸出。

Training XOR with Resilient Propagation (RPROP)
Training Iteration #1, Error: 0.266564333804989
Training Iteration #2, Error: 0.2525674154011323
Training Iteration #3, Error: 0.2510141208338126
Training Iteration #4, Error: 0.2501895607116004
Training Iteration #5, Error: 0.24604660296617512
Training Iteration #6, Error: 0.24363697465430123
Training Iteration #7, Error: 0.24007542622000883
Training Iteration #8, Error: 0.23594361591893737
Training Iteration #9, Error: 0.23110199069041137
Training Iteration #10, Error: 0.22402031408256806
...
Training Iteration #41, Error: 0.0169149539750981
Training Iteration #42, Error: 0.012983289628979862
Training Iteration #43, Error: 0.010217909135985562
Training Iteration #44, Error: 0.007442433731742264
Testing neural network
Input: 0 ; 0   Output: 0.000005296759326400659   Ideal: 0
Input: 1 ; 0   Output: 0.9176637562838892   Ideal: 1
Input: 0 ; 1   Output: 0.9249242746585553   Ideal: 1
Input: 1 ; 1   Output: 0.036556423402042126   Ideal: 0

正如上文所示,它用了44個迭代訓(xùn)練來教神經(jīng)網(wǎng)絡(luò)執(zhí)行XOR操作,神經(jīng)網(wǎng)絡(luò)的初始化權(quán)重是從隨機數(shù)字開始的。數(shù)據(jù)訓(xùn)練的過程中會逐漸調(diào)整權(quán)重,以產(chǎn)生期望的輸出。神經(jīng)網(wǎng)絡(luò)的隨機部分是權(quán)重的初始化量值。除了這些,神經(jīng)網(wǎng)絡(luò)是決定性的。給定相同的權(quán)重和輸入,神經(jīng)網(wǎng)絡(luò)始終會產(chǎn)生相同的輸出。

在上面的輸出中,你可能會注意到輸出的結(jié)果并不是非常精確的。因為神經(jīng)網(wǎng)絡(luò)永遠(yuǎn)不會為1的輸出精確到1.0。由于開始的權(quán)重是隨機的,所以你不可能從這個神經(jīng)網(wǎng)絡(luò)中得到兩個相同的結(jié)果。另外,由于一些隨機的初始化權(quán)重量值是完全不可訓(xùn)練的,正因如此,有時你會看到XOR神經(jīng)網(wǎng)絡(luò)達到了5000的最大訓(xùn)練值,然而就還是放棄了。

你可以在下面URL中看到這個案例的運行實例。

http://www.heatonresearch.com...

我們現(xiàn)在來觀察這個程序是如何構(gòu)建的。首先,我們創(chuàng)建輸入和理想輸出。

var XOR_INPUT = [
  [0,0],
  [1,0],
  [0,1],
  [1,1]
];
var XOR_IDEAL = [
  [0],
  [1],
  [1],
  [0]
];

上面的兩個數(shù)組分別包含了輸入和理想輸出。這個“真相表”將被用來訓(xùn)練神經(jīng)網(wǎng)絡(luò)。

接著我們來創(chuàng)建一個三層神經(jīng)網(wǎng)絡(luò)。輸入層有兩個神經(jīng)元,隱藏的神經(jīng)元有三個,輸出層有一個神經(jīng)元。

    var network = ENCOG.BasicNetwork.create( [
      ENCOG.BasicLayer.create(ENCOG.ActivationSigmoid.create(),2,1),
      ENCOG.BasicLayer.create(ENCOG.ActivationSigmoid.create(),3,1),
      ENCOG.BasicLayer.create(ENCOG.ActivationSigmoid.create(),1,0)] );

network.randomize();

創(chuàng)建和隨機化神經(jīng)網(wǎng)絡(luò)的時候,將會調(diào)用隨機化函數(shù)將權(quán)重填充為隨機值。

訓(xùn)練神經(jīng)網(wǎng)絡(luò)有很多不同方法,對于本例,我們會采用RPROP(一種基于彈性反向傳播的神經(jīng)網(wǎng)絡(luò)算法原理)來實現(xiàn)。

var train = ENCOG.PropagationTrainer.create(network,XOR_INPUT,XOR_IDEAL,"RPROP",0,0);

現(xiàn)在,我們將通過迭代訓(xùn)練進行循環(huán)處理,直到出錯率降到可以接受的水平線以下為止。

var iteration = 1;
do
{
  train.iteration();
  var str = "Training Iteration #" + iteration + ", Error: " + train.error;
con.writeLine(str); 
  iteration++;
} while( iteration<1000 && train.error>0.01);

現(xiàn)在神經(jīng)網(wǎng)絡(luò)的訓(xùn)練已完成,我們將對輸入數(shù)組進行循環(huán)處理,并將其提交給神經(jīng)網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)會顯示出對應(yīng)輸出。

var input = [0,0];
var output = [];
con.writeLine("Testing neural network");
for(var i=0;i

這是對神經(jīng)網(wǎng)絡(luò)的一個非常簡單的介紹,我還做了一個關(guān)于Java和C#神經(jīng)網(wǎng)絡(luò)內(nèi)容,你如果只對神經(jīng)網(wǎng)絡(luò)感興趣,下面的內(nèi)容應(yīng)該會有所幫助。

Introduction to Neural Networks for Java
Introduction to Neural Networks for C# 

此外,如果你想了解神經(jīng)網(wǎng)絡(luò)的基本介紹,下面的文章可能會對你有用。

http://www.heatonresearch.com...

神經(jīng)網(wǎng)絡(luò)分類

現(xiàn)在我們來看一個稍微復(fù)雜些的神經(jīng)網(wǎng)絡(luò)分類,這個神經(jīng)網(wǎng)絡(luò)將會學(xué)習(xí)如何進行分類。我們會學(xué)到神經(jīng)網(wǎng)絡(luò)是如何通過訓(xùn)練數(shù)據(jù)集來學(xué)習(xí)對數(shù)據(jù)點進行分類,并且能夠?qū)τ?xùn)練數(shù)據(jù)集中不存在的數(shù)據(jù)點進行分類。

你可以在下面的URL中在線運行這個示例代碼:

http://www.heatonresearch.com...

本案例將利用前饋神經(jīng)網(wǎng)絡(luò)原理進行分類。為了充分利用這個程序,我們在畫圖區(qū)域繪制了幾個彩色點。必須保證你至少有兩個彩色點,否則程序就無法進行分類。一旦你開始畫點并且點擊begin(開始),則神經(jīng)網(wǎng)絡(luò)也就開始訓(xùn)練了。你將看到你提供的數(shù)據(jù)點附近的其他區(qū)域是如何進行分類的。

上一個神經(jīng)網(wǎng)絡(luò)案例有是兩個輸入神經(jīng)元和三個輸出神經(jīng)元的。隱藏層的結(jié)構(gòu)是由drop列表決定的。舉例來說,如果你選擇了2:10:10:3,你將會得到一個與以下圖像相似的網(wǎng)絡(luò),這個網(wǎng)絡(luò)有兩個隱藏層,每層有10個神經(jīng)元。

輸入神經(jīng)元代表一個點的x坐標(biāo)和y坐標(biāo)。為了繪出上面的圖像,該程序在x坐標(biāo)和y坐標(biāo)的網(wǎng)格上進行循環(huán)處理。每個網(wǎng)格組件都會對神經(jīng)網(wǎng)絡(luò)進行查詢。左上角的細(xì)胞是[0,0],右下角的細(xì)胞坐標(biāo)是[1,1]。對于具有sigmoid(常用的非線性激活函數(shù))激活函數(shù)的神經(jīng)網(wǎng)絡(luò)數(shù)據(jù),通常可以在0到1之間的范圍內(nèi)接受輸入,因此這個范圍的表現(xiàn)良好。中心點是[0.5,0.5]。

神經(jīng)網(wǎng)絡(luò)的輸出即正方形中像素點的RGB顏色值。[0,0,0]表示黑色,[1,1,1]表示白色。當(dāng)你在繪圖區(qū)域畫點時,就等同于在提供訓(xùn)練數(shù)據(jù)。輸入神經(jīng)元將會根據(jù)你輸入的數(shù)據(jù)訓(xùn)練出放置x坐標(biāo)和y坐標(biāo)的方式。期望或者理想中的輸出應(yīng)該是與你在該位置選擇的顏色近似一致。

讓我們來看一個簡單的案例。如果你只畫出兩個數(shù)據(jù)點,那么這個區(qū)域就會被分割成兩部分。如下圖所示,你可以看到一個紅色的數(shù)據(jù)點和一個藍色的數(shù)據(jù)點。

圖8:兩個數(shù)據(jù)點的分類

該算法為了讓應(yīng)用程序得到的錯誤評級比較低,它僅需要保證藍色數(shù)據(jù)點位于藍色區(qū)域,而紅色數(shù)據(jù)點位于紅色區(qū)域。其他所有像素點都是基于已知像素點的“猜測”。但由于這樣已知的數(shù)據(jù)非常少,所以神經(jīng)網(wǎng)絡(luò)很難真正猜到這兩個區(qū)域之間的邊界到底在哪里。

如果你提供了更多的訓(xùn)練數(shù)據(jù),那你會得到一個更加復(fù)雜的形狀。如果你選擇創(chuàng)建一個雙色的隨機圖像,那你會得到與下圖類似的數(shù)據(jù)點。

圖9:多個數(shù)據(jù)點的分類

在此圖中,神經(jīng)網(wǎng)絡(luò)創(chuàng)建了一種更加復(fù)雜的模式試圖來適應(yīng)所有的數(shù)據(jù)點。

你還可以選擇創(chuàng)建一個復(fù)雜的多顏色模式。下面的案例中為數(shù)據(jù)點隨機生成了顏色值。神經(jīng)網(wǎng)絡(luò)甚至?xí)㈩伾M行混合,試圖做出妥協(xié),以此來盡可能地降低誤差。

圖10:多顏色數(shù)據(jù)點分類

此算法甚至有可能學(xué)習(xí)復(fù)雜的相互螺旋的形狀,如下圖所示。

圖11:螺旋數(shù)據(jù)點的分類

延伸閱讀

本文介紹了JavaScript中的機器學(xué)習(xí),如果想了解更多關(guān)于機器學(xué)習(xí)的知識,那么你可能會對下面的鏈接感興趣。

Encog 項目

Encog 維基百科

關(guān)于Encog的更多信息

Facebook上關(guān)于Encog的內(nèi)容

歷史

2012年10月16日的第一個版本,引用文件版本 Encog JS v1.0

翻譯人:白加黑大人,該成員來自云+社區(qū)翻譯社
原文鏈接:https://www.codeproject.com/A...
原文作者:JeffHeaton
原文譯題:通過JS庫Encog實現(xiàn)JavaScript機器學(xué)習(xí)和神經(jīng)學(xué)網(wǎng)絡(luò)
相關(guān)閱讀

Python中Keras深度學(xué)習(xí)庫的回歸教程

從程序員的角度設(shè)計一個Java的神經(jīng)網(wǎng)絡(luò)

如何使用 scikit-learn 為機器學(xué)習(xí)準(zhǔn)備文本數(shù)據(jù)

此文已由作者授權(quán)云加社區(qū)發(fā)布,轉(zhuǎn)載請注明文章出處

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107363.html

相關(guān)文章

  • JavaScript機器學(xué)習(xí)之線性回歸

    摘要:不能用于機器學(xué)習(xí)太慢幻覺矩陣操作太難有函數(shù)庫啊,比如只能用于前端開發(fā)開發(fā)者笑了機器學(xué)習(xí)庫都是開發(fā)者機器學(xué)習(xí)庫神經(jīng)網(wǎng)絡(luò)神經(jīng)網(wǎng)絡(luò)自然語言處理卷積神經(jīng)網(wǎng)絡(luò)一系列庫神經(jīng)網(wǎng)絡(luò)深度學(xué)習(xí)我們將使用來實現(xiàn)線性回歸,源代碼在倉庫。 譯者按: AI時代,不會機器學(xué)習(xí)的JavaScript開發(fā)者不是好的前端工程師。 原文: Machine Learning with JavaScript : Part 1 ...

    gitmilk 評論0 收藏0
  • 深度學(xué)習(xí)之父的傳奇人生

    摘要:隨后深度學(xué)習(xí)的研究大放異彩,廣泛應(yīng)用在了圖像處理和語音識別領(lǐng)域。比如的學(xué)生就用深度學(xué)習(xí)算法贏得年的。深度學(xué)習(xí)和人工智能的春天離人工智能最近的互聯(lián)網(wǎng)公司敏銳嗅到了這一機遇。 多倫多大學(xué)計算機系教授Geoffrey Hinton是Deep Learning的開山鼻祖,我們來講講他的故事。他有個傳奇的姑姑不過先來說說他姑姑吧,他姑姑Joan Hinton是一個與中國有關(guān)的具有傳奇經(jīng)歷的人物,中文名...

    Jinkey 評論0 收藏0
  • Tensorflow學(xué)習(xí)之建造神經(jīng)網(wǎng)絡(luò)

    摘要:接下來,是很關(guān)鍵的一步,如何讓機器學(xué)習(xí)提升它的準(zhǔn)確率。機器學(xué)習(xí)的內(nèi)容是用來每一次的數(shù)據(jù),逐步提升神經(jīng)網(wǎng)絡(luò)的預(yù)測準(zhǔn)確性。每步我們輸出一下機器學(xué)習(xí)的誤差。 經(jīng)過前期的學(xué)習(xí),這一節(jié)來學(xué)習(xí)稍微綜合一點的,建造一個完整的神經(jīng)網(wǎng)絡(luò),包括添加神經(jīng)層,計算誤差,訓(xùn)練步驟,判斷是否在學(xué)習(xí)。 添加層 構(gòu)造添加一個神經(jīng)層的函數(shù)。 def add_layer(inputs, in_size, out_size...

    NSFish 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<