全文共5234字,預計學習時長10分鐘數據庫
圖片來源:unsplash.com/@alinnnaaaabash
本文將介紹如何創建進階神經網絡。微信
輸入數據網絡
本教程惟一使用的數據庫爲NumPy。app
import numpy as np複製代碼
激活函數dom
在隱藏層中會使用tanh激活函數,而在輸出層中則會使用sigmod函數。在兩種函數的圖中都很容易找到信息。下面直接執行函數。函數
以上爲Sigmoid函數。如下爲該函數代碼:學習
def sigmoid(x): return (1 / (1 + np.exp(-x)))複製代碼
設定參數ui
什麼是參數和超參數?參數指權值和誤差。超參數會影響參數,並設置在學習過程開始以前。準確無誤設置超參數並不容易,須要不斷調整數值。超參數包括學習率、迭代次數、校準率等。人工智能
想知道如何設置矩陣規模嗎?看看下面的答案吧!
這是什麼意思呢?例如:
(第0層,即L=0),輸入層神經元數量=3
(第1層,即L=1),隱藏層神經元數量=5
(第2層,即L=2),輸出層神經元數量=1
但願以上代碼都能奏效!如今設置參數。
def setParameters(X, Y, hidden_size):
np.random.seed(3)
input_size = X.shape[0] # number of neurons in input layer
output_size = Y.shape[0] # number of neurons in output layer.
W1 = np.random.randn(hidden_size, input_size)*np.sqrt(2/input_size)
b1 = np.zeros((hidden_size, 1))
W2 = np.random.randn(output_size, hidden_size)*np.sqrt(2/hidden_size)
b2 = np.zeros((output_size, 1))
return {'W1': W1, 'W2': W2, 'b1': b1, 'b2': b2}複製代碼
定義變量W一、b一、W2和b2。變量初始值設爲0也無妨。但初始化權值時要格外謹慎。初始值毫不能爲0。爲何?若權值初始值爲0,函數Z = Wx + b的值恆爲0。多層神經網絡中,每層的神經元共同做用。因此應該如何設置初始權值呢?本文使用he初始化。
公式
# Python implementation
np.random.randn(output_size,
hidden_size)*np.sqrt(2/hidden_size)複製代碼
除he初始化之外,也可使用如下方法:
np.random.randn(output_size, hidden_size)*0.01複製代碼
建議:在參數初始化中,請勿將權值設爲0或大數值。
前向傳播
前向傳播
上圖清晰解釋了前向傳播。在Python中的應用爲:
def forwardPropagation(X, params):
Z1 = np.dot(params['W1'], X)+params['b1']
A1 = np.tanh(Z1)
Z2 = np.dot(params['W2'], A1)+params['b2']
y = sigmoid(Z2)
return y, {'Z1': Z1, 'Z2': Z2, 'A1': A1, 'y': y}複製代碼
爲何要儲存 {‘Z1’: Z1, ‘Z2’: Z2, ‘A1’: A1, ‘y’: y}?由於在反向傳播中會用到這些數值。
成本函數
剛纔介紹了前向傳播,獲得預測值(y)。這個值由成本函數計算得出。下圖能夠說明:
更新參數
更新參數後找到可能最小化成本的最佳參數,本文不會對此再作探討。但在上一段提到,若是數值在拋物線右側,導數(斜率)爲正,數值遞減,左移接近最小成本值;若數值在拋物線左側,斜率爲負,所以參數會增至預期的最小成本值。
如下爲使用的成本函數:
成本函數
此成本函數的Python代碼:
def cost(predict, actual):
m = actual.shape[1]
cost__ = -np.sum(np.multiply(np.log(predict),
actual) + np.multiply((1 - actual), np.log(1 - predict)))/m
return np.squeeze(cost__)複製代碼
反向傳播
肯定成本後,下面返回去求權值和誤差的導數。
def backPropagation(X, Y, params, cache):
m = X.shape[1]
dy = cache['y'] - Y dW2 = (1 / m) * np.dot(dy, np.transpose(cache['A1']))
db2 = (1 / m) * np.sum(dy, axis=1, keepdims=True)
dZ1 = np.dot(np.transpose(params['W2']), dy) * (1-np.power(cache['A1'], 2))
dW1 = (1 / m) * np.dot(dZ1, np.transpose(X))
db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)
return {"dW1": dW1, "db1": db1, "dW2": dW2, "db2": db2}複製代碼
def backPropagation(X, Y, params,cache)中的parama和cache是什麼?在前向傳播中儲存數值,就是爲了用於反向傳播。Params是參數(權值和誤差)。
更新參數
獲得參數後,代入如下公式:
公式中alpha (α)是超參數的學習率。在學習開始前須要設置數值。在學習率右側的數值爲導數。alpha和導數已知,能夠更新參數。
def updateParameters(gradients, params, learning_rate = 1.2):
W1 = params['W1'] - learning_rate * gradients['dW1']
b1 = params['b1'] - learning_rate * gradients['db1']
W2 = params['W2'] - learning_rate * gradients['dW2']
b2 = params['b2'] - learning_rate * gradients['db2']
return {'W1': W1, 'W2': W2, 'b1': b1, 'b2': b2}複製代碼
循環是關鍵
須要屢次迭代才能找到迴歸最低成本的參數。如今開始循環!
def fit(X, Y, learning_rate, hidden_size,
number_of_iterations = 5000):
params = setParameters(X, Y, hidden_size)
cost_ = [] for j in range(number_of_iterations):
y, cache = forwardPropagation(X, params)
costit = cost(y, Y)
gradients = backPropagation(X, Y, params, cache)
params = updateParameters(gradients, params, learning_rate)
cost_.append(costit) return params, cost_複製代碼
Hidden_size指隱藏層中神經元數量。因爲在學習開始前設定,它相似於超參數。return params, cost_指找到的最佳參數。cost_爲每次迭代預估的成本。
運行代碼!
使用sklearn建立數據集。
import sklearn.datasets
X, Y =
sklearn.datasets.make_moons(n_samples=500,
noise=.2)X, Y = X.T, Y.reshape(1, Y.shape[0])複製代碼
X爲輸入值,Y爲實際輸出值。
params, cost_ = fit(X, Y, 0.3, 5, 5000)複製代碼
本文中學習率設置爲0.3,隱藏層神經元數量爲5,迭代次數爲5000.固然也可設置不一樣數值嘗試。
下面畫圖以說明每次迭代中成本函數的變化。
import matplotlib.pyplot as pltplt.plot(cost_)複製代碼
結果正確!
first_cost = 0.7383781203733911last_cost = 0.06791109327547613複製代碼
完整代碼:
import numpy as np
def sigmoid(x):
return (1 / (1 + np.exp(-x)))def setParameters(X, Y, hidden_size):
np.random.seed(3)
input_size = X.shape[0] # number of neurons in
input layer
output_size = Y.shape[0] # number of neurons in
output layer.
W1 = np.random.randn(hidden_size, input_size)*np.sqrt(2/input_size)
b1 = np.zeros((hidden_size, 1))
W2 = np.random.randn(output_size, hidden_size)*np.sqrt(2/hidden_size)
b2 = np.zeros((output_size, 1))
return {'W1': W1, 'W2': W2, 'b1': b1, 'b2': b2}def forwardPropagation(X, params):
Z1 = np.dot(params['W1'], X)+params['b1']
A1 = np.tanh(Z1)
Z2 = np.dot(params['W2'], A1)+params['b2'] y = sigmoid(Z2)
return y, {'Z1': Z1, 'Z2': Z2, 'A1': A1, 'y': y}
def cost(predict, actual): m = actual.shape[1]
cost__ = -np.sum(np.multiply(np.log(predict),
actual) + np.multiply((1 - actual),
np.log(1 - predict)))/m
return np.squeeze(cost__)
def backPropagation(X, Y, params, cache): m = X.shape[1]
dy = cache['y'] - Y
dW2 = (1 / m) * np.dot(dy, np.transpose(cache['A1']))
db2 = (1 / m) * np.sum(dy, axis=1, keepdims=True)
dZ1 = np.dot(np.transpose(params['W2']), dy) * (1-np.power(cache['A1'], 2))
dW1 = (1 / m) * np.dot(dZ1, np.transpose(X))
db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)
return {"dW1": dW1, "db1": db1, "dW2": dW2, "db2": db2}def
updateParameters(gradients, params, learning_rate = 1.2):
W1 = params['W1'] - learning_rate * gradients['dW1']
b1 = params['b1'] - learning_rate * gradients['db1']
W2 = params['W2'] - learning_rate * gradients['dW2']
b2 = params['b2'] - learning_rate * gradients['db2']
return {'W1': W1, 'W2': W2, 'b1': b1, 'b2': b2}
def fit(X, Y, learning_rate, hidden_size, number_of_iterations = 5000):
params = setParameters(X, Y, hidden_size)
cost_ = [] for j in range(number_of_iterations):
y, cache = forwardPropagation(X, params)
costit = cost(y, Y)
gradients = backPropagation(X, Y, params, cache)
params = updateParameters(gradients, params, learning_rate)
cost_.append(costit)
return params,
cost_# Testing the codeimport sklearn.datasetsX,
Y = sklearn.datasets.make_moons(n_samples=500, noise=.2)X,
Y = X.T, Y.reshape(1, Y.shape[0])params, cost_ = fit(X, Y, 0.3, 5, 5000)
import matplotlib.pyplot as pltplt.plot(cost_)複製代碼
留言 點贊 關注
咱們一塊兒分享AI學習與發展的乾貨
歡迎關注全平臺AI垂類自媒體 「讀芯術」
(添加小編微信:dxsxbb,加入讀者圈,一塊兒討論最新鮮的人工智能科技哦~)