python实现BP神经网络(详细参数)
来源:互联网 发布:邮件系统服务软件排名 编辑:程序博客网 时间:2024/05/16 19:29
最近几天在研究BP神经网络网时,发现网上对它的介绍很多,但是在编程实现的时候,总感觉很多博客介绍BP的公式的时候没有介绍清楚,参考了不少博客还是感觉模棱两可,最后参考了周志华老师的《机器学习》这本书,再结合之前在网上看到的,自己用python实现了一个标准的BP网络。在这里记录一下学习过程。
1,BP神经网络
在参考其他博客的时候,感觉都没有把BP网络的图以及变量表示清楚。导致我自己在看博客代码实现的时候,变量全部都搞混了。后来参考了周志华老师的《机器学习》感觉上面把变量定义的很清楚,在此参考。
1.1 正向传播
BP的网络如下(这里直接拍照了 QAQ):
图中定义了一个3层神经网络。输入层,隐藏层,输出层个数分别为
公式符号全部就介绍完了。是不是搞晕了。在这里总结一下:
s型函数:
最初输入:
输入层和隐藏层权值:
隐藏层输入:
隐藏层阀值:
隐藏层输出:
隐藏层与输出层权值:
输出层输入:
输出层阀值:
输出层输出值:
当有一个输入
1.2 反向传播
在正向过程计算完成后,然后就要通过误差的反向传播(error backpropagation)修改权值和阀值了。误差使用每次正向传播的输出值与真实值的平方差得到
这里以隐藏层与输出层的权值阀值为例,先求关于权值的偏导
在此总结一下反向传播的各个参数:
隐藏层与输出层之间权值的梯度:
输出层阀值的梯度:
输入层与隐藏层之间的权值梯度:
隐藏层的阀值梯度:
至此BP的公式就介绍完了。
2,代码实现
代码实现的过程中有些技巧,在参考的https://www.cnblogs.com/Finley/p/5946000.html博客中,博主没有考虑输出层的阀值,只是考虑了输入层的阀值。而在http://blog.csdn.net/acdreamers/article/details/44657439这篇博客中,博主使用的是c++写的。没有将权值用矩阵表示。完全是利用for循环写的QAQ。
所以我在实现自己的神经网络时,考虑了隐藏层阀值以及输出层阀值,并且利用权值矩阵将输入层与隐藏层以及隐藏层和输出层的权值和阀值用两个矩阵input_weights以及output_weights表示。
代码如下:
#! /usr/bin/python# -*- encoding:utf8 -*-import numpy as npdef rand(a, b): return (b - a) * np.random.random() + adef sigmoid(x): return 1.0 / (1.0 + np.exp(-x))def sigmoid_derivative(x): return x * (1 - x)class BP: def __init__(self, layer, iter, max_error): self.input_n = layer[0] # 输入层的节点个数 d self.hidden_n = layer[1] # 隐藏层的节点个数 q self.output_n = layer[2] # 输出层的节点个数 l self.gj = [] self.eh = [] self.input_weights = [] # 输入层与隐藏层的权值矩阵 self.output_weights = [] # 隐藏层与输出层的权值矩阵 self.iter = iter # 最大迭代次数 self.max_error = max_error # 停止的误差范围 # for i in range(self.input_n + 1): # tmp = [] # for j in range(self.hidden_n): # tmp.append(rand(-0.2, 0.2)) # self.input_weights.append(tmp) # # for i in range(self.hidden_n + 1): # tmp = [] # for j in range(self.output_n): # tmp.append(rand(-0.2, 0.2)) # self.output_weights.append(tmp) # self.input_weights = np.array(self.input_weights) # self.output_weights = np.array(self.output_weights) # 初始化一个(d+1) * q的矩阵,多加的1是将隐藏层的阀值加入到矩阵运算中 self.input_weights = np.random.random((self.input_n + 1, self.hidden_n)) # 初始话一个(q+1) * l的矩阵,多加的1是将输出层的阀值加入到矩阵中简化计算 self.output_weights = np.random.random((self.hidden_n + 1, self.output_n)) self.gj = np.zeros(layer[2]) self.eh = np.zeros(layer[1]) # 正向传播与反向传播 def forword_backword(self, xj, y, learning_rate=0.1): xj = np.array(xj) y = np.array(y) input = np.ones((1, xj.shape[0] + 1)) input[:, :-1] = xj x = input # ah = np.dot(x, self.input_weights) ah = x.dot(self.input_weights) bh = sigmoid(ah) input = np.ones((1, self.hidden_n + 1)) input[:, :-1] = bh bh = input bj = np.dot(bh, self.output_weights) yj = sigmoid(bj) error = yj - y self.gj = error * sigmoid_derivative(yj) # wg = np.dot(self.output_weights, self.gj) wg = np.dot(self.gj, self.output_weights.T) wg1 = 0.0 for i in range(len(wg[0]) - 1): wg1 += wg[0][i] self.eh = bh * (1 - bh) * wg1 self.eh = self.eh[:, :-1] # 更新输出层权值w,因为权值矩阵的最后一行表示的是阀值多以循环只到倒数第二行 for i in range(self.output_weights.shape[0] - 1): for j in range(self.output_weights.shape[1]): self.output_weights[i][j] -= learning_rate * self.gj[0][j] * bh[0][i] # 更新输出层阀值b,权值矩阵的最后一行表示的是阀值 for j in range(self.output_weights.shape[1]): self.output_weights[-1][j] -= learning_rate * self.gj[0][j] # 更新输入层权值w for i in range(self.input_weights.shape[0] - 1): for j in range(self.input_weights.shape[1]): self.input_weights[i][j] -= learning_rate * self.eh[0][j] * xj[i] # 更新输入层阀值b for j in range(self.input_weights.shape[1]): self.input_weights[-1][j] -= learning_rate * self.eh[0][j] return error def fit(self, X, y): for i in range(self.iter): error = 0.0 for j in range(len(X)): error += self.forword_backword(X[j], y[j]) error = error.sum() if abs(error) <= self.max_error: break def predict(self, x_test): x_test = np.array(x_test) tmp = np.ones((x_test.shape[0], self.input_n + 1)) tmp[:, :-1] = x_test x_test = tmp an = np.dot(x_test, self.input_weights) bh = sigmoid(an) # 多加的1用来与阀值相乘 tmp = np.ones((bh.shape[0], bh.shape[1] + 1)) tmp[:, : -1] = bh bh = tmp bj = np.dot(bh, self.output_weights) yj = sigmoid(bj) print yj return yjif __name__ == '__main__': # 指定神经网络输入层,隐藏层,输出层的元素个数 layer = [2, 4, 1] X = [ [1, 1], [2, 2], [1, 2], [1, -1], [2, 0], [2, -1] ] y = [[0], [0], [0], [1], [1], [1]] # x_test = [[2, 3], # [2, 2]] # 设置最大的迭代次数,以及最大误差值 bp = BP(layer, 10000, 0.0001) bp.fit(X, y) bp.predict(X)
- python实现BP神经网络(详细参数)
- 神经网络之BP神经网络(Python实现)
- BP神经网络Python实现
- BP神经网络python实现
- BP神经网络的Python实现
- 用python实现BP神经网络
- BP神经网络python简单实现
- BP神经网络python简单实现
- BP神经网络的Python实现
- bp神经网络的python实现
- Python实现三层BP神经网络
- BP神经网络(python代码)
- BP神经网络PYthon实现(带有”增加充量项“)
- BP神经网络PYthon实现(带有”增加充量项“)
- BP神经网络PYthon实现(带有”增加充量项“)
- 用Python实现BP神经网络(附代码)
- Python使用numpy实现BP神经网络
- BP神经网络的Python简单实现
- 编写一个应用程序,用户分别从两个文本框输入学术的姓名和分数,程序按成绩排序将这些学生的姓名和分数显示在一个文本区中。 程序运行效果如图:
- Linux进程控制编程知识框架梳理
- 关于CSS中left:50%; top:50%; margin-left: -150px; margin-top: -75px;
- SSM框架之table与json之间的关系(一)
- rsync工具介绍,rsync常用选项,rsync通过ssh同步
- python实现BP神经网络(详细参数)
- 23种设计模式之-----门面模式(Facade Pattern)
- 中国移动业务支撑系统简介(BOSS、BASS、BOMC、4A及VGOP)
- obj.style.width问题
- 正则表达式总结(持续更新。。)
- 欢迎使用CSDN-markdown编辑器
- 进程控制块(PCB) —— task_struct
- leetcode 35. Search Insert Position搜索插入位置(二分查找)
- git简易教程