機器學習中快速修補構建神經網絡的選擇可以是它

通用近似定理

機器學習中快速修補構建神經網絡的選擇可以是它

神經網絡在1989年首次被證實,它可以被歸類為通用函數近似器。給定任意連續的N維函數f(x),只有一個隱含層和有限數量的神經元的神經網絡能夠在x的固定範圍內和一個有限誤差ε內近似這樣的函數。

本文將利用這個定理評估一個關於多重非平凡函數的簡單體系結構,以證明我們的網絡能夠從數據中學習。

一些輔助函數

機器學習中快速修補構建神經網絡的選擇可以是它

讓我們定義這些輔助函數,這些輔助函數將幫助我們進行訓練和評估:

· genDataSet1D:使用開始、結束和步驟信息,此函數生成一個向量元組數組,每個元組對應一個(x,y)對。請注意,根據需要,這可以是任何維度,但為了簡單起見,本教程中的輸入和輸出都將是一維的。

· yRealFn:這是我們定義目標函數的地方。來自該函數的數據點將被採樣並繪製在最終圖上,以顯示我們試圖建模的實際底層函數。

· yRealFnAndNoise:該函數簡單地將一個概率項添加到yRealFn的輸出中,模擬數據中存在的噪音。但是,如果這個錯誤沒有被適當地縮放,它將會比確定性項(yRealFn)大得多,從而導致網絡學習的不是實際的函數。

· meanFeatureSqErr&evalAngEpochErr:這些函數將在本教程的訓練部分進行說明。

初始化網絡

定義架構

機器學習中快速修補構建神經網絡的選擇可以是它

為了測試我們的網絡,只有一個隱藏層的簡單神經網絡就足夠了。作者研究了一些必要的隱藏節點,以便學習任何合理的平滑函數,發現8個節點就足以完成這項工作。

根據經驗,選擇太少的隱藏節點可能會導致擬合不足,反之則會導致過度擬合。

當選擇一個激活函數時,有很多常用的方法:tanh,sigmoid,ReLU等等。作者決定採用tanh,因為它非常適合學習平滑函數中存在的非線性。

機器學習中快速修補構建神經網絡的選擇可以是它

tanh(x)(紅色)及其衍生物(綠色)。

選擇超參數

如果你一直關注機器學習,從一開始你就會意識到超參數搜索或多或少的嘗試和錯誤。當然,你還可以查看幾個時期的成本函數圖,並對你認為的最佳值進行有根據的估計。

目標函數

在開始訓練之前,還有最後一步:選擇合理複雜的函數,可以用來生成良好規劃的數據集,同時可以在視覺上進行比較。

你會注意到,對於處於相同範圍內的所有輸入,輸出都受閉區間[0,1]的限制。這是一個深思熟慮的決定,可以避免使用均值標準化,通過保持所有特徵在相似範圍內,有助於防止過度的權重。

機器學習中快速修補構建神經網絡的選擇可以是它

三個測試函數以及它們的圖的定義。

我們將使用步長為0.01的x∈[0,1]來訓練我們的網絡。因此,在這個範圍內將產生101個等間距樣本,我們將保留約6%用於驗證(統一選擇)。

機器學習中快速修補構建神經網絡的選擇可以是它

訓練我們的網絡

概述

讓我們首先從頂層收集我們需要訓練的函數:

•對於每個時期,我們需要執行梯度下降,在我們的情況下,將隨機完成(每個樣本一次)。然後,我們會在下一個時期使用更新後的網絡進行進一步的訓練。

•在此過程中,通過在每個時期結束時評估我們的網絡並獲得誤差度量(例如平方誤差)來跟蹤我們的訓練誤差。

使用MapFold

保持接近函數範例,而不是使用傳統的for循環,我們將利用List.mapFold進行訓練。

那麼mapFold如何工作?

簡而言之,它是List.fold和List.map的有效組合。它允許在給定當前列表元素和先前狀態的情況下來計算新狀態,同時使用我們選擇的函數轉換當前列表元素。這個函數的最終輸出是一個由變換列表和最終狀態組成的元組。

實現

在trainEpoch函數中,訓練數組首先隨機被打亂。這個新重組的數組被輸入到perfGradDesc。該函數通過使用Array.fold傳播網絡更新,在整個訓練數據集(單次傳遞)上執行樣本的梯度下降。

一旦我們對網絡進行了一次訓練,並從trainEpoch獲得最終網絡後,我們需要使用我們選擇的成本函數來評估該時期的訓練誤差。每個樣本的誤差需要與lastLayerDeriv函數一致。因此,對於由themeanFeatureSqErr函數實現的錯誤度量,平方誤差是最合適的選擇。

注意:儘管我們的網絡可以支持任何維度的輸出,但在涉及成本函數時,每個樣本只有一個標量度量值是有用的。因此,每個樣本的誤差將是每個輸出特徵的平方誤差的平均值。這不會影響一維輸出的誤差,並且如果所有輸出維度都具有大致相同的比例,則這是合理的選擇。

在對整個訓練集進行平均誤差後,我們得到均方誤差。該值由evalAvgEpochErrfunction計算。

最後,在每個時期結束時,(xAndyShuffArr,newNet)是傳播到下一時期的新狀態,而err是替換原始列表中時期數的映射對象。

機器學習中快速修補構建神經網絡的選擇可以是它

訓練我們的網絡的代碼

結果

機器學習中快速修補構建神經網絡的選擇可以是它

y = 0.4x 2 + 0.2 + 0.3x * sin8x的結果跨越多個時期。

這裡有一些視覺證據表明網絡實際上正在訓練!為了繪製數據,本文將使用過去用於F#繪圖的PLplot庫。繪製這些圖需要一些額外的代碼量,但這可以在本文結尾處鏈接的此項目的Github存儲庫中找到。

傳說

· 粉紅色的線代表沒有噪音的底層真實函數。這僅用於繪圖,但從未用於任何計算。

· 青色點是包括訓練和測試數據點的整個數據集。所有誤差都是參考這些點來計算的。

· 綠色圓圈表示對訓練數據進行評估的最終假設。隨著訓練週期的增加你可以觀察到它們越來越接近真實的函數曲線。

· 最後,粉紅色十字代表在測試數據上評估的最終假設。如果仔細觀察,你可以注意到它們很好地跟蹤了訓練數據點,並且這通過MSE的訓練測試分數得到了證實。

評估目標函數

機器學習中快速修補構建神經網絡的選擇可以是它

機器學習中快速修補構建神經網絡的選擇可以是它

機器學習中快速修補構建神經網絡的選擇可以是它

從上到下:f(x)= 0.4x 2 +0.2 + 0.3x * sin8x、g(x)= 0.6e ^ - (0.3sin12x /(0.3 + x))、h(x)= 0.4-0.1log x + 0.1)+ 0.5x * cos12x

這裡是三個測試函數的結果,你可以點擊其中的每一個來更詳細地查看它們。只需一眼就能看出,網絡通常在更平滑的函數上運行的更好。隨著每個函數靜止點附近的梯度增加,神經網絡訓練變得更加困難(觀察損失曲線)。這與我們使用tanh(x)作為激活函數有關。

儘管如此,我們現在已經有了通用近似定理成立的直觀證明!

結論

現在我們已經定義了我們的基本架構,並且能夠訓練任何任意數據,我們可以使用網絡來訓練和測試常用數據集。

通用近似定理在機器學習領域還有很長的路要走。它甚至可以擴展用來實現最簡單的神經網絡以提高收斂性:批量標準化,小批量梯度下降,自定義權重初始化等等。

不用擔心,F#上進行3000次訓練需要大約3秒的時間,這使得它成為快速神經網絡修補和評估的潛在候選者。使用類似設計原理和類似參數選擇的腳本的python版本需要大約168秒!

正如所承諾的,所有的源代碼都可以在Github上找到。(https://github.com/hsed/funct-nn)


分享到:


相關文章: