Python 实现神经网络逆向传播算法(含详细注释)

来源:互联网 发布:淘宝现代热水器怎么样 编辑:程序博客网 时间:2024/06/10 16:40

参考资料:A Step by Step Backpropagation Example

这里有翻译版本:用笔一步步演示人工神经网络的反向传播算法

上面的链接给出了一个逆向传播算法的具体例子,一步一步地描述了该算法的执行过程,并且包含完整的数学推导过程,很适合入门者阅读。

根据这篇文章,我用python简单实现了逆向传播算法,由于接触python时间不长,代码可能存在很多需要改善的地方。

实现逆向传播的代码我只参考了这一篇文章,测试用的也是文章中的例子,如果代码中有不理解的部分,可以在文章中找到相应的概念或解释。

原文中也给出了python实现代码,比起作者的代码,我认为我写得更加直接和浅白,相当于原文的直接翻译,而且有附有大量注释。

代码:

neuralNetwork.py

# -*- coding: utf-8 -*- from numpy import randomfrom math import eclass neuron:def __init__(self, typeName, net = 0, out = None, sigma = None, value = None):self.typeName = typeName # 三种神经元,input output 和 hiddenself.net = net # hidden和ouput神经元有此属性,为神经元的输入self.out = out # hidden和ouput神经元有此属性,为神经元的输出self.sigma = sigma # hidden和output神经元有此属性,用于backward propagationself.value = value # input和output神经元有此属性,保存用户输入值class NeuralNetwork:def __init__(self, inputList, outputList, layerSizeList, paraArrayList = None, biasList = None, eta = 0.5):self.inputSize = len(inputList)self.outputSize = len(outputList)self.layerNum = len(layerSizeList) # 隐藏层数self.layerSizeList = layerSizeList # 储存每个隐藏层有几个神经元self.inputNeuralList = []self.outputNeuralList = []self.layerList = [] # 储存各个隐藏层,隐藏层中储存该层中的神经元self.eta = eta # 控制梯度下降速度的参数# 未给出系数矩阵初始值,则随机生成if (paraArrayList == None):# input 与 第一个隐层间的系数矩阵firstArray = random.random(size=(inputSize, layerSizeList[0]))self.paraArrayList.append(firstArray)# 隐层之间的系数矩阵for i in range(layerNum - 1):middleArray = random.random(size=(layerSizeList[i], layerSizeList[i+1]))self.paraArrayList.append(middleArray)# 最后一个隐层与output间的系数矩阵lastArray = random.random(size=(layerSizeList[layerNum-1], outputSize))self.paraArrayList.append(lastArray)else:self.paraArrayList = paraArrayList# 未给出各层的bias,则随机产生if biasList == None:biasList = [] for i in range(layerNum+1):self.biasList.append(random.random())else:self.biasList = biasList# 生成输入神经元列表for input in inputList:self.inputNeuralList.append(neuron(typeName='input',value=input))# 生成隐藏神经元列表for size in layerSizeList:layer = []for i in range(size):layer.append(neuron(typeName='hidden'))self.layerList.append(layer)# 生层输出神经元列表for output in outputList:self.outputNeuralList.append(neuron(typeName='output',value=output))# 激活函数def sigmoid(self, x):return 1 / (1 + e**(-x))# 计算输出值和真实值的差的平方和,再除2def error(self):sum = 0;for i in range(self.outputSize):sum += (self.outputNeuralList[i].value - self.outputNeuralList[i].out)**2return sum / 2.0# 计算隐藏层和输出层中神经元的net和outdef forwardPropagation(self):# 处理第一个隐层for i in range(len(self.layerList[0])):currNeuron = self.layerList[0][i]currNeuron.net = 0for j in range(self.inputSize):currNeuron.net += self.paraArrayList[0][j][i] * self.inputNeuralList[j].valuecurrNeuron.net += self.biasList[0]currNeuron.out = self.sigmoid(currNeuron.net)# 处理其他隐层for i in range(1, self.layerNum): for j in range(len(self.layerList[i])): #对于该隐层的每个神经元currNeuron = self.layerList[i][j]currNeuron.net = 0for k in range(len(self.layerList[i-1])): #对于其上一层的每个神经元currNeuron.net += self.layerList[i-1][k].out * self.paraArrayList[i][k][j]currNeuron.out = self.sigmoid(currNeuron.net)# 处理输出层for i in range(self.outputSize):currNeuron = self.outputNeuralList[i]currNeuron.net = 0for j in range(len(self.layerList[self.layerNum-1])):currNeuron.net += self.layerList[self.layerNum-1][j].out * self.paraArrayList[len(self.paraArrayList)-1][j][i]currNeuron.net += self.biasList[len(self.biasList)-1]currNeuron.out = self.sigmoid(currNeuron.net)# 反向传播算法def backwardPropagation(self):# 先正向传播,更新各个神经元的net和outself.forwardPropagation()# 计算输出层的sigmafor neuron in self.outputNeuralList:neuron.sigma = -(neuron.value - neuron.out) * neuron.out * (1 - neuron.out)# 计算最后一个隐藏层的sigmalastHiddenLayer = self.layerList[len(self.layerList)-1]for i in range(len(lastHiddenLayer)):sum = 0for j in range(len(self.outputNeuralList)):sigma = self.outputNeuralList[j].sigmaw = self.paraArrayList[len(self.paraArrayList)-1][i][j]sum += sigma * wlastHiddenLayer[i].sigma = sum * lastHiddenLayer[i].out * (1 - lastHiddenLayer[i].out)# 计算其他隐藏层的sigmafor i in range(self.layerNum-1):sum = 0for j in range(len(self.layerList[i])):for k in range(len(self.layerList[i+1])):sigma = self.layerList[i+1][k].sigmaw = self.paraArrayList[i+1][j][k]sum += sigma * wself.layerList[i][j].sigma = sum * self.layerList[i][j].out * (1 - self.layerList[i][j].out)# 更新连接矩阵的系数# 最后一个隐层和输出层间的系数矩阵lastHiddenLayer = self.layerList[len(self.layerList)-1]for i in range(len(lastHiddenLayer)):for j in range(self.outputSize):self.paraArrayList[len(self.paraArrayList)-1][i][j] -= self.eta * self.outputNeuralList[j].sigma * lastHiddenLayer[i].out# 隐层间的系数矩阵for i in range(self.layerNum-1):for j in range(len(self.layerList[i])):for k in range(len(self.layerList[i+1])):self.paraArrayList[i+1][j][k] -= self.eta * self.layerList[i][j].out * self.layerList[i+1][k].sigma# 输入层与第一个隐层间的系数矩阵for i in range(self.inputSize):for j in range(len(self.layerList[0])):self.paraArrayList[0][i][j] -= self.eta * self.inputNeuralList[i].value * self.layerList[0][j].sigmadef train(self, round):for i in range(round):self.backwardPropagation()print 'error:', self.error()print 'predict value:',for output in self.outputNeuralList:print output.out,print ''print '---------'

test.py

import numpy as npfrom neuralNetwork import NeuralNetworkinputList = [0.05, 0.1]layerSizeList = [2]array1 = np.array([[0.15,0.25],[0.2,0.3]])array2 = np.array([[0.4,0.5],[0.45,0.55]])paraArrayList = [array1, array2]biasList = [0.35, 0.6]outputList = [0.01, 0.99]neuralNetwork = NeuralNetwork(inputList,outputList,layerSizeList,paraArrayList,biasList,1.0)neuralNetwork.train(10000)

算法的预测结果为: 0.0127848007154,0.987185784233,与目标结果0.01, 0.99 相近

原创粉丝点击