Python实现的人工神经网络算法示例【基于反向传播算法】
本文实例讲述了Python实现的人工神经网络算法。分享给大家供大家参考,具体如下:
注意:本程序使用Python3编写,额外需要安装numpy工具包用于矩阵运算,未测试python2是否可以运行。
本程序实现了《机器学习》书中所述的反向传播算法训练人工神经网络,理论部分请参考我的读书笔记。
在本程序中,目标函数是由一个输入x和两个输出y组成,
x是在范围【-3.14,3.14】之间随机生成的实数,而两个y值分别对应y1=sin(x),y2=1。
随机生成一万份训练样例,经过网络的学习训练后,再用随机生成的五份测试数据验证训练结果。
调节算法的学习速率,以及隐藏层个数、隐藏层大小,训练新的网络,可以观察到参数对于学习结果的影响。
算法代码如下:
#!usr/bin/envpython3
#-*-coding:utf-8-*-
importnumpyasnp
importmath
#definitionofsigmoidfuntion
#numpy.expworkforarrays.
defsigmoid(x):
return1/(1+np.exp(-x))
#definitionofsigmoidderivativefuntion
#inputmustbesigmoidfunction'sresult
defsigmoid_output_to_derivative(result):
returnresult*(1-result)
#inittrainingset
defgetTrainingSet(nameOfSet):
setDict={
"sin":getSinSet(),
}
returnsetDict[nameOfSet]
defgetSinSet():
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)
returnx,y
defgetW(synapse,delta):
resultList=[]
#遍历隐藏层每个隐藏单元对每个输出的权值,比如8个隐藏单元,每个隐藏单元对两个输出各有2个权值
foriinrange(synapse.shape[0]):
resultList.append(
(synapse[i,:]*delta).sum()
)
resultArr=np.array(resultList).reshape(1,synapse.shape[0])
returnresultArr
defgetT(delta,layer):
result=np.dot(layer.T,delta)
returnresult
defbackPropagation(trainingExamples,etah,input_dim,output_dim,hidden_dim,hidden_num):
#可行条件
ifhidden_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
foriinrange(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
#whileTrue:
foriinrange(10000):
errorMax=0
forx,yintrainingExamples:
iCount+=1
layerList=[]
#正向传播
layerList.append(
sigmoid(np.dot(x,synapseList[0]))
)
forjinrange(hidden_num):
layerList.append(
sigmoid(np.dot(layerList[-1],synapseList[j+1]))
)
#对于网络中的每个输出单元k,计算它的误差项
deltaList=[]
layerOutputError=y-layerList[-1]
#收敛条件
errorMax=layerOutputError.sum()iflayerOutputError.sum()>errorMaxelseerrorMax
deltaK=sigmoid_output_to_derivative(layerList[-1])*layerOutputError
deltaList.append(deltaK)
iLength=len(synapseList)
forjinrange(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)
forjinrange(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)
ifabs(lastErrorMax-errorMax)<0.0001:
print("收敛了")
print("####################")
break
lastErrorMax=errorMax
#测试训练好的网络
foriinrange(5):
xTest,yReal=getSinSet()
layerTmp=sigmoid(np.dot(xTest,synapseList[0]))
forjinrange(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__':
importdatetime
tStart=datetime.datetime.now()
#使用什么样的训练样例
nameOfSet="sin"
x,y=getTrainingSet(nameOfSet)
#settingofparameters
#这里设置了学习速率。
etah=0.01
#隐藏层数
hidden_num=2
#网络输入层的大小
input_dim=x.shape[1]
#隐含层的大小
hidden_dim=100
#输出层的大小
output_dim=y.shape[1]
#构建训练样例
trainingExamples=[]
foriinrange(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("timecost:")
print(tEnd-tStart)
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数据结构与算法教程》、《Python加密解密算法与技巧总结》、《Python编码操作技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》
希望本文所述对大家Python程序设计有所帮助。