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命令行参数解析模块getopt使用实例
Apr 13 Python
使用Python的Twisted框架实现一个简单的服务器
Apr 16 Python
python实现多线程的方式及多条命令并发执行
Jun 07 Python
python基础教程之五种数据类型详解
Jan 12 Python
Python多进程库multiprocessing中进程池Pool类的使用详解
Nov 24 Python
Python闭包执行时值的传递方式实例分析
Jun 04 Python
Python多线程原理与用法详解
Aug 20 Python
Python 一句话生成字母表的方法
Jan 02 Python
python 堆和优先队列的使用详解
Mar 05 Python
next在python中返回迭代器的实例方法
Dec 15 Python
python学习之使用Matplotlib画实时的动态折线图的示例代码
Feb 25 Python
OpenCV图像变换之傅里叶变换的一些应用
Jul 26 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
新版PHP极大的增强功能和性能
2006/10/09 PHP
php mssql 日期出现中文字符的解决方法
2009/03/10 PHP
配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
2009/04/25 PHP
php Undefined index的问题
2009/06/01 PHP
PHP实现通过正则表达式替换回调的内容标签
2015/06/15 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
php使用Swoole实现毫秒级定时任务的方法
2020/09/04 PHP
javascript下过滤数组重复值的代码
2007/09/10 Javascript
javascript sudoku 数独智力游戏生成代码
2010/03/27 Javascript
script标签的 charset 属性使用说明
2010/12/04 Javascript
jQuery+css+html实现页面遮罩弹出框
2013/03/21 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
使用JavaScript和CSS实现文本隔行换色的方法
2015/11/04 Javascript
JS HTML5实现拖拽移动列表效果
2020/08/27 Javascript
图片上传之FileAPI与NodeJs
2017/01/24 NodeJs
JSON数据中存在单个转义字符“\”的处理方法
2018/07/11 Javascript
微信小程序项目实践之九宫格实现及item跳转功能
2018/07/19 Javascript
JavaScript之数组扁平化详解
2019/06/03 Javascript
了解Javascript中函数作为对象的魅力
2019/06/19 Javascript
python实现udp数据报传输的方法
2014/09/26 Python
Python的socket模块源码中的一些实现要点分析
2016/06/06 Python
python如何在终端里面显示一张图片
2016/08/17 Python
Python read函数按字节(字符)读取文件的实现
2019/07/03 Python
Python解析json时提示“string indices must be integers”问题解决方法
2019/07/31 Python
python脚本后台执行方式
2019/12/21 Python
详解python polyscope库的安装和例程
2020/11/13 Python
CSS3实现滚动条动画效果代码分享
2016/08/03 HTML / CSS
浅谈移动端网页图片预加载方案
2018/11/05 HTML / CSS
数学专业推荐信范文
2013/11/21 职场文书
车间班组长的职责
2013/12/13 职场文书
小学趣味运动会加油稿
2014/09/25 职场文书
行政复议决定书
2015/06/24 职场文书
2015年国庆节寄语
2015/08/17 职场文书
python 通过使用Yolact训练数据集
2021/04/06 Python
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题