如何手動優化神經網絡模型(附鏈接)

翻譯:陳丹  校對:車前子

本文約5400字,建議閱讀15分鐘

本文是一個教授如何優化神經網絡模型的基礎教程,提供了具體的實戰代碼供讀者學習和實踐。

深度學習的神經網絡是採用隨機梯度下降優化算法對訓練數據進行擬合。

利用誤差反向傳播算法對模型的權值進行更新。優化和權值更新算法的組合是經過仔細挑選的,是目前已知的最有效的擬合神經網絡的方法。

然而,也可以使用交替優化算法將神經網絡模型擬合到訓練數據集。這是一個有用的練習,可以瞭解更多關於神經網絡的是如何運轉的,以及應用機器學習時優化的中心性。具有非常規模型結構和不可微分傳遞函數的神經網絡,也可能需要它。

在本教程中,您將瞭解如何手動優化神經網絡模型的權重。

完成本教程後,您將知道:

  • 如何從頭開始開發神經網絡模型的正向推理通路。

  • 如何優化二值分類感知器模型的權值。

  • 如何利用隨機爬山算法優化多層感知器模型的權值。

我們開始吧。

圖源土地管理局,權利歸其所有

教程概述

本教程分爲三個部分:它們是:

  • 優化神經網絡

  • 優化感知器模型

  • 優化多層感知器

優化神經網絡

深度學習或神經網絡是一種靈活的機器學習。

它們是受大腦結構和功能的啓發而來的,由節點和層次組成的模型。神經網絡模型的工作原理是將給定的輸入向量傳播到一個或多個層,以產生可用於分類或迴歸預測建模的數值輸出。

通過反覆將模型暴露在輸入和輸出示例中,並調整權重以使模型輸出相對於期望輸出的誤差最小來訓練模型。這就是所謂的隨機梯度下降優化算法。模型的權值是使用微積分中的一個特定規則來調整的,即將誤差按比例分配給網絡中的每個權重。這被稱爲反向傳播算法。

利用反向傳播進行權值更新的隨機梯度下降優化算法是訓練神經網絡模型的最佳方法。然而,這並不是訓練神經網絡的唯一方法。

可以使用任意的優化算法來訓練神經網絡模型。

也就是說,我們可以定義一個神經網絡模型結構,並使用給定的優化算法爲模型找到一組權重,從而使預測誤差最小或分類精度達到最大。

交替優化算法通常來說比反向傳播的隨機梯度下降算法效率更低。然而,在某些特定情況下,它可能更有效,例如非標準網絡體系結構或不可微分的傳遞函數。

在訓練機器學習的算法中,特別是神經網絡中,展示優化的中心性是一個有趣的練習。

接下來,讓我們探索如何使用隨機爬山算法訓練一個稱爲感知器模型的簡單單節點神經網絡。

優化感知器模型

感知器算法(https://machinelearningmastery.com/implement-perceptron-algorithm-scratch-python/)是最簡單的人工神經網絡。

它是一個單神經元模型,可用於兩類分類問題,爲以後開發更大的網絡提供了基礎。

在本節中,我們將優化感知器神經網絡模型的權重。

首先,讓我們定義一個綜合二進制分類問題,我們可以用它作爲優化模型的焦點。

我們可以使用make_classification()(https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_classification.html)函數定義一個包含1000行和5個輸入變量的二分類問題。

下面的示例創建數據集並總結數據的形狀。

運行上述示例,打印出所創建數據集的形狀,以確定符合我們的預期。

接下來,我們需要定義一個感知器模型。

感知器模型有一個節點,它對數據集中的每一列都有一個輸入權重。

每個輸入值乘以其相應的權重得到一個加權和,然後添加一個偏差權重,就像迴歸模型中的截距係數一樣。這個加權和稱爲活性值。最後,對活性值進行解釋並用於預測類標籤,1表示正激活,0表示負激活。

在優化模型權重之前,我們必須建立模型並相信它的運作方式。

讓我們從定義一個用於解釋模型激活的函數開始。

這被稱爲激活函數,或傳遞函數;後一個名稱更傳統,是我的首選。

下面的transfer()函數接受模型的激活並返回一個類標籤,class=1表示正激活或零激活,class=0表示負激活。這稱爲階躍函數。


接下來,我們可以開發一個函數,該函數計算來自數據集的給定輸入行的模型活性值。

此函數將獲取模型的數據行和權重,並計算輸入的加權和以及偏差權重。下面的activate()函數實現了這一點。

注意:我們特意使用簡單的Python列表和命令式編程風格,而不是NumPy的數組或列表壓縮,是爲了讓Python初學者更易讀懂。您可以隨意優化它,並在下面的註釋中發佈您的代碼。

接下來,我們可以一起使用activate()和transfer()函數來生成給定數據行的預測。下面的predict_row()函數實現了這一點。

接下來,我們可以爲給定數據集中的每一行調用predict_row()函數。下面的predict_dataset()函數實現了這一點。

同樣,我們有意使用簡單的命令式編碼方式來提高可讀性,而不是列表壓縮。

最後,我們可以使用該模型對我們的合成數據集進行預測,以確認它都是正確工作的。

我們可以使用rand()函數生成一組隨機的模型權重。

回想一下,我們需要爲每個輸入賦予一個權重(在這個數據集中有五個輸入),再加上一個額外的權重作爲偏移權重。

然後我們可以將這些權重與數據集一起使用來進行預測。

我們可以評估這些預測的分類精度。

就這樣。

我們可以將所有這些整理在一起,並演示用我們的簡單感知器模型進行分類。下面列出了完整的示例。

運行該示例將爲訓練數據集中的每個示例生成一個預測,然後打印出分類預測的準確度。

注意:您的結果可能會因爲算法或評估過程的隨機性或數值精度的差異而有所不同(https://machinelearningmastery.com/different-results-each-time-in-machine-learning/)。考慮運行該示例幾次並比較平均結果。

如果給定一組隨機權重和一個每類中有相同數量示例的數據集,我們期望大約50%的準確率,這與我們在本例中看到的差不多。

現在,我們可以優化數據集的權重,以獲得該數據集的良好準確度。

首先,我們需要將數據集分成訓練集和測試集。重要的是要保留一些未用於優化模型的數據,以便在對新數據進行預測時,我們可以對模型的性能進行合理的估計。

我們將使用67%的數據進行培訓,剩下的33%作爲測試集來評估模型的性能。

接下來,我們可以開發一個隨機爬山算法。

優化算法需要一個目標函數來優化。它必須取一組權重,並返回一個與更好的模型相對應的最小化或最大化的分數。

在這種情況下,我們將使用一組給定的權重來評估模型的準確性,並返回分類精度,這必須使其最大化。

下面的objective()函數通過給定數據集和一組權重來實現這一點,並返回模型的精度。

接下來,我們可以定義隨機爬山算法(https://machinelearningmastery.com/stochastic-hill-climbing-in-python-from-scratch/)。

該算法需要一個初始解(例如隨機權重),並且會不斷地對解進行小的修改,並檢查它是否會產生一個性能更好的模型。對當前解決方案所做的更改量由“步長”超參數控制。此過程將持續固定次數的迭代,也作爲超參數提供。

下面的hillclimbing()函數實現了這一點,它將數據集、目標函數、初始解和超參數作爲參數,並返回找到的最佳權重集和估計的性能。

然後我們可以調用這個函數,傳入一組權重作爲初始解,將訓練數據集作爲優化模型的數據集。

最後,我們可以在測試數據集上評估最佳模型並報告性能。

結合這一點,下面列出了在合成二進制優化數據集上優化感知器模型權重的完整示例。

每次對模型進行改進時,運行示例將報告迭代次數和分類精度。

在搜索的最後,報告了最佳權重集在訓練數據集上的性能,並計算和報告了同一模型在測試數據集上的性能。

注意:您的結果可能會因爲算法或評估過程的隨機性或數值精度的差異而有所不同(https://machinelearningmastery.com/different-results-each-time-in-machine-learning/)。考慮運行該示例幾次並比較平均結果。

在這種情況下,我們可以看到優化算法找到了一組權重,在訓練數據集上達到了88.5%的準確率,在測試數據集上達到了81.8%的準確率。

現在我們已經熟悉瞭如何手動優化感知器模型的權重,讓我們看看如何擴展示例來優化多層感知器(Multilayer Perceptron,MLP)模型的權重。

優化多層感知器

多層感知器(MLP)模型是一個具有一個或多個層次的神經網絡,每一層都有一個或多個節點。

它是感知器模型的擴展,可能是應用最廣泛的神經網絡(深度學習)模型。

在本節中,我們將在上一節所學的基礎上,優化每層具有任意數量層和節點的MLP模型的權重。

首先,我們將開發模型並用隨機權重進行測試,然後使用隨機爬山算法優化模型權重。

當使用MLPs進行二分類時,通常使用sigmoid變換函數(也稱爲logistic函數)來代替感知器中使用的階躍變換函數。

此函數輸出0-1之間的實數,表示二項式概率分佈(https://machinelearningmastery.com/discrete-probability-distributions-for-machine-learning/),例如一個示例屬於1類的概率。下面的transfer()函數實現了這一點。

我們可以使用上一節中相同的activate()函數。在這裏,我們將使用它來計算給定層中每個節點的激活。

predict_row()函數必須替換爲更精細的版本。

函數獲取一行數據和網絡並返回網絡的輸出。

我們將把我們的網絡定義爲一個列表。每個層將是一個節點列表,每個節點將是一個權重列表或數組。

爲了計算網絡的預測,我們簡單地枚舉層,然後枚舉節點,然後對每個節點的輸出進行激活計算和變換。在這種情況下,我們將對網絡中的所有節點使用相同的變換函數,儘管這不是必須的。

對於具有多個層的網絡,上一層的輸出用作下一層中每個節點的輸入。然後返回網絡中最後一層的輸出。

下面的predict_row()函數實現了這一點。

就是這樣。

最後我們需要定義一個網絡。

例如,我們可以使用單個隱藏層和單個節點定義MLP,如下所示:

這實際上是一個感知器,儘管它有一個sigmoid變換函數。這很無聊。

讓我們定義一個具有一個隱藏層和一個輸出層的MLP。第一個隱藏層將有10個節點,每個節點將從數據集中獲取輸入模式(例如5個輸入)。輸出層將有一個節點,從第一個隱藏層的輸出接收輸入,然後輸出預測。

然後我們可以使用模型對數據集進行預測。

在計算分類精度之前,我們必須將預測四捨五入到分類標籤0和1。

將這些整合在一起,在我們合成的二進制分類數據集上使用隨機初始權重來評估MLP的完整示例如下所示。

運行該示例將爲訓練數據集中的每個示例生成一個預測,然後打印預測的分類精度。

注意:您的結果可能會因爲算法或評估過程的隨機性或數值精度的差異而有所不同(https://machinelearningmastery.com/different-results-each-time-in-machine-learning/)。考慮運行該示例幾次並比較平均結果。

同樣,我們希望在給定一組隨機權重和一個數據集(每個類中有相同數量的示例)的情況下,準確率大約爲50%,這與我們在本例中看到的差不多。

接下來,我們可以將隨機爬山算法應用於數據集。

這與將爬山應用於感知器模型非常相同,只是在這種情況下,一個步驟需要修改網絡中的所有權重。

爲此,我們將開發一個新功能,創建一個網絡副本,並在製作副本時對網絡中的每個權重進行變異。

下面的step()函數實現了這一點。

修改網絡中的所有權重是具有侵略性的。

在搜索空間中,一個不那麼激進的步驟可能是對模型中的權重子集進行一個小的更改,也許是由一個超參數控制的。這個作爲擴展內容。

然後我們可以從hillclimbing()函數調用這個新的step()函數。

結合這一點,下面列出了應用隨機爬山算法優化二分類MLP模型權重的完整示例。

每次對模型進行改進時,運行示例將報告迭代次數和分類精度。

在搜索的最後,報告了最佳權重集在訓練數據集上的性能,並計算和報告了同一模型在測試數據集上的性能。

注意:您的結果可能會因爲算法或評估過程的隨機性或數值精度的差異而有所不同(https://machinelearningmastery.com/different-results-each-time-in-machine-learning/)。考慮運行該示例幾次並比較平均結果。

在這種情況下,我們可以看到優化算法找到了一組權重,在訓練數據集上達到了87.3%的準確率,在測試數據集上達到了大約85.1%的準確率。

進一步閱讀

如果您想深入瞭解,本節將提供有關該主題的更多資源。

教程

用於評估機器學習算法的訓練測試分割:

https://machinelearningmastery.com/train-test-split-for-evaluating-machine-learning-algorithms

如何用Python中從頭開始實現感知器算法:

https://machinelearningmastery.com/implement-perceptron-algorithm-scratch-python/

如何用Python編寫反向傳播的神經網絡(從頭開始):

https://machinelearningmastery.com/implement-backpropagation-algorithm-scratch-python/

接口

sklearn.datasets.make_classification 接口:

https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_classification.html

sklearn.metrics.accuracy_score 接口:

https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html

numpy.random.rand接口:

https://numpy.org/doc/stable/reference/random/generated/numpy.random.rand.html

總結

在本教程中,您瞭解瞭如何手動優化神經網絡模型的權重。

具體來說,你學到了:

  • 如何從頭開始開發神經網絡模型的正向推理通路。

  • 如何優化二分類感知器模型的權值。

  • 如何利用隨機爬山算法優化多層感知器模型的權值。

原文標題:

How to Manually Optimize Neural Network Models

原文鏈接:

https://machinelearningmastery.com/manually-optimize-neural-networks/

譯者簡介:陳丹,復旦大學大三在讀,主修預防醫學,輔修數據科學。對數據分析充滿興趣,但初入這一領域,還有很多很多需要努力進步的空間。

END

版權聲明:本號內容部分來自互聯網,轉載請註明原文鏈接和作者,如有侵權或出處有誤請和我們聯繫。


合作請加QQ:365242293  

數據分析(ID : ecshujufenxi )互聯網科技與數據圈自己的微信,也是WeMedia自媒體聯盟成員之一,WeMedia聯盟覆蓋5000萬人羣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章