當前層輸出為Ij,f為非線性轉(zhuǎn)化函數(shù),又稱為激活函數(shù),定義如下:
即每一層的輸出為:
這樣就可以通過輸入值正向得到每一層的輸出值。
2、根據(jù)誤差反向傳送 對于輸出層:其中Tk是真實值,Ok是預(yù)測值
對于隱藏層:
權(quán)重更新:其中l(wèi)為學(xué)習(xí)率
偏向更新:
3、終止條件
偏重的更新低于某個閾值;
預(yù)測的錯誤率低于某個閾值;
達到預(yù)設(shè)一定的循環(huán)次數(shù);
4、非線性轉(zhuǎn)化函數(shù)
上面提到的非線性轉(zhuǎn)化函數(shù)f,一般情況下可以用兩種函數(shù):
(1)tanh(x)函數(shù):
tanh(x)=sinh(x)/cosh(x)
sinh(x)=(exp(x)-exp(-x))/2
cosh(x)=(exp(x)+exp(-x))/2
(2)邏輯函數(shù),本文上面用的就是邏輯函數(shù)
五、BP神經(jīng)網(wǎng)絡(luò)的python實現(xiàn)
需要先導(dǎo)入numpy模塊
import numpy as np
定義非線性轉(zhuǎn)化函數(shù),由于還需要用到給函數(shù)的導(dǎo)數(shù)形式,因此一起定義
def tanh(x):
return np.tanh(x)
def tanh_deriv(x):
return 1.0 - np.tanh(x)*np.tanh(x)
def logistic(x):
return 1/(1 + np.exp(-x))
def logistic_derivative(x):
return logistic(x)*(1-logistic(x))
設(shè)計BP神經(jīng)網(wǎng)絡(luò)的形式(幾層,每層多少單元個數(shù)),用到了面向?qū)ο?,主要是選擇哪種非線性函數(shù),以及初始化權(quán)重。layers是一個list,里面包含每一層的單元個數(shù)。
class NeuralNetwork:
def __init__(self, layers, activation='tanh'):
"""
:param layers: A list containing the number of units in each layer.
Should be at least two values
:param activation: The activation function to be used. Can be
"logistic" or "tanh"
"""
if activation == 'logistic':
self.activation = logistic
self.activation_deriv = logistic_derivative
elif activation == 'tanh':
self.activation = tanh
self.activation_deriv = tanh_deriv
self.weights = []
for i in range(1, len(layers) - 1):
self.weights.append((2*np.random.random((layers[i - 1] + 1, layers[i] + 1))-1)*0.25)
self.weights.append((2*np.random.random((layers[i] + 1, layers[i + 1]))-1)*0.25)
實現(xiàn)算法
def fit(self, X, y, learning_rate=0.2, epochs=10000):
X = np.atleast_2d(X)
temp = np.ones([X.shape[0], X.shape[1]+1])
temp[:, 0:-1] = X
X = temp
y = np.array(y)
for k in range(epochs):
i = np.random.randint(X.shape[0])
a = [X[i]]
for l in range(len(self.weights)):
a.append(self.activation(np.dot(a[l], self.weights[l])))
error = y[i] - a[-1]
deltas = [error * self.activation_deriv(a[-1])]
for l in range(len(a) - 2, 0, -1):
deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))
deltas.reverse()
for i in range(len(self.weights)):
layer = np.atleast_2d(a[i])
delta = np.atleast_2d(deltas[i])
self.weights[i] += learning_rate * layer.T.dot(delta)
實現(xiàn)預(yù)測
def predict(self, x):
x = np.array(x)
temp = np.ones(x.shape[0]+1)
temp[0:-1] = x
a = temp
for l in range(0, len(self.weights)):
a = self.activation(np.dot(a, self.weights[l]))
return a
我們給出一組數(shù)進行預(yù)測,我們上面的程序文件保存名稱為BP
from BP import NeuralNetwork
import numpy as np
nn = NeuralNetwork([2,2,1], 'tanh')
x = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([1,0,0,1])
nn.fit(x,y,0.1,10000)
for i in [[0,0], [0,1], [1,0], [1,1]]:
print(i, nn.predict(i))
結(jié)果如下:
([0, 0], array([ 0.99738862]))
([0, 1], array([ 0.00091329]))
([1, 0], array([ 0.00086846]))
([1, 1], array([ 0.99751259]))
評論
查看更多