Python实现的三层BP神经网络算法示例

作者:罗兵 时间:2021-05-16 19:21:05 

本文实例讲述了Python实现的三层BP神经网络算法。分享给大家供大家参考,具体如下:

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

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

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()

希望本文所述对大家Python程序设计有所帮助。

来源:http://www.cnblogs.com/hhh5460/p/4304628.html

标签:Python,神经网络,算法
0
投稿

猜你喜欢

  • 使用python接入微信聊天机器人

    2022-04-08 10:07:23
  • Python OpenCV之常用滤波器使用详解

    2023-02-07 22:18:25
  • Vue中金额、日期格式化插件@formatjs/intl的使用及说明

    2024-04-27 16:06:48
  • javascript开发中使用onpropertychange,oninput事件解决onchange事件的不足

    2024-04-26 17:14:12
  • sysbench对mysql压力测试的详细教程

    2024-01-13 01:33:40
  • Python之列表的插入&替换修改方法

    2023-04-15 00:38:27
  • MySQL不使用order by实现排名的三种思路总结

    2024-01-17 13:43:46
  • 使用Spring AOP实现MySQL数据库读写分离案例分析(附demo)

    2024-01-16 04:47:03
  • 简单实例解释Oracle分页查询

    2023-07-16 00:54:03
  • OpenCV图像轮廓的绘制方法

    2022-10-17 22:05:54
  • Python中五种实现字符串反转的方法

    2023-11-08 00:22:12
  • Python随机生成数模块random使用实例

    2022-08-04 21:04:48
  • php session_start()出错原因分析及解决方法

    2024-06-07 15:44:29
  • sqlserver中去除字符串中连续的分隔符的sql语句

    2024-01-24 02:45:51
  • Javascript——浅析注册事件

    2008-08-19 12:44:00
  • Python 调用VC++的动态链接库(DLL)

    2023-06-19 09:01:44
  • python中使用矢量化替换循环详解

    2023-08-27 00:51:01
  • SQL Server数据库连接中常见的错误分析

    2009-01-15 12:51:00
  • js数组去重的方法汇总

    2024-04-18 10:55:17
  • python实现ip查询示例

    2021-07-07 20:04:32
  • asp之家 网络编程 m.aspxhome.com