python版BP神经网络

效果不好,郁闷

# -*- coding: utf-8 -*-
"""
Created on Fri Sep 23 20:00:52 2016

@author: Zoro.Z
"""
import sys

reload(sys)

sys.setdefaultencoding('utf8')
import numpy as np
import matplotlib.pyplot as plt
lr=0.003
SamNum = 200
TestSamNum = 100
HiddenUnit1Num=10
InDim=2 #样本输入维数
OutDim=1 #样本输出维数
#根据目标函数获得样本输入输出
SamIn1=8*np.random.random(size=SamNum)-4 #产生样本向量
SamIn2=8*np.random.random(size=SamNum)-4 #产生样本向量
SamIn=np.vstack((SamIn1,SamIn2))
SamOut=0.25*(2+np.sin(SamIn1)+np.cos(SamIn2))
# SamOut=1.1*(1-SamIn1+2*SamIn2.^2).*exp(-SamIn1.^2/2)
TestSamIn1=np.arange(-4, 4, .05)#测试数据
TestSamIn2=np.arange(-4, 4, .05) #测试数据
TestSamIn=np.vstack((TestSamIn1,TestSamIn2))
TestSamOut=0.25*(2+np.sin(TestSamIn1)+np.cos(TestSamIn2))
# TestSamOut=1.1*(1-TestSamIn1+2*TestSamIn2.^2).*exp(-TestSamIn1.^2/2) #测试数据目标输出
MaxEpochs = 10000 #最大训练次数
# lr=0.000005 #学习率,不可过大
E0=0.01 #目标误差
W1=0.2*np.random.random((HiddenUnit1Num,InDim))-0.1
B1=0.2*np.random.random((HiddenUnit1Num,1))-0.1
W2=0.2*np.random.random((OutDim,HiddenUnit1Num))-0.1
B2=0.2*np.random.random((OutDim,1))-0.1
Dw1Ex=np.zeros((HiddenUnit1Num,InDim))
Db1Ex=np.zeros((HiddenUnit1Num,1))
for i in range(0,MaxEpochs):
u=W1.dot(SamIn)+B1.dot(np.ones((1,SamIn.shape[1])))
Hidden1Out=1/(1+np.exp(-u))
NetworkOut=W2.dot(Hidden1Out)+B2   #网络输出值
#停止学习判断条件
Error=SamOut-NetworkOut#是一个1*100的向量
SSE=0.5*(np.sum(Error**2))#所有样本产生的误差平方和
if SSE<E0:
break
#误差曲线

if ((i%1)==0):
#pause(0.0000001)
plt.scatter(i,SSE)#,title('Steepest Descent');
# xlabel('epoch');ylabel('error')

#计算反向传播误差
Delta2=Error#Ep对y求偏导=(y-y^) 这个是矩阵形式,包含每个样本
a=np.zeros((10,200))#
Dw2Ex=Delta2.dot(Hidden1Out.conj().T)#E对W2偏导=Ep对W2偏导数的和=∑(y-y^)*z  求得的是每个样本的导数和∑aEp/aW2
#Dw2Ex=sum(a,2)#
Db2Ex=np.sum(Delta2);
b=np.zeros((10,2,200))#
for m in range(0,SamNum-1): #对每一个样本分别计算
Delta1=(W2.dot(Delta2[0,m]))*Hidden1Out[:,m]*(1-Hidden1Out[:,m])#Ep对Sk求偏导=aEp/aSk=(aEp/ay)*(ay/aSj)*(aSj/aZk)*(aZk/aSk)=(y-y^)*1*w2*z*(1-z),换成所有样本的矩阵形式即前式
#         Dw1Ex=Dw1Ex+Delta1*(SamIn(:,m))#           %E对W1偏导=Ep对W1偏导的和=Delta1*X=∑w2*(y-y^)*z*(1-z)*x
Db1Ex=Db1Ex+Delta1.conj().T#
for n in range(0,1):
b[:,n,m]= Delta1.dot(SamIn[n,m])
Dw1Ex=np.sum(b,2);
W1=W1+lr*Dw1Ex;
B1=B1+lr*Db1Ex;
W2=W2+lr*Dw2Ex;
B2=B2+lr*Db2Ex;
Dw1Ex=np.zeros((HiddenUnit1Num,InDim))#%Dw1Ex每次权值更新迭代最后要清零,否则本次的导数结果对上次有影响
Db1Ex=np.zeros((HiddenUnit1Num,1))#
u=W1.dot(TestSamIn)+B1.dot(np.ones((1,TestSamIn.shape[1])))
Hidden1Out=1/(1+np.exp(-u))#
TestNetworkOut=W2.dot(Hidden1Out)+B2
plt.figure(figsize=(10,6), dpi=100)
plt.xticks(np.linspace(0,200,9,endpoint=True))
plt.scatter(np.linspace(0,199,200,endpoint=True),SamOut, marker = 'x', color = 'm', label='1', s = 30)
plt.plot(np.linspace(0,199,200,endpoint=True),NetworkOut.reshape(200,1),linewidth=1, linestyle="-")
plt.show()                #legend('Original sample output','BP output');
#title('BP网络训练图');
#xlabel('Sample number');
plt.figure(figsize=(10,6), dpi=100)
plt.plot(TestSamIn1,TestNetworkOut.reshape(160,1))
plt.plot(TestSamIn1,TestSamOut)
plt.show()
#==============================================================================
#legend('Test sample output','BP output');
#title('BP网络测试图');
#label('Sample');    ### unterminated keywords ###
#plt.yticks(np.linspace(0,1,11))

See Also