RBF网络实验过程fromgraphvizimportDigraphdot=Digraph(comment='TheRoundTable')dot.node('A',"RBF网络理论理解")dot.node('B',"用数据组织RBF网络")dot.node('C',"代码实现")dot.node('D',"问题与解决方案")dot.node('E',"感受与经验")dot.edges(["AB","BC","CD","DE"])dotRBF网络理解rbf网络我觉得应该是可以解决函数拟合问题的网络,和adaline学习的类似前。与rbf网络相比,可以解决非线性可分性问题。与bp网络相比,rbf网络只有一个隐藏层,计算方便,不易陷入bp网络中经常出现的局部最优情况。rbf网络应该是建立在覆盖定理和插值定理之上的网络,在覆盖定理中,揭示了低维不可分样本点在高纬度的可分性,在插值定理中,揭示了如何利用高纬度维可分性质完成函数模拟拟合问题。rbf网络的实现关键在于rbf函数的中心点和宽高的调整。在实现代码的时候,就是围绕这个关键点进行处理的。结合RBF网络的数据组织,这道题用到的数据还是双月数据,所以问题的关键是在双月数据中找到关键点,因为我还是不懂如何使用global梯度下降来调整径向基函数的中心点、宽度和高度,所以我选择使用中心自组织的方式构建rbf网络代码实现代码实现逻辑fromgraphvizimportDigraphdot=Digraph(comment='TheRoundTable')dot.node('A',"相关包导入")dot.node('B',"导入相关数据并展示")dot.node('C',"定义高斯函数,报错函数,以及欧拉距离的计算函数")dot.node('D',"使用kmeans算法确定中心点和宽度")dot.node('E',"训练调整rbf网络高度")dot.node('F',"Decisionsurfacedisplay")dot.edges(["AB","BC","CD","DE","EF"])dot具体代码#导入相关包importnumpyasnpiimportmatplotlib.pyplotaspltimportmathLEARNING_RATE=0.45#learningratedefhalfmoon(rad,width,d,n_samp):'''生成半月数据@paramrad:radius@paramwidth:width@paramd:distance@paramn_samp:quantity'''ifn_samp%2!=0:#保证数量是doublen_samp+=1data=np.zeros((3,n_samp))#生成0矩阵,生成3行n_samp列的矩阵aa=np.random.random((2,int(n_samp/2)))radius=(rad-width/2)+width*aa[0,:]theta=np.pi*aa[1,:]x=半径*np。cos(theta)y=radius*np.sin(theta)label=np.ones((1,len(x)))#1类的标签x1=radius*np.cos(-theta)+rad#在x在y1的基础上向右移动rad个单位y1=radius*np.sin(-theta)+d#在y的倒数的基础上向下移动d个单位label1=0*np.ones((1,len(x1)))#2类数据的标签[0,:]=np.连接([x,x1])数据[1,:]=np。concatenate([y,y1])data[2,:]=np.concatenate([label,label1],axis=1)#合并数据returndatadataNum=1000data=halfmoon(10,5,5,dataNum)np.savetxt('halfmoon.txt',data.T,fmt='%4f',delimiter=',')#导入相关数据并显示defload_data(file):#读入数据x=[]y=[]withopen(file,'r')asf:lines=f.readlines()forlineinlines:line=line.strip().split(',')x_item=[float(line[0]),float(line[1])]#x_item存储x,y值y_item=float(line[2])#y_item存储z值(期望值)x.append(x_item)y.append(y_item)returnnp.array(x),np.array(y)#x,y值和z值(期望值),分别存储在x和yfile="E:\\data\\temp\\workspace\\net_exp3\\adaline_fix\\halfmoon.txt"INPUTS,OUTPUTS=load_data(file)#获取x、y值和z值(期望值)#绘制数据x_aixs=INPUTS[:,0]y_aixs=INPUTS[:,1]neg_x_axis=x_aixs[输出==0]neg_y_axis=y_aixs[输出==0]pos_x_axis=x_aixs[输出==1]pos_y_axis=y_aixs[输出==1]plt.figure()plt.scatter(neg_x_axis,neg_y_axis,c="b",s=10)plt.scatter(pos_x_axis,pos_y_axis,c="g",s=10)plt.show()#训练数据生成(通过打乱原始数据的顺序生成训练数据)data=[]foriinrange(len(INPUTS)):数据。追加([输入[i][0],输入[i][1],输出[i]])trainData=[]tmp=[]foriinrange(1000):tmp.append(i)np.random.shuffle(tmp)foriinrange(len(tmp)):trainData.append(data[tmp[i]])#定义高斯函数、误差函数、欧拉距离的计算函数defGaussianFun(center,input,方差):distance=math.sqrt(math.pow((input[0]-center[0]),2)+math.pow((input[1]-center[1]),2))GaussianOut=math.exp(-0.5*(1/math.pow(方差,2)*math.pow(distance,2)))返回GaussianOutdefErrorFun(Error):Error_sum=0foriinError:Error_sum+=math.pow(i,2)Error_sum=Error_sum/2returnError_sumdefDistance(center,input):distance=math.sqrt(math.pow((input[0]-center[0]),2)+math.pow((input[1]-center[1]),2))返回距离使用kmeans算法确定中心点和width这里先通过调库生成初始中心点#kmeans确定rbf中心点hidGradation_nodeNum=10#设置隐藏层节点数为10#生成随机中心centerNum=hidGradation_nodeNum#设置来自sklearn.cluster的中心数导入KMeansclusterData=[]foriintrainData:clusterData.append([i[0],i[1]])clusterData=np.array(clusterData)kmeans=KMeans(n_clusters=hidGradation_nodeNum,random_state=0).fit(clusterData)center=[]foriinkmeans.cluster_centers_:center.append(list(i))#这里确定的是初始中心是根据l生成的初始中心点ibrary,并使用成本函数$$J(C)=\frac{1}{2}\sum^k_{j=1}\sum_{C(i)=j}\|x_i-迭代处理中心u_j\|^2$$rbf函数的宽度由以下函数决定$$\sigma^2_j=\frac{d_{max}}{\sqrt{2*K}}$$#这里的计算是k均值优化后的中心点dataLabel=list(kmeans.labels_)tmpData=[]divideData=[]foriinrange(len(clu??sterData)):tmpData.append([clusterData[i][0],clusterData[i][1],dataLabel[i]])foriinrange(hidGradation_nodeNum):divideData.append([])process=TrueforitemintmpData:divideData[item[2]-1].append([item[0],item[1]])record=0while(process):record+=1foriinrange(len(divideData)):x=0y=0count=0tmpCenter=centerforitemindivideData[i]:count+=1x+=item[0]y+=item[1]center[i][0]=x/countcenter[i][1]=y/countcount=0foriinrange(len(center)):if(abs(tmpCenter[i][0]-center[i][0])==0和abs(tmpCenter[i][1]-center[i][1])==0):count+=1if(count==len(center)):process=Falseforiin范围(len(divideData)):divideData[i]=[]distance=[]foriinrange(len(trainData)):distance=[]forjincenter:distance.append(距离(trainData[i],j))minDistance=np.array(distance).min()distance=list(distance)divideData[distance.index(minDistance)].append([trainData[i][0],tmpData[i][1]])foriinrange(len(divideData)):x=0y=0count=0tmpCenter=centerforitemindivideData[i]:count+=1x+=item[0]y+=item[1]center[i][0]=x/countcenter[i][1]=y/countvariance=[]foriinrange(hidGradation_nodeNum):variance.append(0)key=[]for我在范围内(len(方差)):对于j在范围内(len(方差)):key.append(距离(中心[i],中心[j]))flag=np.array(key).max()foriinrange(len(variance)):variance[i]=flag/math.sqrt(2*hidGradation_nodeNum)最后生成的中心点是center生成的rbf函数widthisvariance#weight是随机生成的weight=[]tmp=np.random.uniform(-5,5)foriinrange(10):weight.append(tmp)weight=np.array(weight)del(tmp)trainingadjustrbfnetworkheight这里的停止规则是:w自然收敛正在停止#process=True#while(process)resultRecord=[]process=Truecount=0error_count=0while(process):error_record=[]count+=1print(count,"turn")foriteminrange(len(trainData)):tmp=[trainData[item][0],trainData[item][1]]tmp_result=0结果=[]gaussianStore=[]foriinrange(hidGradation_nodeNum):gaussianStore.append(GaussianFun(tmp,center[i],variance[i]))result.append(weight[i]*GaussianFun(tmp,center[i],variance[i]))fori结果:tmp_result+=ierror=trainData[item][2]-tmp_resulterror_record.append(error)deltaWeight=np.dot(np.array(gaussianStore),LEARNING_RATE*error)weight[:]+=deltaWeightif(ErrorFun(deltaWeight)<0.01):error_count+=1if(error_count>10):处理=False1turn2turn3turn4turn5turn6turn7turn8turn9turn10turn11turn决策面显示黑色点是中心点#绘制分类结果图x=[]y=[]red_xaxis=[]red_yaxis=[]green_xaxis=[]green_yaxis=[]foriinrange(-15,25):x.append(i/1)foriinrange(-8,13):y.append(i/1)对于x中的i:对于y中的j:tmp=[i,j]tmp_result=0结果=[]gaussianStore=[]forkinrange(hidGradation_nodeNum):result.append(weight[k]*GaussianFun(tmp,center[k],variance[k]))forkinresult:tmp_result+=kif(tmp_result>0.5):red_xaxis.append(i)red_yaxis.append(j)else:green_xaxis.append(i)green_yaxis.append(j)centerX=[]centerY=[]foriinrange(len(center)):centerX.append(center[i][0])centerY.append(center[i][1])plt.figure()复制代码plt.scatter(centerX,centerY,c="k",s=200,marker="*")plt.scatter(green_xaxis,green_yaxis,c="g",s=10)plt.scatter(red_xaxis,red_yaxis,c="r",s=10)plt.scatter(neg_x_axis,neg_y_axis,c="b",s=10)plt.scatter(pos_x_axis,pos_y_axis,c="b",s=10)plt.show()问题及该解决方案可能仍然无法理解某些库。比如代码中调用的kmean库,其实调用之后,用自己定义的costfunction去调整中心点,发现调用库给的中心点已经是costfunction最小的点.我可能不理解一些默认参数,所以我花了很多时间来处理很多步骤。神经网络参数很多。首先比如kmean中心点个数的确定,以及宽度的确定,宽度的计算也有两个公式。一般来说,可以调整的参数很多。有时我不知道从哪里开始。在学习rbf网络的时候,因为不了解rbf网络的原理,走了很多弯路,Fuyu展示了搞清楚几个关键参数的调整后,才知道这个网络其实可以在adaline网络的基础。这段代码是我在之前的adaline网络的基础上做的修改。最后还是很容易理解的,在设置权重调整的过程中,其实是误差函数的选择出了问题。一开始$E=\frac{1}{2}\sum^k_{i=1}e^2_i$是误差函数,但是因为对这个函数的理解不是很深,所以发现这个函数15左右就停止下落了,一开始以为是我的权值调整方式有问题,直到画了决策面,发现分类效果还不错,然后回过头来想这个功能,发现我选择这个E取15,也就是说每个点的误差都在0.1以内,这个误差还是可以接受的。关于这一点,我只能说是我对错误函数的理解不够,所以才造成了自己的错误判断。感想和体会程序应该是数据结构+算法流程+文档。在这个作业中,数据是非常简单的数据,所以困扰我的只是算法过程。了解了rbf网络的调整原理后,代码其实并不难写,只是一味的害怕。在了解rbf网络的原理之前,在github上找了几个代码。这是因为不懂原理,所以网上找的代码看不懂,也无从下手修改。了解了基础知识后,我决定自己写,其实写起来也没花多少时间。网上的代码不一定适合自己使用,还是要辩证的看网上的资料
