这是一个非常漂亮的三层反向传播神经网络的python实现,下一步我准备试着将其修改为多层BP神经网络。

下面是运行演示函数的截图,你会发现预测的结果很惊人!

提示:运行演示函数的时候,可以尝试改变隐藏层的节点数,看节点数增加了,预测的精度会否提升

 import math
import random
import string random.seed(0) # 生成区间[a, b)内的随机数
def rand(a, b):
return (b-a)*random.random() + a # 生成大小 I*J 的矩阵,默认零矩阵 (当然,亦可用 NumPy 提速)
def makeMatrix(I, J, fill=0.0):
m = []
for i in range(I):
m.append([fill]*J)
return m # 函数 sigmoid,这里采用 tanh,因为看起来要比标准的 1/(1+e^-x) 漂亮些
def sigmoid(x):
return math.tanh(x) # 函数 sigmoid 的派生函数, 为了得到输出 (即:y)
def dsigmoid(y):
return 1.0 - y**2 class NN:
''' 三层反向传播神经网络 '''
def __init__(self, ni, nh, no):
# 输入层、隐藏层、输出层的节点(数)
self.ni = ni + 1 # 增加一个偏差节点
self.nh = nh
self.no = no # 激活神经网络的所有节点(向量)
self.ai = [1.0]*self.ni
self.ah = [1.0]*self.nh
self.ao = [1.0]*self.no # 建立权重(矩阵)
self.wi = makeMatrix(self.ni, self.nh)
self.wo = makeMatrix(self.nh, self.no)
# 设为随机值
for i in range(self.ni):
for j in range(self.nh):
self.wi[i][j] = rand(-0.2, 0.2)
for j in range(self.nh):
for k in range(self.no):
self.wo[j][k] = rand(-2.0, 2.0) # 最后建立动量因子(矩阵)
self.ci = makeMatrix(self.ni, self.nh)
self.co = makeMatrix(self.nh, self.no) def update(self, inputs):
if len(inputs) != self.ni-1:
raise ValueError('与输入层节点数不符!') # 激活输入层
for i in range(self.ni-1):
#self.ai[i] = sigmoid(inputs[i])
self.ai[i] = inputs[i] # 激活隐藏层
for j in range(self.nh):
sum = 0.0
for i in range(self.ni):
sum = sum + self.ai[i] * self.wi[i][j]
self.ah[j] = sigmoid(sum) # 激活输出层
for k in range(self.no):
sum = 0.0
for j in range(self.nh):
sum = sum + self.ah[j] * self.wo[j][k]
self.ao[k] = sigmoid(sum) return self.ao[:] def backPropagate(self, targets, N, M):
''' 反向传播 '''
if len(targets) != self.no:
raise ValueError('与输出层节点数不符!') # 计算输出层的误差
output_deltas = [0.0] * self.no
for k in range(self.no):
error = targets[k]-self.ao[k]
output_deltas[k] = dsigmoid(self.ao[k]) * error # 计算隐藏层的误差
hidden_deltas = [0.0] * self.nh
for j in range(self.nh):
error = 0.0
for k in range(self.no):
error = error + output_deltas[k]*self.wo[j][k]
hidden_deltas[j] = dsigmoid(self.ah[j]) * error # 更新输出层权重
for j in range(self.nh):
for k in range(self.no):
change = output_deltas[k]*self.ah[j]
self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k]
self.co[j][k] = change
#print(N*change, M*self.co[j][k]) # 更新输入层权重
for i in range(self.ni):
for j in range(self.nh):
change = hidden_deltas[j]*self.ai[i]
self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j]
self.ci[i][j] = change # 计算误差
error = 0.0
for k in range(len(targets)):
error = error + 0.5*(targets[k]-self.ao[k])**2
return error def test(self, patterns):
for p in patterns:
print(p[0], '->', self.update(p[0])) def weights(self):
print('输入层权重:')
for i in range(self.ni):
print(self.wi[i])
print()
print('输出层权重:')
for j in range(self.nh):
print(self.wo[j]) def train(self, patterns, iterations=1000, N=0.5, M=0.1):
# N: 学习速率(learning rate)
# M: 动量因子(momentum factor)
for i in range(iterations):
error = 0.0
for p in patterns:
inputs = p[0]
targets = p[1]
self.update(inputs)
error = error + self.backPropagate(targets, N, M)
if i % 100 == 0:
print('误差 %-.5f' % error) def demo():
# 一个演示:教神经网络学习逻辑异或(XOR)------------可以换成你自己的数据试试
pat = [
[[0,0], [0]],
[[0,1], [1]],
[[1,0], [1]],
[[1,1], [0]]
] # 创建一个神经网络:输入层有两个节点、隐藏层有两个节点、输出层有一个节点
n = NN(2, 2, 1)
# 用一些模式训练它
n.train(pat)
# 测试训练的成果(不要吃惊哦)
n.test(pat)
# 看看训练好的权重(当然可以考虑把训练好的权重持久化)
#n.weights() if __name__ == '__main__':
demo()

最新文章

  1. SQL Server 2012 新特性:包含数据库访问数据库引擎
  2. Mule入门基础
  3. Hdu5093 Battle ships 二分图
  4. Let’s Encrypt 配置
  5. Source Insight 常用设置和快捷键大全
  6. Oracle的DBMS_OUTPUT.PUT_LINE用法及脚本批处理方法
  7. 《OpenGL着色语言》理解点记录二
  8. class、interface、struct的区别
  9. DemoExample
  10. SQL2008-表对表直接复制数据
  11. pdf压缩之GSview
  12. Firebug中命令行栏(Commandlinie)的使用介绍和总结
  13. 五毛的cocos2d-x学习笔记08-动画
  14. Codeforces Round #252 (Div. 2) 441B. Valera and Fruits
  15. redis采用序列化方案存对象
  16. [转]Firefox拦截12306订票网站的解决办法
  17. jstl常用语句
  18. firewall服务配置
  19. Linux基础命令第三天
  20. hdu-2255(带权二分图)

热门文章

  1. scrapy简单入门及选择器(xpath\css)
  2. "docker build" requires exactly 1 argument(s).
  3. 适配iOS6与iOS7
  4. 解决win 和 ubuntu 虚拟机之间 无法 复制粘贴的问题,以及重装vmtool后,还是无法解决的办法
  5. PHP设计模式系列 - 解释器模式
  6. Mina使用总结(四)传输对象ObjectSerializationCodecFactory
  7. Weblogic web应用中获取文件的绝对路径
  8. 【洛谷】【动态规划(多维)】P1006 传纸条
  9. P3935 Calculating
  10. Js 面向对象之封装,继承,原型,原型链