吴恩达《机器学习》学习笔记十一——神经网络代码
吳恩達《機器學習》學習筆記十一——神經網絡代碼
- 數據準備
- 神經網絡結構與代價函數·
- 初始化設置
- 反向傳播算法
- 訓練網絡與驗證
課程鏈接:https://www.bilibili.com/video/BV164411b7dx?from=search&seid=5329376196520099118
數據集鏈接:https://pan.baidu.com/s/1ZkB_RW9ehEV_w6ryZT64Ag
提取碼:8utg
這次筆記,我們將再次處理手寫數字數據集,第八次筆記是使用的多分類邏輯回歸算法,這次使用反向傳播的前饋神經網絡。 我們將通過反向傳播算法實現神經網絡成本函數和梯度計算的非正則化和正則化版本。 我們還將實現隨機權重初始化和使用網絡進行預測的方法。
由于使用的數據集和上次代碼練習是相同的,我們將重新使用代碼來加載數據。
數據準備
import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.io import loadmat data = loadmat('ex4data1.mat') data
由于我們以后需要這些(并將經常使用它們),我們先來創建一些有用的變量。
我們也需要對我們的y標簽進行一次one-hot 編碼。 one-hot 編碼將類標簽n(k類)轉換為長度為k的向量,其中索引n為“hot”(1),而其余為0。 Scikitlearn有一個內置的實用程序,我們可以使用這個。
one-hot編碼后的y會變成如下圖這種形式:
對應的類別位置設置為1,其余位置全部是0。
看一下變換前后的標簽尺寸:
y[0], y_onehot[0,:]神經網絡結構與代價函數·
我們要為此練習構建的神經網絡具有與我們的實例數據**(400 +偏置單元)大小匹配的輸入層,25個單位的隱藏層(帶有偏置單元的26個),以及一個輸出層, 10個單位對應我們的一個one-hot編碼類標簽**。 其網絡結構如下圖所示,其中輸入層有400+1個神經元,隱藏層有25+1個神經元,輸出層有10個神經元:
我們需要實現的第一件是評估一組給定的網絡參數的損失的代價函數。神經網絡的代價函數若不帶正則項就是如下所示的表達式:
帶正則項的話表達式就會變成:
先定義一下sigmoid函數:
如果要計算代價函數則需要前向傳播來計算預測結果h(x),所以要先定義前向傳播的函數:
def forward_propagate(X, theta1, theta2):# INPUT:參數值theta,數據X# OUTPUT:當前參數值下前項傳播結果# TODO:根據參數和輸入的數據計算前項傳播結果# STEP1:獲取樣本個數m = X.shape[0]# STEP2:實現神經網絡正向傳播 a1 =np.insert(X, 0, values=np.ones(m), axis=1) #給X矩陣插入一行1元素z2 =a1 * theta1.Ta2 =np.insert(sigmoid(z2), 0, values=np.ones(m), axis=1) #注意插入1元素z3 = a2 * theta2.Th = sigmoid(z3)return a1, z2, a2, z3, h def cost(params, input_size, hidden_size, num_labels, X, y, lamda):# INPUT:神經網絡參數,輸入層維度,隱藏層維度,訓練數據及標簽,正則化參數# OUTPUT:當前參數值下的代價函數# TODO:根據上面的公式計算代價函數# STEP1:獲取樣本個數m = X.shape[0]# STEP2:將矩陣X,y轉換為numpy型矩陣X =np.matrix(X)y =np.matrix(y)# STEP3:從params中獲取神經網絡參數,并按照輸入層維度和隱藏層維度重新定義參數的維度theta1 = np.matrix(np.reshape(params[:hidden_size * (input_size + 1)], (hidden_size, (input_size + 1))))theta2 = np.matrix(np.reshape(params[hidden_size * (input_size + 1):], (num_labels, (hidden_size + 1))))# STEP4:調用前面寫好的前項傳播函數a1, z2, a2, z3, h = forward_propagate(X, theta1, theta2)# STEP5:初始化代價函數J = 0# STEP6:根據公式計算代價函數for i in range(m): #遍歷每個樣本first_term =np.multiply(-y[i,:], np.log(h[i,:]))second_term = np.multiply((1 - y[i,:]), np.log(1 - h[i,:]))J += np.sum(first_term - second_term)J = J / m# STEP7:計算代價函數的正則化部分J += (float(lamda) / (2 * m)) * (np.sum(np.power(theta1[:,1:], 2)) + np.sum(np.power(theta2[:,1:], 2)))return J初始化設置
將網絡的層數、神經元數目、正則化系數、參數等一些變量進行初始化設置。
# 初始化設置 input_size = 400 hidden_size = 25 num_labels = 10 lamda = 1# 隨機初始化完整網絡參數大小的參數數組 params = (np.random.random(size=hidden_size * (input_size + 1) + num_labels * (hidden_size + 1)) - 0.5) * 0.25m = X.shape[0] X = np.matrix(X) y = np.matrix(y)# 將參數數組解開為每個層的參數矩陣 theta1 = np.matrix(np.reshape(params[:hidden_size * (input_size + 1)], (hidden_size, (input_size + 1)))) theta2 = np.matrix(np.reshape(params[hidden_size * (input_size + 1):], (num_labels, (hidden_size + 1))))theta1.shape, theta2.shape
這邊顯示的是theta1和theta2的維度,要結合與輸入X的維度理解。
觀察一下這些中間變量的維度。
代價函數在計算假設矩陣h之后,應用代價函數來計算y和h之間的總誤差。
cost(params, input_size, hidden_size, num_labels, X, y_onehot, lamda)
這是初始時刻用隨機設置的參數計算得到的初始代價函數值。
反向傳播算法
接下來是反向傳播算法。 反向傳播參數更新計算將減少訓練數據上的網絡誤差。 我們需要的第一件事是計算我們之前創建的Sigmoid函數的梯度的函數。
def sigmoid_gradient(z):return np.multiply(sigmoid(z), (1 - sigmoid(z)))它所作的工作如下面這幅圖所示,后面的計算中會經常使用到這個函數,所以提前寫出來:
現在我們準備好實施反向傳播來計算梯度。 由于反向傳播所需的計算是代價函數中所需的計算過程,我們實際上將擴展代價函數以執行反向傳播并返回代價和梯度。梯度的計算過程如下所示:
反向傳播計算最難的部分(除了理解為什么我們正在做所有這些計算)是獲得正確矩陣維度。 順便說一下,你容易混淆了A * B與np.multiply(A,B)使用。 基本上前者是矩陣乘法,后者是元素乘法(除非A或B是標量值,在這種情況下沒關系)。 無論如何,讓我們測試一下,以確保函數返回我們期望的。
J, grad = backprop(params, input_size, hidden_size, num_labels, X, y_onehot, lamda) J, grad.shape
參數的數量應該為40125+2610=10285個,驗證無誤。
訓練網絡與驗證
我們終于準備好訓練我們的網絡,并用它進行預測。 這與以往的具有多類邏輯回歸的練習大致相似。
from scipy.optimize import minimize# minimize the objective function fmin = minimize(fun=backprop, x0=params, args=(input_size, hidden_size, num_labels, X, y_onehot, lamda), method='TNC', jac=True, options={'maxiter': 250}) fmin
用訓練好的參數來進行預測:
最后再計算一下準確率:
correct = [1 if a == b else 0 for (a, b) in zip(y_pred, y)] accuracy = (sum(map(int, correct)) / float(len(correct))) print ('accuracy = {0}%'.format(accuracy * 100))總結
以上是生活随笔為你收集整理的吴恩达《机器学习》学习笔记十一——神经网络代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BoW(词袋Bag of words)
- 下一篇: PyTorch框架学习一——PyTorc