计算智能作业 感知机非线性拟合
作业:
自选非线性分类或曲线拟合问题,用BP网络训练、学习。
使用BP算法进行拟合:
程序代码如下:
import math
import random
import matplotlib.pyplot as plt
def ActFun(val):
return 1/(1+math.exp(-val))
class neuron(object):
def __init__(self):
self.wval=[]
self.bval=0
self.alpha=0.5
self.input=[]
self.netk=0.0 #xi * wi 之和
def InputVal(self,val): #输入上一层输出
self.input=val
if not self.wval:
for i in range(len(val)):
self.wval.append(random.uniform(-1,1))
print('wval',self.wval)
def InputAlpha(self,a): #更新a
self.alpha=a
def UpDatePara(self,ithoutput,delta): #更新参数
for i in range(len(self.wval)):
self.wval[i]=self.wval[i]-self.alpha*ithoutput[i]*delta #更新神经元的全部w
self.bval=self.bval-self.alpha*delta
print('afterwval',self.wval)
return self.wval
def GetOutput(self): #计算输出
sum=0
for i in range(len(self.wval)):
sum=sum+self.wval[i]*self.input[i]
sum=sum+self.bval
self.netk=sum #输入总值,计算δ时需要
return ActFun(sum)
def __str__(self): #标准输出
result=''
for i in range(len(self.wval)):
result=result+' '+str(self.wval[i])
return '{'+result+'}'
class BPNetwork(object): #num为一个列表 每一层的神经元数量
def __init__(self,Depth,num):
self.Depth=Depth
self.cellnum=num
self.NeuSum=[] #BP神经网络 全部神经元
for i in range(Depth):
Neu=[] #第i+1层神经元
for j in range(num[i]):
cell=neuron()
Neu.append(cell)
self.NeuSum.append(Neu)
def getout(self,input):
xdata=[]
xdata.append(input) #xdata为每一层输出 第零层为输入
for i in range(self.Depth): #层层计算输出
ydata=[] #上一层输出的临时列表
for j in range(self.cellnum[i]):
self.NeuSum[i][j].InputVal(xdata[i])
ydata.append(self.NeuSum[i][j].GetOutput())
xdata.append(ydata)
return xdata[self.Depth]
def calforward(self,input,output): #BP神经网络对于一个样本进行前向计算,返回每一层的输出
xdata=[]
xdata.append(input) #xdata为每一层输出 第零层为输入
for i in range(self.Depth): #层层计算输出
ydata=[] #上一层输出的临时列表
for j in range(self.cellnum[i]):
self.NeuSum[i][j].InputVal(xdata[i])
ydata.append(self.NeuSum[i][j].GetOutput())
xdata.append(ydata)
err=0.0
for i in range(len(xdata[self.Depth])):
err=err+(output[i]-xdata[self.Depth][i])**2
print('data',xdata)
return xdata,err
def UpdateCell(self,stoutput,data): #BP神经网络方向反向参数更新
Alldelta=[] #所有的δ值
num=self.Depth # num为神经网络层数
deltaLayer=[]
for i in range(self.cellnum[num-1]): #对最后一层的神经元进行更新
delta=(data[num][i]-stoutput[i])*(1-data[num][i])*data[num][i]
deltaLayer.append(delta)
#self.NeuSum[num-1][i].UpDatePara(data[num-1],delta) #上一层神经元的输出与δ
Alldelta.append(deltaLayer)
for i in range(num-1):
deltaLayer=[] #倒数第i+2行的δ值
for j in range(self.cellnum[num-2-i]):
delta=0
for z in range(self.cellnum[num-1-i]):
delta=delta+self.NeuSum[num-1-i][z].wval[j]*Alldelta[i][z]
delta=delta*(1-data[num-i-1][j])*data[num-i-1][j]
deltaLayer.append(delta)
#wval=self.NeuSum[num-2-i][j].UpDatePara(data[num-2-i],delta)
Alldelta.append(deltaLayer)
print('delta',Alldelta)
for i in range(num-1):
for j in range(len(self.NeuSum[i])):
self.NeuSum[i][j].UpDatePara(data[i],Alldelta[num-1-i][j])
for i in range(len(self.NeuSum[num-1])):
self.NeuSum[num-1][i].UpDatePara(data[num-1],Alldelta[0][i])
return Alldelta
def train(self,input,stoutput):
data=[]
err=0
data,err=self.calforward(input,stoutput)
error=self.UpdateCell(stoutput,data)
return err
def main():
BP=BPNetwork(2,[10,1])
a=[0.1,0.2]
c=[0.7]
b=[0.5,0.6]
d=[0.4]
adata=[]
bdata=[]
for i in range(20):
adata.append(i/20)
bdata.append(i**2/400)
for i in range(1000): #x训练次数
for j in range(20):
temp1=[]
temp2=[]
temp1.append(adata[j])
temp2.append(bdata[j])
BP.train(temp1,temp2)
outdata=[]
for i in range(20):
temp=[]
temp.append(adata[i])
outdata.append(BP.getout(temp))
plt.plot(adata,bdata)
plt.plot(adata,outdata)
plt.show()
main()
结果如上图所示(拟合y=x**2)
上次智能控制实验,看了看老师BP神经网络的代码,是将各层数据建立为各个数组,一共三层,这样感觉便起来就简单很多,也不用class啥的了。