当前层输出为Ij,f为非线性转化函数,又称为激活函数,定义如下:
即每一层的输出为:
这样就可以通过输入值正向得到每一层的输出值。
2、根据误差反向传送 对于输出层:其中Tk是真实值,Ok是预测值
对于隐藏层:
权重更新:其中l为学习率
偏向更新:
3、终止条件
偏重的更新低于某个阈值;
预测的错误率低于某个阈值;
达到预设一定的循环次数;
4、非线性转化函数
上面提到的非线性转化函数f,一般情况下可以用两种函数:
(1)tanh(x)函数:
tanh(x)=sinh(x)/cosh(x)
sinh(x)=(exp(x)-exp(-x))/2
cosh(x)=(exp(x)+exp(-x))/2
(2)逻辑函数,本文上面用的就是逻辑函数
五、BP神经网络的python实现
需要先导入numpy模块
import numpy as np
定义非线性转化函数,由于还需要用到给函数的导数形式,因此一起定义
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))
设计BP神经网络的形式(几层,每层多少单元个数),用到了面向对象,主要是选择哪种非线性函数,以及初始化权重。layers是一个list,里面包含每一层的单元个数。
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)
实现算法
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)
实现预测
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
我们给出一组数进行预测,我们上面的程序文件保存名称为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))
结果如下:
([0, 0], array([ 0.99738862]))
([0, 1], array([ 0.00091329]))
([1, 0], array([ 0.00086846]))
([1, 1], array([ 0.99751259]))
评论
查看更多