邁向機器學習的第一步從這裡開始

程序員書屋 發佈 2020-01-20T01:44:03+00:00

清單7-1 簡單訓練數據Input:[1], Desired Output: [7]Input: [2], Desired Output: [14]Input: [3], Desired Output: [21]顯然係數5無法產生預期輸出。

本文要點:

  • 多項式擬合;
  • 貪心隨機訓練;
  • 徑向基函數(RBF function);
  • 徑向基函數網絡模型(RBF Network Model)。

從前面幾章我們知道,機器學習算法的一般形式是接受出入向量,生成輸出向量。要把輸入向量變換到輸出向量,還要用到另外兩個向量,這兩個額外的向量分別叫作「長期記憶」和「短期記憶」。長期記憶又被稱為「權重」或「係數」,是通過訓練來調整的;短期記憶則並非所有的機器學習算法都需要用到。

把機器學習算法想成是一個函數可能會有助於理解。為了便於演示,我們假設式7-1所示的簡單等式是一個機器學習算法。

(7-1)

此處我們假設x是一個單值標量,而非一個向量;值5則是一個係數。通常來說,係數會被組合成一個向量的形式,用以表示算法的「長期記憶」。當我們對式7-1所示的機器學習算法進行訓練的時候,我們會調整係數直到得到預期輸出。如果清單7-1所示是式7-1對應算法的訓練數據,那麼就可以向式7-1提供輸入,並對其輸出結果進行評估。

清單7-1 簡單訓練數據

Input: [1], Desired Output: [7]Input: [2], Desired Output: [14]Input: [3], Desired Output: [21]

顯然係數5無法產生預期輸出。根據第6章所講的內容,我們可以計算上述預期輸出和式7-1的實際輸出之間的誤差,比如式7-1的輸入為1,則實際輸出為5,而對應的預期輸出卻是7。

要為機器學習算法搜尋適當的係數有許多種不同的方法,並且調整係數的方法也是機器學習的主要研究領域。

如果機器學習算法是一個如式7-1的線性函數,一般會用精確的數學方法來求合適的係數。就本例而言,我們只需找到乘以1後所得結果為7的係數即可,因此係數就是7。並且係數為7的話,對訓練集中的其他數據誤差也為0。

並非所有的數據集都像清單7-1這麼簡單,事實上,能夠通過擬合係數(長期記憶向量)得到完全零誤差的情況是十分少見的,因為大多數數據包含了噪聲。所謂「噪聲」,指的是輸入數據中任何不可復現的部分,因此會導致更高的誤差。由於噪聲的緣故,機器學習算法的目標一般也是「算法在新數據上運行良好」,而不會苛求「零誤差」。

如果得到了零誤差的結果,反而應該懷疑是否出現了過擬合現象。過擬合現象的出現是由於機器學習算法已經完全「記住」了訓練數據,這種情況下,算法已經不再提取特徵,轉而僅僅重複調用記憶好的輸入向量,因此過擬合的算法對不在原訓練數據集中的新數據不具有良好的表現。

接下來讓我們來看看優化係數、降低誤差的方法,並且還會介紹一些優化係數的基本算法,第8章則會討論像模擬退火算法、Nelder -Mead算法[1]這樣更加高級的算法。

本書中出現的大多數訓練算法具有通用性,對任何給定的「長期記憶」,這些算法都可以嘗試進行優化;但也不是所有的算法都如此,有些訓練算法對訓練的模型有獨特的適用性,在第10章中就可以看到這樣的算法。當然,除此以外,本書其他章節中大多數算法是通用算法。

7.1  多項式係數

本節將以一個多項式作為待優化的機器學習算法,來介紹優化多項式係數的通用訓練方法。一般來說,要優化的係數比一個簡單的多項式更為複雜,但這樣的例子可以作為介紹機器學習算法的一個很好的切入點。在一個數據集上擬合多項式,可以有效說明那些複雜的機器學習算法的基本工作原理。

所謂多項式,其實就是由變量和常係數組成的數學表達式,其中的運算只有加法、減法、乘法和正整數的冪運算,式7-2就是一個典型的二次多項式[2]。

(7-2)

式7-2接受一個值x,返回一個值y,輸入、輸出向量的大小均為1,式中三個係數分別為:2,4,6。其中,各係數均乘以變量x的冪項,係數2乘以x的平方,係數4乘以x,係數6則乘以x的0次冪,也就是常數1,表現出來就是一個單純的常數項。

式7-2所示多項式共有3項,每一項對應一個係數,則式(7-2)中的3個係數可以視作一個向量並表示如下:

[2, 4, 6]

就式7-2而言,係數均已確定,但一般情況下係數的值需要使用機器學習算法來確定。要達到這個目的,就需要用包含各種預期輸出的訓練集來對算法進行訓練,其中,不同的預期輸出對應於各種不同的輸入,這樣的訓練數據可以經由實驗收集。要將這些數據擬合為二次多項式,機器學習算法就很有用處。

接下來讓我們先創建一些訓練數據。已知所要的解是係數[2, 4, 6],這當然完全是人為設定的,但有助於說明基本訓練算法的使用。要生成訓練數據,只需疊代多個x的值,並計算出對應的多項式的值即可,然後使用隨機的係數來訓練,以接近正確的係數。我們將僅使用訓練數據,以此來看看能否重新獲得正確的係數。

生成的訓練數據如清單7-2所示,顯然,這是將輸入從-50疊代到+50的結果,理想輸出由計算得出。

清單7-2 多項式訓練數據

[BasicData: input: [-50.0], ideal: [4806.0]][BasicData: input: [-49.0], ideal: [4612.0]][BasicData: input: [-48.0], ideal: [4422.0]]...[BasicData: input: [47.0], ideal: [4612.0]][BasicData: input: [48.0], ideal: [4806.0]][BasicData: input: [49.0], ideal: [5004.0]]

給定以上數據,接下來看看如何調整係數以產生這些數。下一節要介紹的是如何使用清單7-2所示的數據來重建式7-2所示的多項式——當然,首先要假定我們並不知道實際的多項式,所有的條件僅僅是清單7-2中的數據。

7.2  訓練入門

在訓練期間調整一個機器學習算法的長期記憶的方法有很多,在本節中,我們將介紹的是「貪心隨機訓練算法」,這個算法實現起來很簡單。在第8章中,我們將會介紹適應性和穩定性更強的訓練算法,這些更加強健的訓練算法能夠比貪心隨機訓練法更快地找到「長期記憶」的最優值。

貪心隨機訓練算法

貪心隨機訓練算法實現起來尤其簡單,概括起來基本上就是為長期記憶向量隨機選取一組值。算法的「貪心」之處在於它只保存到當前為止效果最好的一組長期記憶值,如果新的長期記憶值比上一組性能更優,毫無疑問算法會選擇保存新的這一組值而丟棄之前的值,這一算法有時也被稱作「隨機漫步算法」。

這一算法可以用如清單7-3所示的偽代碼表示。

清單7-3 貪心隨機訓練算法(最小性能版本)

function iteration( ltm, // 當前的長期記憶向量 lowRange, // 隨機範圍的最小值 highRange //隨機範圍的最大值){ // 評估當前狀態的性能 oldScore = calculateScore(ltm); // 保存當前狀態的副本 // 以免性能提升失敗 len = ltm.length; oldLtm = ltm.clone(); // 隨機設置一個狀態 for i from 0 to len {  ltm[i] = rand(lowRange, highRange); } // 對新的隨機狀態進行評估 newScore = calculateScore(ltm); // 貪心判定。新的隨機狀態相對上一個狀態是否有性能上的提升? // 如果沒有,則恢復上一個狀態 if(newScore>oldScore) {  ltm = oldLtm.clone();2 }}

上述代碼實現了貪心隨機訓練算法的一個疊代,傳遞的參數共有3個。

  • 參數1:要優化的長期記憶向量;
  • 參數2和參數3:給長期記憶向量中各元素賦值的隨機範圍上下限。

疊代函數把隨機值賦給長期記憶向量,將隨機賦值前後的評估得分進行比較,如果得分沒有下降,則丟棄新的長期記憶值並恢復上一個狀態的長期記憶值。算法只接受性能有所改善的結果,這正是算法被稱作「貪心」的原因,卻並非總是最佳策略。俗話說得好,「退步原來是向前」,偶爾在性能上適當地妥協可能會在之後得到更佳的結果。

無論如何,貪心隨機訓練算法確實可以對向量值進行訓練。對形如式7-2的多項式運行算法,可以得到如下結果:

Iteration #999984, Score = 37.93061791363337,Iteration #999985, Score = 37.93061791363337,Iteration #999986, Score = 37.93061791363337,Iteration #999987, Score = 37.93061791363337,Iteration #999988, Score = 37.93061791363337,Iteration #999989, Score = 37.93061791363337,Iteration #999990, Score = 37.93061791363337,Iteration #999991, Score = 37.93061791363337,Iteration #999992, Score = 37.93061791363337,Iteration #999993, Score = 37.93061791363337,Iteration #999994, Score = 37.93061791363337,Iteration #999995, Score = 37.93061791363337,Iteration #999996, Score = 37.93061791363337,Iteration #999997, Score = 37.93061791363337,Iteration #999998, Score = 37.93061791363337,Iteration #999999, Score = 37.93061791363337,Iteration #1000000, Score = 37.93061791363337,Final score: 37.930617913633372.0026889363153195xˆ2 + 4.057350732096355x + 9.393343096548456

如上所示,貪心隨機訓練算法的結果與預期係數相當接近,預期結果是[2,4,6],而算法得到的結果則是[2.002,4.057,9.3933]。

貪心隨機訓練算法的結果一般被作為一個基準,可以將貪心隨機訓練算法的結果與要評估的新算法進行比較,如果新算法的表現不比貪心隨機訓練算法好,就說明新算法的性能堪憂。

7.3  徑向基函數網絡

上一節中,我們學習了如何優化多項式係數,但大多數機器學習算法比一個簡單多項式複雜得多。本節我們就將介紹一種被稱為「徑向基函數網絡[3]」(Radial Basic Function Network,RBF Network)的算法模型,這是一種可以用於回歸和分類的統計模型。

徑向基函數網絡有一個代表「長期記憶」的向量,但不存在「短期記憶」向量,其中「長期記憶」由係數和其他參數組合而成。訓練該網絡的方法有很多,網絡以徑向基函數為基本組成結構,並且貪心隨機訓練算法和爬山算法都可以用於訓練這種網絡。

第7.3.1節會簡單熟悉一下徑向基函數的概念,並給出其長期記憶向量具體都由哪些成分組成。

7.3.1 徑向基函數

徑向基函數是人工智慧領域一個非常重要的概念,因為很多人工智慧算法都需要用到這種技術。徑向基函數也分為許多種不同的類型,本章會介紹其中一部分。

徑向基函數關於其在x軸上的中點對稱,並在中點處達到最大值,這一最大值稱作「峰值」,且峰值一般為1。實際上在徑向基函數網絡中,峰值總是1,中點則視情況而定。

徑向基函數可以是多維的,但無論輸入向量是多少維,輸出都總是一個標量值。

有很多常見的徑向基函數,其中最常用的就是「高斯函數」。圖7-1就是對稱軸為直線x=0的一維高斯函數圖像。

徑向基函數通常被用於選擇性地放縮數據,高斯函數也不例外。以圖7-1為例,如果用這個函數來放縮數據,則中心點處放縮幅值最大,越往x軸正負方向放縮幅值越小。

圖7-1 高斯函數

在給出高斯徑向基函數的公式之前,先要研究一下多維的情況如何處理。需要注意的是,徑向基函數的輸入是多維數據,返回的則是一個標量值——這是通過計算徑向基函數的輸入向量和中心向量之間的距離實現的,其中「距離」記為r。當然,要使計算能夠進行,輸入向量和中心向量維數必須相同。只要計算出了這個r,接下來就可以計算出對應的徑向基函數值了——所有的徑向基函數都要用到這個計算出的「距離」r

式7-3即為r的計算公式:

{—:}(7-3)

式7-3中雙重豎線的符號表示計算的是「距離」。歐氏距離是徑向基函數中最常用的距離概念,但在特殊情況下,也有可能使用其他的距離概念——本書中的示例均使用歐氏距離。因此本書中的r就是指的輸入向量x和中心向量xi之間的歐氏距離,本節所有徑向基函數中的「距離」r均由式7-3計算得出。

高斯徑向基函數的公式如式7-4所示:

{—:}(7-4)

只要計算出了r,計算徑向基函數的值就很容易了,式7-4中的希臘字母

一般用來表示「徑向基函數」。

高斯函數並非唯一的徑向基函數,還有一些其他的徑向基函數,其函數圖像也各不相同。如果使用徑向基函數來進行數據放縮的話,不同的函數圖像則意味著不同的放縮方式。圖7-2所示是Ricker小波的函數圖像。

圖7-2 Ricker小波(墨西哥帽函數)

Ricker小波函數也經常被用作徑向基函數,由於其函數圖像與墨西哥的寬邊帽形狀十分相似,因此又被稱作「墨西哥帽函數」,如式7-5所示。

{—:}(7-5)

從圖7-2可以看出,Ricker小波函數實際上是在兩邊進行負向放縮,繼續增大「距離」r的絕對值則放縮幅度逐漸回歸到0值。

不同的徑向基函數適用於不同的情況,還有一些常用的徑向基函數包括:

  • 多二次函數(Multiquadric);
  • 逆二次函數(Inverse quadratic);
  • 逆多二次函數(Inverse multiquadric);
  • 多重調和樣條(Polyharmonic spline);
  • 薄板樣條(Thin plate spline)。

使用徑向基函數可以實現被稱作「徑向基函數網絡」的統計模型,並且可以使用任何此前討論過的方法來訓練這個模型。

7.3.2 徑向基函數網絡

徑向基函數網絡是一種既可以用於分類問題,也可以用於回歸問題的統計模型。該網絡本質上就是一至多個徑向基函數的加權求和,其中每個徑向基函數均接受一個帶權重的輸入,從而對輸出進行預測。式7-6描述了一個徑向基函數網絡:


(7-6)

注意其中雙豎線表示運算結果是「距離」,但並未規定計算距離的算法,也就是說選取哪種距離參與運算需要視情況而定。上式中X指的是輸入向量;c是徑向基函數的中心向量;p是所選的徑向基函數(比如高斯函數);a是每個徑向基函數對應的係數,一般為向量形式,也稱「權重」;b則是每個輸入對應的權重係數。本章稍後會給出式7-6對應的偽代碼實現。

下面以鳶尾花數據集為例,應用徑向基函數網絡,圖7-3即為該網絡的圖形化表示。

圖7-3所示的網絡有4項輸入(包括花萼寬、花萼長、花瓣寬、花瓣長),分別對應於描述鳶尾花種屬的各項特徵。為簡單起見,圖7-3中假定3個鳶尾花種屬的編碼方式為獨熱編碼法;當然也可以用等邊編碼法,不過輸出項就應該只有兩個了。示例中需要選取3個徑向基函數——這一選擇沒有什麼限制條件,全憑個人喜好。增加徑向基函數的數目能夠使模型學習更加複雜的數據集,但也會耗費更多的時間。

圖7-3中的箭頭代表的是式7-6中全部的係數:輸入和徑向基函數之間的箭頭表示的是式7-6中的係數b;徑向基函數和求和號之間的箭頭則表示係數a。可能你也注意到了圖7-3中的「偏置框」,這是人為添加的一個返回值總是1的函數;由於輸出是一個常數,因此也就不需要輸入。偏置項到求和號之間的權重起著類似於線性回歸中「截距」的作用,因此偏置的存在並不總是壞事兒,在本例中,偏置就是徑向基函數網絡的一個重要組成部分。在神經網絡中,也經常會用到「偏置節點」。

圖7-3 以鳶尾花數據集為輸入的徑向基函數網絡

從圖7-3中的求和號有多個可以看出,這是一個分類問題,幾個求和運算的最大值所對應項即預測結果。而如果是一個回歸問題,則輸出應當只有一項。該輸出即回歸問題的預測結果。

你肯定注意到了圖7-3中的偏置節點,其所在位置與徑向基函數同一層級,就像是另一個徑向基函數,只不過不像徑向基函數那樣需要接受輸入而已。這個偏置節點總是輸出常數1,然後這個1再乘以對應的係數,就相當於無論輸入是什麼情況,都把對應係數直接加到了輸出項中。尤其在輸入為0的時候,偏置節點就會很有用,因為它使得即使輸入為0,徑向基函數層也依然有值可以輸出。

徑向基函數網絡的長期記憶向量由幾個不同的部分組成:

  • 輸入係數;
  • 輸出係數(求和係數);
  • 徑向基函數放縮範圍(在各維度上範圍相同);
  • 徑向基函數中心向量。

徑向基函數網絡把這所有的元素保存為一個向量,這個向量即為該徑向基函數網絡的「長期記憶向量」。稍後我們會使用貪心隨機訓練算法或爬山算法來訓練網絡,以使其長期記憶向量的值達到能夠根據提供的特徵數據正確判斷鳶尾花類別的程度。

這個模型的工作原理與此前的多項式相差無幾,僅有的不同在於表達式更加複雜,因為現在需要計算多個輸出值以及徑向基函數的函數值了。

7.3.3 實現徑向基函數網絡

本節要給出作為示例的徑向基函數網絡中,兩個主要函數的偽代碼實現。首先來看徑向基函數網絡的初始化函數,該函數的主要作用是在生成徑向基函數的時候,給網絡分配長期記憶向量。要創建一個徑向基函數網絡,需要提供下列3項信息:

  • 輸入通道數目;
  • 徑向基函數數目;
  • 輸出通道數目。

輸入和輸出的數目決定於輸入和輸出向量的大小,對於選定數據集,這些值也是給定的。徑向基函數的數目就稍微主觀一些,使用的徑向基函數越多,模型得到預期結果的性能就越好,但同時也會導致模型的時間效率下降。

清單7-4給出了初始化一個徑向基函數網絡的偽代碼。

清單7-4 初始化徑向基函數網絡

function initRBFNetwork( theInputCount, // 網絡的輸入通道數目 rbfCount, // 網絡中徑向基函數的數目 theOutputCount // 網絡的輸出通道數目){ result = new RBFNetwork(); // 給該網絡設置幾個簡單的參數 result.inputCount = theInputCount; result.outputCount = theOutputCount; // 計算輸入和輸出權重的數目 // 由於額外的偏置節點,因此要在輸出中加1 inputWeightCount = inputCount∗rbfCount; outputWeightCount = (rbfCount + 1) ∗outputCount; rbfParams = (inputCount + 1) ∗rbfCount; // 為長期記憶向量分配足夠的空間 result.longTermMemory = alloc(inputWeightCount + outputWeightCount + rbfParams); // 設置網絡的其他參數 result.indexInputWeights = 0; result.indexOutputWeights = inputWeightCount + rbfParams; // 分配徑向基函數 result.rbf = new FnRBF[rbfCount]; // 設置每一個徑向基函數 for i from 0 to rbfCount { // 獲取當前徑向基函數(在整個長期記憶向量中)對應的索引 rbfIndex = inputWeightCount + ((inputCount + 1) ∗i); // 分配一個高斯函數,並指定輸入數目和 // 該徑向基函數參數在長期記憶向量中的存儲位置。 // 高斯函數的參數是寬度和中心點位置 result.rbf[i] = new GaussianFunction(  inputCount, result.longTermMemory, rbfIndex); } // 返回新生成的網絡 return result;}

上述方法開頭分配了一個名為「result」的對象來保存徑向基函數網絡,其中保存的內容包括長期記憶向量和網絡的其他基本參數。

上述代碼精確計算了保存各個係數和徑向基函數參數這些長期記憶需要多大的空間,且每個徑向基函數都被分配了一段長期記憶對應的存儲空間來保存相應的函數參數。本例中,徑向基函數的參數是:① 寬度;② 中心點位置。

上述代碼實際上並未給長期記憶賦值,因此在網絡構造完成之後,一般會賦給一組隨機值,稱之為「初始化點」。之後,「訓練」的過程會調整長期記憶的值,以向能夠產生接近預期輸出的值靠攏。就本例的鳶尾花數據集而言,輸出指的就是網絡判斷出的輸入數據對應的鳶尾花種屬。

徑向基函數網絡構建完畢,且長期記憶設置好之後,就可以開始訓練網絡了。首先就需要調用徑向基函數網絡模型,並評估其初始化的輸出——由於初始化點是一組隨機值,因此最初的輸出結果表現不會很好,但訓練畢竟還是需要從某組值開始,也就無所謂是不是隨機值了。

跟多項式的情況一樣,我們也必須計算徑向基函數網絡的輸出,清單7-5中的偽代碼就體現了這一計算過程。

清單7-5 計算徑向基函數網絡的輸出

function computeRBFNetwork(  input,//輸入向量  network // 徑向基函數網絡){  // 首先,計算每個徑向基函數的輸出值  // 添加一個額外的徑向基函數輸出值作為偏置  // (偏置值總為1)  rbfOutput = alloc(network.rbf.length + 1);  // 偏置值總為1  rbfOutput[rbfOutput.length − 1] = 1;  for rbfIndex from 0 to network.rbf.length{   // 輸入加權   weightedInput = alloc(input.length);   for inputIndex from 0 to input.length   {    memoryIndex = network.indexInputWeights     +(rbfIndex∗network.inputCount) + inputIndex;    weightedInput[inputIndex] = input[inputIndex]∗network.longTermMemory[memoryIndex];  }  // 計算當前徑向基函數的值  rbfOutput[rbfIndex] =  network.rbf[rbfIndex].evaluate(weightedInput);  }  // 計算輸出值  // 其值為各徑向基函數輸出的加權結果  result= alloc(network.outputCount);  for outputIndex from 0 to result.length  {   sum = 0;   for rbfIndex from 0 to rbfOutput.length   {    // 徑向基函數個數在原來的基礎上加1,作為偏置項    memoryIndex = network.indexOutputWeights     +(outputIndex∗(network.rbf.length + 1)) + rbfIndex;    sum += rbfOutput[rbfIndex]     ∗network.longTermMemory[memoryIndex];   }   result[outputIndex] = sum;  }  // 最後,返回計算結果  return result;}

上述代碼計算出了多層網絡的最終輸出,下面簡單介紹代碼邏輯。首先創建名為rbfOutput的變量,顧名思義,該變量用以保存各徑向基函數的輸出。接下來依次遍歷徑向基函數,並計算出每個徑向基函數的加權輸入——所謂「加權輸入」,其實就是將輸入與徑向基函數的輸入係數相乘得到的向量。在圖7-3中,最左邊的一列箭頭代表的就是這些輸入係數。依次計算出徑向基函數的值,就得到了除最後一個元素以外的整個rbfOutput向量,而這最後一個元素作為偏置節點,其值恆為1。

得到rbfOutput向量之後,將其乘以網絡的輸出係數,也就是圖7-3中最右邊一列箭頭所代表的係數(實際上是中間那一列箭頭)。最後把計算出的輸出值保存到結果向量中,並將結果向量的值返回給主調函數。

7.3.4 應用徑向基函數網絡

下面分別給出了在XOR(異或)數據集和鳶尾花數據集上應用徑向基函數網絡的示例,可以清楚地看到徑向基函數是如何擬合數據集的預期輸出的。我們先來看看在XOR數據集上,經過隨機訓練算法訓練後模型的輸出效果。

Iteration #999996, Score = 0.013418057671024912,Iteration #999997, Score = 0.013418057671024912,Iteration #999998, Score = 0.013418057671024912,Iteration #999999, Score = 0.013418057671024912,Iteration #1000000, Score = 0.013418057671024912,Final score:  0.013418057671024912[0.0, 0.0] −> [−0.16770550224628078], Ideal: [0.0][1.0, 0.0] −> [0.9067663351025073], Ideal: [1.0][0.0, 1.0] −> [0.8703332321473845], Ideal: [1.0][1.0, 1.0] −> [0.0064115711694006094], Ideal: [0.0]

經過大量的疊代,最後終於把評估得分降到了0.01,在上述輸出效果中,顯然我們略過了大部分的訓練疊代,並且從上面的輸出也可以看出,實際輸出與理想輸出並不嚴格相等。比如第一個輸入[0, 0]對應的理想輸出是[0],而實際輸出則是一個與之相當接近的值,-0.16。理想輸出本應均為1的兩個輸入,對應的實際輸出則是與1相近的兩個值,分別為0.906和0.87。

在鳶尾花數據集上訓練的輸出結果如下:

Iteration #99971, Score = 0.08747428121794937,Iteration #99972, Score = 0.08747428121794937,Iteration #99973, Score = 0.08747428121794937,Iteration #99974, Score = 0.08747428121794937,Iteration #99975, Score = 0.08747428121794937,Iteration #99976, Score = 0.08747428121794937,Iteration #99977, Score = 0.08747428121794937,Iteration #99978, Score = 0.08747428121794937,Iteration #99979, Score = 0.08747428121794937,Iteration #99980, Score = 0.08747428121794937,Iteration #99981, Score = 0.08747428121794937,Iteration #99982, Score = 0.08747428121794937,Iteration #99983, Score = 0.08747428121794937,Iteration #99984, Score = 0.08747428121794937,Iteration #99985, Score = 0.08747428121794937,Iteration #99986, Score = 0.08747428121794937,Iteration #99987, Score = 0.08747428121794937,Iteration #99988, Score = 0.08747428121794937,Iteration #99989, Score = 0.08747428121794937,Iteration #99990, Score = 0.08747428121794937,Iteration #99991, Score = 0.08747428121794937,Iteration #99992, Score = 0.08747428121794937,Iteration #99993, Score = 0.08747428121794937,Iteration #99994, Score = 0.08747428121794937,Iteration #99995, Score = 0.08747428121794937,Iteration #99996, Score = 0.08747428121794937,Iteration #99997, Score = 0.08747428121794937,Iteration #99998, Score = 0.08747428121794937,Iteration #99999, Score = 0.08747428121794937,Iteration #100000, Score = 0.08747428121794937,Final score: 0.08747428121794937

上述輸出表明,通過使用貪心隨機訓練算法並經過大量疊代,整個訓練過程一直持續到評分降到了0.08的等級,這意味著大多數鳶尾花都能夠被正確地分類。在第8章,我們會使用更先進的算法,在更少的疊代次數內得到更好的結果。

7.4 本章小結

本章介紹了訓練機器學習算法的基礎知識,正常來說,在訓練過後,對於特定輸入,機器學習算法都能夠產生與預期結果接近的輸出。而帶有預期輸出的給定輸入就是被用來訓練模型的所謂「訓練集」。

大多數機器學習算法有「長期記憶」這個屬性,並在訓練過程中不斷調整。「長期記憶」還有個名字叫作「權重」,有時也被稱作「係數」,一般被保存為向量形式。

本章還介紹了貪心隨機訓練算法,這是一種很簡單的訓練算法,其實就是給長期記憶隨機賦值,不斷嘗試新的參數組合,並保存表現最佳的參數組合。同時,該算法也經常作為一個基準,用以衡量比較其他算法的性能。

在本章中我們訓練了兩個不同的模型:一個簡單的多項式和一個徑向基函數網絡模型。多項式的例子展示了貪心隨機訓練算法如何用於擬合簡單公式,並用該算法估計了示例多項式中的3個係數。

徑向基函數網絡模型的基礎就是徑向基函數,這種函數具有關於中點對稱的特性。每個徑向基函數都具有多維的中心點,和可變的寬度值;但要注意的是,對指定的徑向基函數而言,在各個維度上,寬度的大小是一致的。本章中,我們使用的是高斯徑向基函數。

徑向基函數網絡使用訓練算法來調整長期記憶的值,模型最終可以用於分類或回歸問題。其中模型的長期記憶包括係數、徑向基函數寬度和徑向基函數的中心點向量。本章中構建出的模型用來擬合了鳶尾花數據集。

第8章會介紹其他的一些優化算法,均可用於調整徑向基函數網絡的長期記憶值。實際上只要模型保存了類似於長期記憶向量這樣的狀態屬性,都可以應用這些優化算法。具體來說,這些算法包括爬山算法、模擬退火算法和Nelder-Mead訓練算法。


[1] 也稱「下坡單純形法」。——譯者注

[2] Lial, 2010。

[3] Bishop,1996。

本文摘自《人工智慧算法 卷1 基礎算法》,[美] 傑弗瑞·希頓(Jeffery Heaton) 著,李爾超 譯。

  • AI算法入門教程書籍,人人都能讀懂的人工智慧書
  • 全彩印刷,實例講解易於理解的人工智慧基礎算法
  • 多種語言版本示例代碼、豐富的在線資源,方便動手實戰與拓展學習

欲建高樓,必重基礎。本書講授諸如維度法、距離度量算法、聚類算法、誤差計算、爬山算法、模擬退火算法、Nelder-Mead算法和線性回歸算法等人工智慧基礎算法。

本書中所有算法均配以具體的數值計算示例。「人工智慧算法」系列圖書的目標讀者是那些沒有良好數學基礎,又對人工智慧感興趣的人。本書讀者只需具有基本的大學代數和計算機編程知識,任何超出這個範圍的內容都會在書中詳細說明。本書為讀者提供配套的示例程序代碼, 當前已有Java、C#、R、C/C++和Python的語言版本,還有社區支持維護的Scala語言版本。

關鍵字: