1. 程式人生 > >Python中從頭開始實現神經網路 - 介紹

Python中從頭開始實現神經網路 - 介紹

原文出處:
http://www.wildml.com/2015/09/implementing-a-neural-network-from-scratch/
Posted on September 3, 2015 by Denny Britz
這篇文章幫助我們用python實踐一下從零開始訓練一個神經網路。
以下是中文翻譯:

獲取程式碼
在這篇文章中,我們將從頭開始實現一個簡單的3層神經網路。 我們不會推匯出所有需要的數學運算,但是我會盡量直觀地解釋我們正在做什麼。 我也會指點資源給你閱讀細節。
在這裡,我假設你熟悉基本的微積分和機器學習的概念,例如 你知道什麼是分類和正規化。 理想情況下,您也可以瞭解梯度下降等優化技術的工作原理。 但是,即使你不熟悉以上任何一點,這篇文章仍然會變得有趣;
但為什麼從頭開始實施一個神經網路呢? 即使您計劃在將來使用像PyBrain這樣的神經網路庫,從頭開始至少實施一次網路也是非常有價值的練習。 它可以幫助您瞭解神經網路是如何工作的,這對於設計有效的模型是至關重要的。
有一點要注意的是,這裡的程式碼示例並不是非常有效。 他們的意思是很容易理解。 在即將釋出的文章中,我將探討如何使用Theano編寫高效的神經網路實現。 (更新:現在可用)

生成資料集
讓我們開始生成一個我們可以玩的資料集。 幸運的是,scikit-learn有一些有用的資料集生成器,所以我們不需要自己編寫程式碼。 我們將使用make_moons函式。

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)

這裡寫圖片描述

我們生成的資料集有兩個類,繪製成紅色和藍色的點。 你可以把藍點看作是男性患者,將紅點看作是女性患者,x軸和y軸是醫學測量。

我們的目標是訓練一個機器學習分類器,預測給定x和y座標的正確類別(女性的男性)。 請注意,資料不是線性可分的,我們不能繪製一條直線來分隔兩個類。 這意味著線性分類器(如Logistic迴歸)將無法適用資料,除非您手動設計對於給定資料集非常有效的非線性特徵(例如多項式)。

事實上,這是神經網路的主要優勢之一。 您不需要擔心功能工程。 神經網路的隱藏層將為您學習功能。

Logistic迴歸

為了證明這一點,讓我們訓練一個Logistic迴歸分類器。 它的輸入是x和y值,輸出是預測的類(0或1)。 為了讓我們的生活更輕鬆,我們使用scikit-learn的Logistic Regression類。

# Train the logistic rgeression classifier
clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X, y)

# Plot the decision boundary
plot_decision_boundary(lambda x: clf.predict(x))
plt.title("Logistic Regression")

這裡寫圖片描述

該圖顯示了我們的Logistic迴歸分類器學到的決策邊界。 它使用直線將資料儘可能分離,但無法捕捉資料的“月亮形狀”。

訓練一個神經網路

現在我們來構建一個具有一個輸入層,一個隱藏層和一個輸出層的三層神經網路。 輸入層中節點的數量取決於我們資料的維數2.類似地,輸出層中節點的數量是由我們所擁有的類的數量決定的,也是2.(因為我們只有2個類, 實際上只能有一個輸出節點預測為0或1,但有2個可以使網路稍後擴充套件到更多類)。 網路的輸入將是x和y座標,其輸出將是兩個概率,一個是0級(“女性”),一個是1級(“男性”)。 它看起來像這樣:
這裡寫圖片描述

我們可以選擇隱藏層的維數(節點數)。我們放入隱藏層的節點越多,我們就可以適應更復雜的功能。但更高的維度是有代價的。首先,需要更多的計算來進行預測並學習網路引數。更多的引數也意味著我們更容易過擬合我們的資料。

如何選擇隱藏層的大小?雖然有一些一般的指導方針和建議,但它總是取決於你的具體問題,更多的是藝術而不是科學。稍後我們將使用隱藏的節點數來看看它是如何影響我們的輸出的。

我們還需要為隱藏層選擇一個啟用函式。啟用功能將圖層的輸入轉換為其輸出。非線性啟用函式使我們能夠擬合非線性假設。用於啟用功能的常見選擇是tanh,sigmoid函式或ReLU。我們將使用tanh,在許多場景中表現相當好。這些函式的一個很好的屬性是可以使用原始函式值來計算它們的派生值。例如,tanh x的導數是1- (tanh x)^2。這很有用,因為它可以讓我們計算一次tanh x並稍後重新使用它的值來得到導數。

因為我們希望我們的網路輸出概率,輸出層的啟用函式將是softmax,這只是將原始分數轉換為概率的一種方法。如果您熟悉邏輯功能,您可以將softmax視為對多個類的歸納