Python实现的人工神经网络算法示例【基于反向传播算法】


Posted in Python onNovember 11, 2017

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

注意:本程序使用Python3编写,额外需要安装numpy工具包用于矩阵运算,未测试python2是否可以运行。

本程序实现了《机器学习》书中所述的反向传播算法训练人工神经网络,理论部分请参考我的读书笔记。

在本程序中,目标函数是由一个输入x和两个输出y组成,
x是在范围【-3.14, 3.14】之间随机生成的实数,而两个y值分别对应 y1 = sin(x),y2 = 1。

随机生成一万份训练样例,经过网络的学习训练后,再用随机生成的五份测试数据验证训练结果。

调节算法的学习速率,以及隐藏层个数、隐藏层大小,训练新的网络,可以观察到参数对于学习结果的影响。

算法代码如下:

#!usr/bin/env python3
# -*- coding:utf-8 -*-
import numpy as np
import math
# definition of sigmoid funtion
# numpy.exp work for arrays.
def sigmoid(x):
  return 1 / (1 + np.exp(-x))
# definition of sigmoid derivative funtion
# input must be sigmoid function's result
def sigmoid_output_to_derivative(result):
  return result*(1-result)
# init training set
def getTrainingSet(nameOfSet):
  setDict = {
    "sin": getSinSet(),
    }
  return setDict[nameOfSet]
def getSinSet():
  x = 6.2 * np.random.rand(1) - 3.14
  x = x.reshape(1,1)
  # y = np.array([5 *x]).reshape(1,1)
  # y = np.array([math.sin(x)]).reshape(1,1)
  y = np.array([math.sin(x),1]).reshape(1,2)
  return x, y
def getW(synapse, delta):
  resultList = []
  # 遍历隐藏层每个隐藏单元对每个输出的权值,比如8个隐藏单元,每个隐藏单元对两个输出各有2个权值
  for i in range(synapse.shape[0]):
    resultList.append(
      (synapse[i,:] * delta).sum()
      )
  resultArr = np.array(resultList).reshape(1, synapse.shape[0])
  return resultArr
def getT(delta, layer):
  result = np.dot(layer.T, delta)
  return result
def backPropagation(trainingExamples, etah, input_dim, output_dim, hidden_dim, hidden_num):
  # 可行条件
  if hidden_num < 1:
    print("隐藏层数不得小于1")
    return
  # 初始化网络权重矩阵,这个是核心
  synapseList = []
  # 输入层与隐含层1
  synapseList.append(2*np.random.random((input_dim,hidden_dim)) - 1)
  # 隐含层1与隐含层2, 2->3,,,,,,n-1->n
  for i in range(hidden_num-1):
    synapseList.append(2*np.random.random((hidden_dim,hidden_dim)) - 1)
  # 隐含层n与输出层
  synapseList.append(2*np.random.random((hidden_dim,output_dim)) - 1)
  iCount = 0
  lastErrorMax = 99999
  # while True:
  for i in range(10000):
    errorMax = 0
    for x, y in trainingExamples:
      iCount += 1
      layerList = []
      # 正向传播
      layerList.append(
        sigmoid(np.dot(x,synapseList[0]))
        )
      for j in range(hidden_num):
        layerList.append(
          sigmoid(np.dot(layerList[-1],synapseList[j+1]))
          )
      # 对于网络中的每个输出单元k,计算它的误差项
      deltaList = []
      layerOutputError = y - layerList[-1]
      # 收敛条件
      errorMax = layerOutputError.sum() if layerOutputError.sum() > errorMax else errorMax
      deltaK = sigmoid_output_to_derivative(layerList[-1]) * layerOutputError
      deltaList.append(deltaK)
      iLength = len(synapseList)
      for j in range(hidden_num):
        w = getW(synapseList[iLength - 1 - j], deltaList[j])
        delta = sigmoid_output_to_derivative(layerList[iLength - 2 - j]) * w
        deltaList.append(delta)
      # 更新每个网络权值w(ji)
      for j in range(len(synapseList)-1, 0, -1):
        t = getT(deltaList[iLength - 1 -j], layerList[j-1])
        synapseList[j] = synapseList[j] + etah * t
      t = getT(deltaList[-1], x)
      synapseList[0] = synapseList[0] + etah * t
    print("最大输出误差:")
    print(errorMax)
    if abs(lastErrorMax - errorMax) < 0.0001:
      print("收敛了")
      print("####################")
      break
    lastErrorMax = errorMax
  # 测试训练好的网络
  for i in range(5):
    xTest, yReal = getSinSet()
    layerTmp = sigmoid(np.dot(xTest,synapseList[0]))
    for j in range(1, len(synapseList), 1):
      layerTmp = sigmoid(np.dot(layerTmp,synapseList[j]))
    yTest = layerTmp
    print("x:")
    print(xTest)
    print("实际的y:")
    print(yReal)
    print("神经元网络输出的y:")
    print(yTest)
    print("最终输出误差:")
    print(np.abs(yReal - yTest))
    print("#####################")
  print("迭代次数:")
  print(iCount)
if __name__ == '__main__':
  import datetime
  tStart = datetime.datetime.now()
  # 使用什么样的训练样例
  nameOfSet = "sin"
  x, y = getTrainingSet(nameOfSet)
  # setting of parameters
  # 这里设置了学习速率。
  etah = 0.01
  # 隐藏层数
  hidden_num = 2
  # 网络输入层的大小
  input_dim = x.shape[1]
  # 隐含层的大小
  hidden_dim = 100
  # 输出层的大小
  output_dim = y.shape[1]
  # 构建训练样例
  trainingExamples = []
  for i in range(10000):
    x, y = getTrainingSet(nameOfSet)
    trainingExamples.append((x, y))
  # 开始用反向传播算法训练网络
  backPropagation(trainingExamples, etah, input_dim, output_dim, hidden_dim, hidden_num)
  tEnd = datetime.datetime.now()
  print("time cost:")
  print(tEnd - tStart)

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

Python 相关文章推荐
Python 命令行非阻塞输入的小例子
Sep 27 Python
python+opencv实现动态物体识别
Jan 09 Python
Python设计模式之观察者模式简单示例
Jan 10 Python
python_opencv用线段画封闭矩形的实例
Dec 05 Python
Python生成器的使用方法和示例代码
Mar 04 Python
树莓派与PC端在局域网内运用python实现即时通讯
Jun 22 Python
解决Django layui {{}}冲突的问题
Aug 29 Python
python 模拟创建seafile 目录操作示例
Sep 26 Python
pandas实现将日期转换成timestamp
Dec 07 Python
在Anaconda3下使用清华镜像源安装TensorFlow(CPU版)
Apr 19 Python
详解Python模块化编程与装饰器
Jan 16 Python
利用Python读取微信朋友圈的多种方法总结
Aug 23 Python
python中使用正则表达式的后向搜索肯定模式(推荐)
Nov 11 #Python
python基础练习之几个简单的游戏
Nov 10 #Python
Python实现购物车功能的方法分析
Nov 10 #Python
Python实现的单向循环链表功能示例
Nov 10 #Python
Python3中的列表,元组,字典,字符串相关知识小结
Nov 10 #Python
浅谈Python处理PDF的方法
Nov 10 #Python
django开发教程之利用缓存文件进行页面缓存的方法
Nov 10 #Python
You might like
解析zend Framework如何自动加载类
2013/06/28 PHP
THINKPHP项目开发中的日志记录实例分析
2014/12/01 PHP
PHP简单检测网址是否能够正常打开的方法
2016/09/04 PHP
php实现生成带二维码图片并强制下载功能
2018/02/24 PHP
php微信开发之谷歌测距
2018/06/14 PHP
laravel5 Eloquent 实现事务方式
2019/10/21 PHP
Mozilla中显示textarea中选择的文字
2006/09/07 Javascript
JS 动态加载脚本的4种方法
2009/05/05 Javascript
在图片上显示左右箭头类似翻页的代码
2013/03/04 Javascript
Bootstrap每天必学之滚动监听
2016/03/16 Javascript
全面解析多种Bootstrap图片轮播效果
2016/05/27 Javascript
JavaScript Promise 用法
2016/06/14 Javascript
响应式表格之固定表头的简单实现
2016/08/26 Javascript
nodejs中向HTTP响应传送进程的输出
2017/03/19 NodeJs
Vue完整项目构建(进阶篇)
2018/02/10 Javascript
快速解决vue动态绑定多个class的官方实例语法无效的问题
2018/09/05 Javascript
JS如何把字符串转换成json
2020/02/21 Javascript
JavaScript实现点击自制菜单效果
2021/02/02 Javascript
python flask 多对多表查询功能
2017/06/25 Python
Python装饰器用法实例总结
2018/02/07 Python
python 反编译exe文件为py文件的实例代码
2019/06/27 Python
python中对数据进行各种排序的方法
2019/07/02 Python
Python图像处理PIL各模块详细介绍(推荐)
2019/07/17 Python
python 单线程和异步协程工作方式解析
2019/09/28 Python
一文彻底解决HTML5页面中长按保存图片功能
2019/06/10 HTML / CSS
AmazeUI的JS表单验证框架实战示例分享
2020/08/21 HTML / CSS
南非领先的在线旅行社:Travelstart南非
2016/09/04 全球购物
C#怎么让一个窗口居中显示?
2015/10/20 面试题
三关爱志愿服务活动方案
2014/08/17 职场文书
个人股份合作协议书
2014/10/24 职场文书
2014年化验员工作总结
2014/11/18 职场文书
2014年控辍保学工作总结
2014/12/08 职场文书
2015秋季运动会通讯稿
2015/07/18 职场文书
七个非常实用的Python工具包总结
2021/06/15 Python
深入理解CSS 中 transform matrix矩阵变换问题
2021/08/30 HTML / CSS
Python获取指定日期是"星期几"的6种方法
2022/03/13 Python