首頁>技術>

> Photo by Leah Huyghe on Unsplash

使用數字識別資料集學習專案

我建議請仔細閱讀"神經網路的想法"部分。但是,如果您不太清楚,請不要擔心。繼續執行部分。我把它分解成小塊。同樣,您自己執行所有程式碼將使您更清晰。

神經網路如何工作

在簡單的神經網路中,神經元是基本的計算單元。他們採用輸入要素並將其作為輸出進行輸出。基本的神經網路如下所示:

在這裡," layer1"是輸入功能。"第1層"進入另一個節點layer2,最後輸出預測的類別或假設。Layer2是隱藏層。您可以使用多個隱藏層。

您必須根據資料集和準確性要求設計神經網路。

正向傳播

從第1層移動到第3層的過程稱為前向傳播。正向傳播的步驟:

· 初始化每個輸入要素的係數theta。假設有10個輸入功能。說,我們有100個培訓示例。這意味著100行資料。在這種情況下,我們輸入矩陣的大小為100 x10。現在,您確定theta1的大小。行數必須與輸入功能的數目相同。在此示例中,該值為10。列數應為您選擇的隱藏層的大小。

· 將輸入要素X與相應的theta相乘,然後新增一個偏差項。透過啟用函式傳遞結果。

有幾種可用的啟用功能,例如S形,tanh,relu,softmax,swish

我將使用S型啟用函式來演示神經網路。

在這裡," a"代表隱藏的圖層或layer2,而b是偏差。

g(z)是S型啟用:

3.初始化隱藏層的theta2。大小將是隱藏層的長度乘以輸出類的數量。在此示例中,下一層是輸出層,因為我們沒有更多的隱藏層。

4.然後,我們需要遵循與以前相同的過程。將theta和隱藏層相乘,然後透過S型啟用層以獲取假設或預測輸出。

反向傳播

反向傳播是從輸出層移動到layer2的過程。在此過程中,我們計算誤差。

· 首先,從原始輸出y中減去假設。那將是我們的增量。

2.現在,計算theta2的梯度。將delta3乘以theta2。將其乘以" a2"乘以" 1- a2"。在下面的公式中," a"上的上標2表示layer2。請不要誤解它為正方形。

3.根據訓練樣本數m從潛水三角洲計算梯度的非正規化形式。

訓練網路

修改theta。將輸入要素乘以學習率乘以delta2即可得出theta1。請注意theta的尺寸。

重複正向傳播和反向傳播的過程,並不斷更新引數,直到達到最佳成本為止。這是成本函式的公式。提醒一下,代價函式表示預測距原始輸出變數有多遠。

如果您注意到,則此成本函式公式幾乎類似於邏輯迴歸成本函式。

神經網路的實現

我將使用安德魯·伍(Andrew Ng)在Coursera的機器學習課程中的資料集。可以從以下連結隨意下載資料集:https://github.com/rashida048/Machine-Learning-With-Python/blob/master/ex3d1.xlsx

這是逐步實現神經網路的方法。我鼓勵您自己執行每一行程式碼並列印輸出以更好地理解它。

· 首先匯入必要的包和資料集。

import pandas as pdimport numpy as npxls = pd.ExcelFile('ex3d1.xlsx')df = pd.read_excel(xls, 'X', header = None)

這是資料集的前五行。這些是數字的畫素值。請隨時下載資料集並遵循:

在此資料集中,輸入和輸出變數組織在單獨的Excel工作表中。讓我們將輸出變數匯入筆記本中:

y = pd.read_excel(xls, 'y', header=None)

這也是僅資料集的前五行。輸出變數是1到10之間的數字。該專案的目標是使用儲存在" df"中的輸入變數來預測數字。

2.查詢輸入和輸出變數的維度

df.shapey.shape

輸入變數或df的形狀為5000 x 400,輸出變數或y的形狀為5000 x 1。

3.定義神經網路

為簡單起見,我們僅使用25個神經元的一個隱藏層。

hidden_layer = 25

找出輸出類。

y_arr = y[0].unique()#Output:array([10, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int64)

如上所示,有10個輸出類。

4.初始化θ和偏差

我們將隨機初始化layer1和layer2的theta。因為我們有三層,所以會有theta1和theta2。

theta1的形狀:圖層1的大小x圖層2的大小

theta2的形狀:第2層的大小x第3層的大小

從第2步開始," df"的形狀為5000 x400。這意味著有400個輸入要素。因此,layer1的大小為400。由於我們將隱藏層的大小指定為25,因此layer2的大小為25。我們有10個輸出類。因此,layer3的大小為10。

theta1的形狀:400 x 25

theta2的形狀:25 x 10

同樣,將有兩個隨機初始化的偏置項b1和b2。

b1的形狀:layer2的大小(在這種情況下為25)

b2的形狀:layer3的大小(在這種情況下為10)

定義用於隨機初始化theta的函式:

def randInitializeWeights(Lin, Lout):    epi = (6**1/2) / (Lin + Lout)**0.5    w = np.random.rand(Lout, Lin)*(2*epi) -epi    return w

使用此功能並初始化theta

hidden_layer = 25output =10theta1 = randInitializeWeights(len(df.T), hidden_layer)theta2 = randInitializeWeights(hidden_layer, output)theta = [theta1, theta2]

現在,如上所述,初始化偏差項:

b1 = np.random.randn(25,)b2 = np.random.randn(10,)

5.實施正向傳播

使用前向傳播部分中的公式。

為了方便起見,定義了一個將theta和X相乘的函式

def z_calc(X, theta): 	return np.dot(X, theta.T)

我們還將使用啟用功能幾次。還要具有乙狀結腸啟用功能

def sigmoid(z): 	return 1/(1+ np.exp(-z))

現在,我將逐步演示正向傳播。首先,計算z項:

z1 =z_calc(df, theta1) + b1

現在透過啟用函式傳遞此z1以獲得我們的隱藏層

a1 = sigmoid(z1)

a1是隱藏層。a1的形狀為5000 x25。重複相同的過程以計算layer3或輸出層

z2 = z_calc(a1, theta2) + b2a2 = sigmoid(z2)

a2的形狀為5000 x10。10列表示10類。a2是我們的layer3或最終輸出或假設。如果在此示例中存在更多隱藏層,則將重複執行同一過程以從一層轉移到另一層。使用輸入要素計算輸出層的過程稱為前向傳播。將它們放到一個函式中,因此我們可以對任意數量的層執行正向傳播:

l = 3  #the umber of layersb = [b1, b2]def hypothesis(df, theta):    a = []    z = []    for i in range (0, l-1):        z1 = z_calc(df, theta[i]) + b[i]        out = sigmoid(z1)        a.append(out)        z.append(z1)        df = out    return out, a, z

6.實施反向傳播

這是向後計算梯度並更新theta的過程。在此之前,我們需要修改" y"。" y"有10個班級。但是我們需要將每個類劃分到其列中。例如,第一列用於類10。對於其餘類,我們將10替換為1,將其替換為0。這樣,我們將為每個類建立一個單獨的列。

y1 = np.zeros([len(df), len(y_arr)])y1 = pd.DataFrame(y1)for i in range(0, len(y_arr)):    for j in range(0, len(y1)):        if y[0][j] == y_arr[i]:            y1.iloc[j, i] = 1        else:             y1.iloc[j, i] = 0y1.head()

現在,我首先逐步演示正向傳播,然後將其全部放入一個函式中,對於反向傳播,我將執行相同的操作。使用上面反向傳播部分中的梯度公式,首先計算delta3。我們將使用前向傳播實現中的z1,z2,a1和a2。

del3 = y1-a2

現在,使用以下公式計算delta2:

這是delta2:

del2 = np.dot(del3, theta2) * a1*(1 - a1)

在這裡,我們需要學習一個新概念。那是一個S形梯度。S型梯度的公式為:

如果您注意到,這與增量公式中的a(1 — a)完全相同。因為a是sigmoid(z)。因為這是一個約定,所以當我將它們全部組合在一起以編寫函式時,我將用此S形梯度代替delta2公式中的a(1-a)項。他們是完全一樣的。我只是想演示兩個。讓我們為S型梯度編寫一個函式:

def sigmoid_grad(z): 	return sigmoid(z)*(1 - sigmoid(z))

最後,是時候使用以下公式更新theta了:

我們需要選擇學習率。我選擇了0.003。我鼓勵您嘗試其他學習率,以瞭解其效果:

theta1 = np.dot(del2.T, pd.DataFrame(a1)) * 0.003theta2 = np.dot(del3.T, pd.DataFrame(a2)) * 0.003

這就是theta需要更新的方式。此過程稱為反向傳播,因為它向後移動。在編寫用於反向傳播的函式之前,我們需要定義成本函式。因為我也將成本的計算包括在反向傳播方法中。儘管可以在正向傳播中新增它,也可以在訓練網路時將其分開。這是成本函式的方法

def cost_function(y, y_calc, l): 	return (np.sum(np.sum(-np.log(y_calc)*y - np.log(1-y_calc)*(1-y))))/m

這裡m是訓練示例的數量。放在一起:

y1 = np.zeros([len(df), len(y_arr)])y1 = pd.DataFrame(y1)for i in range(0, len(y_arr)):    for j in range(0, len(y1)):        if y[0][j] == y_arr[i]:            y1.iloc[j, i] = 1        else:             y1.iloc[j, i] = 0y1.head()

7.訓練網路

我將訓練網路20個紀元。我將在此程式碼片段中再次初始化theta。因為我已經使用了theta並對其進行了更新。因此,如果我不再次對其進行初始化,那麼我將最終從更新的theta開始。但我想重新開始。

theta1 = randInitializeWeights(len(df.T), hidden_layer)theta2 = randInitializeWeights(hidden_layer, output)theta = [theta1, theta2]cost_list = []for i in range(20):    theta, cost= backpropagation(df, theta, y1, 0.003)    cost_list.append(cost)cost_list

我使用了0.003的學習率,並將其運行了20個時期。但是請檢視下面提供的GitHub連結。我嘗試了不同的學習速度和不同的時期,終於到達了這裡。

我們獲得了在每個時期計算出的成本清單以及最終更新的theta。使用此最終theta預測輸出。

8.預測輸出並計算精度

只需使用假設函式來傳遞此更新的theta以預測輸出:

out, a, z = hypothesis(df, theta)

現在計算精度,

accuracy= 0for i in range(0, len(out)):    for j in range(0, len(out[i])):        if out[i][j] >= 0.5 and y1.iloc[i, j] == 1:            accuracy += 1accuracy/len(df)

精度為100%。完美吧?但是,我們並非始終都能獲得100%的準確性。有時,獲得70%的準確性非常好,具體取決於資料集。

恭喜!您剛剛開發了完整的神經網路!

結論

對於更簡單的分類問題,邏輯迴歸仍然非常有效!但是對於更復雜的問題,神經網路可以提供更好的結果。如您所見,透過向前和向後傳播,它可以更好地學習訓練資料。在自然語言處理和影象分類中,神經網路在AI行業中的表現非常出色。

這是Github的完整工作程式碼連結:https://github.com/rashida048/Machine-Learning-With-Python/blob/master/NeuralNetworkFinal.ipynb

13
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 資料目錄已死;資料發現永生