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

作者:miangangzhen 时间:2022-01-09 12:04:13 

本文实例讲述了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程序设计有所帮助。

来源:http://blog.csdn.net/miangangzhen/article/details/51281989

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

猜你喜欢

  • Python合并多个装饰器小技巧

    2022-05-31 04:51:45
  • 那些被我遗忘掉的XHTML标签们

    2008-06-07 14:27:00
  • DB2和 Oracle的并发控制(锁)的比较

    2009-02-28 10:29:00
  • php curl选项列表(超详细)

    2023-07-18 15:19:32
  • Javascript浅拷贝与深拷贝实现

    2013-07-16 22:47:46
  • Sql Server2005对现有数据进行分区具体步骤

    2008-06-26 13:18:00
  • Python协程的2种实现方式分享

    2022-12-21 12:42:56
  • SQL Server中读取XML文件的简单做法

    2008-12-23 15:29:00
  • 重命名批处理python脚本

    2021-04-27 22:56:38
  • python opencv 简单阈值算法的实现

    2023-04-04 04:23:03
  • 一篇文章教你用Python绘画一个太阳系

    2022-12-16 14:43:16
  • 浅谈视觉设计的准确性

    2007-09-18 17:59:00
  • AJAX:如何处理书签和后退按钮

    2008-03-21 18:44:00
  • python3实现字符串的全排列的方法(无重复字符)

    2022-04-14 19:47:56
  • go sync Once实现原理示例解析

    2023-07-01 12:21:13
  • python用moviepy对视频进行简单的处理

    2023-08-03 07:02:15
  • SQL注入防御:用三种策略应对SQL注入攻击

    2008-12-15 16:31:00
  • Go各时间字符串使用解析

    2023-06-25 02:15:17
  • 支持中文的Len, Left, Right函数

    2008-03-18 13:50:00
  • python基于Opencv实现人脸口罩检测

    2021-11-18 02:45:16
  • asp之家 网络编程 m.aspxhome.com