1 通过神经网络滤波和信号处理,传统的sigmoid函数具有全局逼近能力,而径向基rbf函数则具有更好的局部逼近能力,采用完全正交的rbf径向基函数作为激励函数,具有更大的优越性,这就是小波神经网络,对细节逼近能力更强。
BP网络的特点
①网络实质上实现了一个从输入到输出的映射功能,而数学理论已证明它具有实现任何复杂非线性映射的功能。这使得它特别适合于求解内部机制复杂的问题。我们无需建立模型,或了解其内部过程,只需输入,获得输出。只要BPNN结构优秀,一般20个输入函数以下的问题都能在50000次的学习以内收敛到最低误差附近。而且理论上,一个三层的神经网络,能够以任意精度逼近给定的函数,这是非常诱人的期望;
②网络能通过学习带正确答案的实例集自动提取“合理的”求解规则,即具有自学习能力;
③网络具有一定的推广、概括能力。
bp主要应用
回归预测(可以进行拟合,数据处理分析,事物预测,控制等)、 分类识别(进行类型划分,模式识别等),在后面的学习中,都将给出实例程序。
但无论那种网络,什么方法,解决问题的精确度都无法打到100%的,但并不影响其使用,因为现实中很多复杂的问题,精确的解释是毫无意义的,有意义的解析必定会损失精度。
BP注意问题
1、BP算法的学习速度很慢,其原因主要有:
a 由于BP算法本质上为梯度下降法,而它所要优化的目标函数又非常复杂,因此,必然会出现“锯齿形现象”,这使得BP算法低效;
结论4:由上表可以看出,后者的初始权值比较合适些,因此训练的时间变短,
误差收敛速度明显快些。因此初始权值的选取对于一个网络的训练是很重要的。
1.4,用最基本的BP 算法来训练BP 神经网络时,学习率、均方
误差、权值、阈值的设置都对网络的训练均有影响。综合选取合理的值,将有
利于网络的训练。在最基本的BP 算法中,学习率在整个训练过程是保持不变的,
学习率过大,算法可能振荡而不稳定;学习率过小,则收敛速度慢,训练时间
长。而要在训练之前选择最佳的学习率是不现实的。因此学习率可变的BP 算法
(variable learning rate backpropagation ,VLBP)应运而生。下一结介绍
用VLBP 来训练该网络的情况。
b 存在麻痹现象,由于优化的目标函数很复杂,它必然会在神经元输出接近0或1的情况下,出现一些平坦区,在这些区域内,权值误差改变很小,使训练过程几乎停顿;
c 为了使网络执行BP算法,不能用传统的一维搜索法求每次迭代的步长,而必须把步长的更新规则预先赋予网络,这种方法将引起算法低效。
2、网络训练失败的可能性较大,其原因有:
a 从数学角度看,BP算法为一种局部搜索的优化方法,但它要解决的问题为求解复杂非线性函数的全局极值,因此,算法很有可能陷入局部极值,使训练失败;
b 网络的逼近、推广能力同学习样本的典型性密切相关,而从问题中选取典型样本实例组成训练集是一个很困难的问题。
3、网络结构的选择:
尚无一种统一而完整的理论指导,一般只能由经验选定。为此,有人称神经网络的结构选择为一种艺术。而网络的结构直接影响网络的逼近能力及推广性质。因此,应用中如何选择合适的网络结构是一个重要的问题。
4、新加入的样本要影响已学习成功的网络,而且刻画每个输入样本的特征的数目也必须相同。
5、采用s型激活函数,由于输出层各神经元的理想输出值只能接近于1或0,而不能打到1或0,因此设置各训练样本的期望输出分量Tkp时,不能设置为1或0,设置0.9或0.1较为适宜。
一 认识bp:
第二节内容:主要是阐述BP中几个容易混绕的概念和问题,包括什么是网络的泛化能力?过拟合是什么,怎么处理?学习速率有什么作用?神经网络的权值和阈值分别是个什么概念?用BP逼近非线性函数,如何提高训练精度?本节主要学习BP中几个容易混绕的概念和问题:什么是网络的泛化能力?过拟合是什么,怎么处理?学习速率有什么作用?神经网络的权值和阈值分别是个什么概念?用BP逼近非线性函数,如何提高训练精度?
什么是网络的泛化能力?
一个神经网路是否优良,与传统最小二乘之类的拟合评价不同(主要依据残差,拟合优度等),不是体现在其对已有的数据拟合能力上,而是对后来的预测能力,既泛化能力。
网络的预测能力(也称泛化能力、推广能力)与训练能力(也称逼近能力、学习能力)的矛盾。一般情况下,训练能力差时,预测能力也差,并且一定程度上,随训练能力地提高,预测能力也提高。但这种趋势有一个极限,当达到此极限时,随训练能力的提高,预测能力反而下降,即出现所谓“过拟合”现象。此时,网络学习了过多的样本细节,而不能反映样本内含的规律。
过拟合是什么,怎么处理?
神经网络计算不能一味地追求训练误差最小,这样很容易出现“过拟合”现象,只要能够实时检测误差率的变化就可以确定最佳的训练次数,比如15000次左右的学习次数,如果你不观察,设成500000次学习,不仅需要很长时间来跑,而且最后结果肯定令人大失所望。
避免过拟合的一种方法是:在数据输入中,给训练的数据分类,分为正常训练用、变量数据、测试数据,在后面节将讲到如何进行这种分类。
其中变量数据,在网络训练中,起到的作用就是防止过拟合状态。
学习速率有什么作用?
学习速率这个参数可以控制能量函数的步幅,并且如果设为自动调整的话,可以在误差率经过快速下降后,将学习速率变慢,从而增加BPNN的稳定性。
此时训练方法采用
采用贝叶斯正则化算法提高 BP 网络的推广能力。
二 主要函数
1 prepca 函数对归一化后的样本数据进行主元分析,从而消除样本数据中的冗余成份,起到数据降维的目的。
[ptrans,transMat] = prepca(pn,0.001);
2、数据归一化 mapminmax(x,minx,maxx)minx为要取得的最小值,maxx为最大值一般归一化到0.1-0.9比较和
2 或者使用mapstd
3 反归一化 y1=mapminmax(‘reverse’,y,ps)
4 dividevec()函数 输入训练数据的乱序排法,以及分类
[trainV,valV,testV] = dividevec(p,t,valPercent,testPercent)
p = rands(3,1000);t = [p(1,:).*p(2,:); p(2,:).*p(3,:)];
[trainV,valV,testV] = dividevec(p,t,0.20,0.20);
net = newff(minmax(p),[10 size(t,1)]);
[trainV,valV,testV,trainInd,valInd,testInd] =divideblock(allV,trainRatio,valRatio,testRatio)
[训练数据,变量数据,测试数据,训练数据矩阵的标号,,变量数据标号,测试数据标号] =divideblock(所有数据,训练数据百分比,变量数据百分比,测试数据百分比)
其实dividevec和后面四个分类函数的区别在于,dividevec一般直接在Matlab代码中调用。
而后面四个函数是通过设置网络的divideFcn函数来实现,比如,net.divideFcn='divideblock',但不是说不可以在代码中像dividevec直接调用
正常数据,是用来正常训练用
变量数据,主要目的是防止训练中出现过拟合状态
测试数据,是用来看训练效果的
net = train(net,trainV.P,trainV.T,[],[],valV,testV);
sim(net,validateSamples.P,[],[],validateSamples.T)
2. 任何生成相同的随机数方法:
试着产生和时间相关的随机数,种子与当前时间有关.
rand('state',sum(100*clock))
即: rand('state',sum(100*clock)) ;rand(10)
只要执行 rand('state',sum(100*clock)) ;的当前计算机时间不现,生成的随机值就不现. 也就是如果时间相同,生成的 随机数还是会相同. 在你计算机速度足够快的情况下,试运行一下: rand('state',sum(100*clock));A=rand(5,5);rand('state',sum(100*clock));B=rand(5,5)
Traingdm % 动量梯度下降算法
Traingda 变学习率梯度下降算法
Traingdx % 变学习率动量梯度下降算法
Trainrp RPROP(弹性BP)算法,内存需求最小 大型网络训练方法
% (共轭梯度算法)
traincgf'; % Fletcher-Reeves修正算法
traincgp'; % Polak-Ribiere修正算法,内存需求比Fletcher-Reeves修正算法略大
traincgb'; % Powell-Beal复位算法,内存需求比Polak-Ribiere修正算法略大
% (大型网络的首选算法)
trainscg'; % Scaled Conjugate Gradient算法,内存需求与Fletcher-Reeves修正算法相同,计算量比上面三种算法都小很多
trainbfg'; % Quasi-Newton Algorithms - BFGS Algorithm,计算量和内存需求均比共轭梯度算法大,但收敛比较快
trainoss'; % One Step Secant Algorithm,计算量和内存需求均比BFGS算法小,比共轭梯度算法略大
% (中型网络的首选算法)
'trainlm'; % Levenberg-Marquardt算法,内存需求最大,收敛速度最快
'trainbr'; % 贝叶斯正则化算法
6 trainb用于网络初始阀值和权值训练函数
[net,tr] = trainb(net,tr,trainV,valV,testV);不直接使用由train调用。
训练好的权值、阈值的输出方法是:
输入到隐层权值: 代码: w1=net.iw{1,1}
隐层阈值:代码: theta1=net.b{1}
隐层到输出层权值 代码:w2=net.lw{2,1};
输出层阈值: 代码:theta2=net.b{2}
net.IW是输入权值,net.LW是层权值,net.b是阈值。直接用命令对这些值赋值就可以了。还有不懂的可以参看帮助
训练好的BP神经网络保存:
因为每次初始化网络时都是随机的,而且训练终止时的误差也不完全相同,结果训练后的权植和阀也不完全相同(大致是一样的),所以每次训练后的结果也略有不同。
找到比较好的结果后,用命令save filen_ame net_name保存网络,可使预测的结果不会变化,在需要的调用时用命令load filename载入。
关于如何找到比较好的结果,进行保存,可以设置误差,在循环中保存,具体使用可以参看bp交通预测优化后的例子
7 最大学习速率
lr=0.99*maxlinlr(p,1);A=purelin(W*P,B);e=T-A;[dW,dB]=learnwh(P,e,lr);B=B+dB。
w为权值,b为阀值。e为误差
神经网络例子。
例子1
本文实习带训练,验证,测试数据的BP函数识别。
x=1:1:100;y=2*sin(x*pi/10)+0.5*randn(1,100);plot(x,y);输入输出
[xg,ps]=mapminmax(x,.1,.9);[yg,pt]=mapminmax(y,.1,.9);归一化到0.1-0.9
[trainV,valV,testV] = dividevec(xg,yg,0.2,0.2);随机抽取训练,验证,测试数据
net=newff(minmax(xg),[15,1],{'tansig','purelin'},'trainscg');建立BP函数
net=train(net,trainV.P,trainV.T,[],[],valV,testV);训练
xtrain=sim(net,trainV.P,[],[],trainV.T);仿真
xvalidation= sim(net,valV.P,[],[],valV.T);仿真
xtest= sim(net,testV.P,[],[],testV.T);仿真
ytrainr=mapminmax('reverse',xtrain,pt);对仿真反归一化
yvalidationr=mapminmax('reverse',xvalidation,pt);对仿真反归一化
ytestr= mapminmax('reverse',xtest,pt);对仿真反归一化
trainr= mapminmax('reverse',trainV.T,pt);反归一化
validationr=mapminmax('reverse',valV.T,pt);反归一化
testr=mapminmax('reverse',testV.T,pt);反归一化
msetrain=mse(trainr-ytrainr);求误差
msevalidation=mse(yvalidationr-validationr);求误差
msetest=mse(testr-ytestr);求误差
例2采用贝叶斯正则化算法提高 BP 网络的推广能力。
二 RBF径向基网络
[net,tr] = newrb(P,T,goal,spread,MN,DF)
Spread为分散系数,默认为1, spread分布密度是自己调节的..我建议你多试几次,Spread越大 函数就越平滑 但是对于目标的接近就越不稳定。MN为最大神经元数目
Here we design a radial basis network given inputs P
and targets T.
P = [1 2 3];
T = [2.0 4.1 5.9];
net = newrb(P,T);
P = 1.5;
Y = sim(net,P)
众所周知,BP网络用于函数逼近时,权值的调节采用的是负梯度下降法。这个调节权值的方法有局限性,即收敛慢和局部极小等。径向基函数网络(RBF)在逼近能力、分类能力和学习速度等方面均优于BP网络。
Matlab中提供了四个径向基函数相关的函数,它们都是创建两层的神经网络,第一层都是径向基层,第二层是线性层或者竞争层。主要的区别是它们权值、阀值就算函数不同或者是否有阀值。
注意:径向基函数网络不需要训练,在创建的时候就自动训练好了。
1.net = newrbe(P,T,spread)
newrbe()函数可以快速设计一个径向基函数网络,且是的设计误差为0。第一层(径向基层)神经元数目等于输入向量的个数,加权输入函数为dist,网络输入函数为netprod;第二层(线性层)神经元数模有输出向量T确定,加权输入函数为dotprod,网络输入函数为netsum。两层都有阀值。
第一层的权值初值为p',阀值初值为0.8326/spread,目的是使加权输入为±spread时径向基层输出为0.5,阀值的设置决定了每一个径向基神经元对输入向量产生响应的区域。
2.[net,tr] = newrb(P,T,goal,spread,MN,DF)
该函数和newrbe一样,只是可以自动增加网络的隐层神经元数模直到均方差满足精度或者神经元数模达到最大为止。
例子1
P=-1:0.1:1;
T=sin(P);
spread=1;
mse=0.02;
net=newrb(P,T,mse,spread);
t=sim(net,P);
plot(P,T,'r*',P,t)
例子2
P=-1:0.1:1;
T=[-0.9602 -0.5770 -0.0729 0.3771 0.6405 0.6600 0.4609 0.1336 -0.2013 -0.4344 -0.5000 -0.3930 -0.1647 0.0988 0.3072 0.3960 0.3449 0.1816 -0.0312 -0.2189 -0.3201];
%应用newb()函数可以快速构建一个径向基神经网络,并且网络自动根据输入向量和期望值%进行调整,从而进行函数逼近,预先设定均方差精度为eg以及散布常数sc。
eg=0.02;
sc=1;
net=newrb(P,T,eg,sc);
figure;
plot(P,T,'+');
xlabel('输入');
X=-1:0.1:1;
Y=sim(net,X);
hold on;
plot(X,Y);
hold off;
legend('目标','输出')
3.net = newgrnn(P,T,spread)泛回归网络(generalized regression neural network)
广义回归网络主要用于函数逼近。它的结构完全与newbre的相同,但是有以下几点区别(没有说明的表示相同):
(1)第二网络的权值初值为T
(2)第二层没有阀值
(3)第二层的权值输入函数为normpod,网络输入函数为netsum
> > P=0:1:20;
> > T=exp(P).*sin(P);
> > net=newgrnn(P,T,0.7);
> > p=0:0.1:20;
> > t=sim(net,p);
> > plot(P,T,'*r',p,t)
4.net = newpnn(P,T,spread)概率神经网络(probabilistic neural network) (主要用于分类问题)
该网络与前面三个最大的区别在于,第二层不再是线性层而是竞争层,并且竞争层没有阀值,其它同newbre,故PNN网络主要用于解决分类问题。PNN是按下面的方式进行分类的:
为网络提供一输入向量后,首先,径向基层计算该输入向量同样本输入向量之间的距离||dist||,该层的输出为一个距离向量;竞争层接受距离向量为输入,计算每个模式出现的概率,通过竞争传递函数为概率最大的元素对应输出1,否则为0。
注意:由于第二层是竞争层,故输入/输出向量必须使用ind2vec/vec2ind函数进行转换,也就是将索引转换为向量或者向量转换为索引。 转换后行数等于数据索引个数,列数等于数据索引中最大的值
> > P=[1 2; 2 2;1 1]'
P =
1 2 1
2 2 1
> > Tc=[1 2 3]; 应该为分类索引
> > T=ind2vec(Tc)
T =
(1,1) 1
(2,2) 1
(3,3) 1
> > spread=1;
> > net=newpnn(P,T,spread);
> > t=sim(net,P)
t =
(1,1) 1
(2,2) 1
(3,3) 1
> > tc=vec2ind(t)
tc =
1 2 3
%从这里可以看出gnn对P准确分类了
例子4 读取wav文件
name=input('file name ','s');
fname = ['F:\\基于概率神经网络的数字语音识别matlab程序\newpnn\wav\name' int2str(i-1) '.wav'];
例子1
%通用径向基函数网络——
%其在逼近能力,分类能力,学习速度方面均优于BP神经网络
%在径向基网络中,径向基层的散步常数是spread的选取是关键
%spread越大,需要的神经元越少,但精度会相应下降,spread的缺省值为1
%可以通过net=newrbe(P,T,spread)生成网络,且误差为0
%可以通过net=newrb(P,T,goal,spread)生成网络,神经元由1开始增加,直到达到训练精度或神经元数目最多为止
例子1 %GRNN网络,迅速生成广义回归神经网络(GRNN)
P=[4 5 6];
T=[1.5 3.6 6.7];
net=newgrnn(P,T);
%仿真验证
p=4.5;
v=sim(net,p)
例子2 %PNN网络,概率神经网络
P=[0 0 ;1 1;0 3;1 4;3 1;4 1;4 3]';
Tc=[1 1 2 2 3 3 3];
%将期望输出通过ind2vec()转换,并设计、验证网络
T=ind2vec(Tc);
net=newpnn(P,T);
Y=sim(net,P);
Yc=vec2ind(Y)
%尝试用其他的输入向量验证网络
P2=[1 4;0 1;5 2]';
Y=sim(net,P2);
Yc=vec2ind(Y)
例子4 %绘制隐层神经元径向基传递函数的曲线
p=-3:.1:3;
a=radbas(p);
plot(p,a)
title('径向基传递函数')
xlabel('输入向量p')
%隐层神经元的权值、阈值与径向基函数的位置和宽度有关,只要隐层神经元数目、权值、阈值正确,可逼近任意函数
%例如
a2=radbas(p-1.5);
a3=radbas(p+2);
a4=a+a2*1.5+a3*0.5;
plot(p,a,'b',p,a2,'g',p,a3,'r',p,a4,'m--')
title('径向基传递函数权值之和')
xlabel('输入p');
ylabel('输出a');
%应用newrb()函数构建径向基网络的时候,可以预先设定均方差精度eg以及散布常数sc
eg=0.02;
sc=1; %其值的选取与最终网络的效果有很大关系,过小造成过适性,过大造成重叠性
net=newrb(P,T,eg,sc);
%网络测试
plot(P,T,'*')
xlabel('输入');
X=-1:.01:1;
Y=sim(net,X);
hold on
plot(X,Y);
hold off
legend('目标','输出')
%应用grnn进行函数逼近
P=[1 2 3 4 5 6 7 8];
T=[0 1 2 3 2 1 2 1];
plot(P,T,'.','markersize',30)
axis([0 9 -1 4])
title('待逼近函数')
xlabel('P')
ylabel('T')
%网络设计
%对于离散数据点,散布常数spread选取比输入向量之间的距离稍小一些
spread=0.7;
net=newgrnn(P,T,spread);
%网络测试
A=sim(net,P);
hold on
outputline=plot(P,A,'o','markersize',10,'color',[1 0 0]);
title('检测网络')
xlabel('P')
ylabel('T和A')
%应用pnn进行变量的分类
P=[1 2;2 2;1 1]; %输入向量
Tc=[1 2 3]; %P对应的三个期望输出
%绘制出输入向量及其相对应的类别
plot(P(1,:),P(2,:),'.','markersize',30)
for i=1:3
text(P(1,i)+0.1,P(2,i),sprintf('class %g',Tc(i)))
end
axis([0 3 0 3]);
title('三向量及其类别')
xlabel('P(1,:)')
ylabel('P(2,:)')
%网络设计
T=ind2vec(Tc);
spread=1;
net=newgrnn(P,T,speard);
%网络测试
A=sim(net,P);
Ac=vec2ind(A);
%绘制输入向量及其相应的网络输出
plot(P(1,:),P(2,:),'.','markersize',30)
for i=1:3
text(P(1,i)+0.1,P(2,i),sprintf('class %g',Ac(i)))
end
axis([0 3 0 3]);
title('网络测试结果')
xlabel('P(1,:)')
ylabel('P(2,:)')
3个径向基网络的matlab源程序
1.基于聚类的RBF 网设计算法
SamNum = 100; % 总样本数
TestSamNum = 101; % 测试样本数
InDim = 1; % 样本输入维数
ClusterNum = 10; % 隐节点数,即聚类样本数
Overlap = 1.0; % 隐节点重叠系数
% 根据目标函数获得样本输入输出
rand('state',sum(100*clock))
NoiseVar = 0.1;
Noise = NoiseVar*randn(1,SamNum);
SamIn = 8*rand(1,SamNum)-4;
SamOutNoNoise = 1.1*(1-SamIn+2*SamIn.^2).*exp(-SamIn.^2/2);
SamOut = SamOutNoNoise + Noise;
TestSamIn = -4:0.08:4;
TestSamOut = 1.1*(1-TestSamIn+2*TestSamIn.^2).*exp(-TestSamIn.^2/2);
figure
hold on
grid
plot(SamIn,SamOut,'k+')
plot(TestSamIn,TestSamOut,'k--')
xlabel('Input x');
ylabel('Output y');
Centers = SamIn(:,1:ClusterNum);
NumberInClusters = zeros(ClusterNum,1); % 各类中的样本数,初始化为零
IndexInClusters = zeros(ClusterNum,SamNum); % 各类所含样本的索引号
while 1,
NumberInClusters = zeros(ClusterNum,1); % 各类中的样本数,初始化为零
IndexInClusters = zeros(ClusterNum,SamNum); % 各类所含样本的索引号
% 按最小距离原则对所有样本进行分类
for i = 1:SamNum
AllDistance = dist(Centers',SamIn(:,i));
[MinDist,Pos] = min(AllDistance);
NumberInClusters(Pos) = NumberInClusters(Pos) + 1;
IndexInClusters(Pos,NumberInClusters(Pos)) = i;
end
% 保存旧的聚类中心
OldCenters = Centers;
for i = 1:ClusterNum
Index = IndexInClusters(i,1:NumberInClusters(i));
Centers(:,i) = mean(SamIn(:,Index)')';
end
% 判断新旧聚类中心是否一致,是则结束聚类
EqualNum = sum(sum(Centers==OldCenters));
if EqualNum == InDim*ClusterNum,
break,
end
end
% 计算各隐节点的扩展常数(宽度)
AllDistances = dist(Centers',Centers); % 计算隐节点数据中心间的距离(矩阵)
Maximum = max(max(AllDistances)); % 找出其中最大的一个距离
for i = 1:ClusterNum % 将对角线上的0 替换为较大的值
AllDistances(i,i) = Maximum+1;
end
Spreads = Overlap*min(AllDistances)'; % 以隐节点间的最小距离作为扩展常数
% 计算各隐节点的输出权值
Distance = dist(Centers',SamIn); % 计算各样本输入离各数据中心的距离
SpreadsMat = repmat(Spreads,1,SamNum);
HiddenUnitOut = radbas(Distance./SpreadsMat); % 计算隐节点输出阵
HiddenUnitOutEx = [HiddenUnitOut' ones(SamNum,1)]'; % 考虑偏移
W2Ex = SamOut*pinv(HiddenUnitOutEx); % 求广义输出权值
W2 = W2Ex(:,1:ClusterNum); % 输出权值
B2 = W2Ex(:,ClusterNum+1); % 偏移
% 测试
TestDistance = dist(Centers',TestSamIn);
TestSpreadsMat = repmat(Spreads,1,TestSamNum);
TestHiddenUnitOut = radbas(TestDistance./TestSpreadsMat);
TestNNOut = W2*TestHiddenUnitOut+B2;
plot(TestSamIn,TestNNOut,'k-')
W2
B2
2.基于梯度法的RBF 网设计算法
SamNum = 100; % 训练样本数
TargetSamNum = 101; % 测试样本数
InDim = 1; % 样本输入维数
UnitNum = 10; % 隐节点数
MaxEpoch = 5000; % 最大训练次数
E0 = 0.9; % 目标误差
% 根据目标函数获得样本输入输出
rand('state',sum(100*clock))
NoiseVar = 0.1;
Noise = NoiseVar*randn(1,SamNum);
SamIn = 8*rand(1,SamNum)-4;
SamOutNoNoise = 1.1*(1-SamIn+2*SamIn.^2).*exp(-SamIn.^2/2);
SamOut = SamOutNoNoise + Noise;
TargetIn = -4:0.08:4;
TargetOut = 1.1*(1-TargetIn+2*TargetIn.^2).*exp(-TargetIn.^2/2);
figure
hold on
grid
plot(SamIn,SamOut,'k+')
plot(TargetIn,TargetOut,'k--')
xlabel('Input x');
ylabel('Output y');
Center = 8*rand(InDim,UnitNum)-4;
SP = 0.2*rand(1,UnitNum)+0.1;
W = 0.2*rand(1,UnitNum)-0.1;
lrCent = 0.001; % 隐节点数据中心学习系数
lrSP = 0.001; % 隐节点扩展常数学习系数
lrW = 0.001; % 隐节点输出权值学习系数
ErrHistory = []; % 用于记录每次参数调整后的训练误差
for epoch = 1:MaxEpoch
AllDist = dist(Center',SamIn);
SPMat = repmat(SP',1,SamNum);
UnitOut = radbas(AllDist./SPMat);
NetOut = W*UnitOut;
Error = SamOut-NetOut;
%停止学习判断
SSE = sumsqr(Error)
% 记录每次权值调整后的训练误差
ErrHistory = [ErrHistory SSE];
if SSE
CentGrad = (SamIn-repmat(Center(:,i),1,SamNum))...
*(Error.*UnitOut(i,*W(i)/(SP(i)^2))';
SPGrad = AllDist(i,.^2*(Error.*UnitOut(i,*W(i)/(SP(i)^3))';
WGrad = Error*UnitOut(i,';
Center(:,i) = Center(:,i) + lrCent*CentGrad;
SP(i) = SP(i) + lrSP*SPGrad;
W(i) = W(i) + lrW*WGrad;
end
end
% 测试
TestDistance = dist(Center',TargetIn);
TestSpreadsMat = repmat(SP',1,TargetSamNum);
TestHiddenUnitOut = radbas(TestDistance./TestSpreadsMat);
TestNNOut = W*TestHiddenUnitOut;
plot(TargetIn,TestNNOut,'k-')
% 绘制学习误差曲线
figure
hold on
grid
[xx,Num] = size(ErrHistory);
plot(1:Num,ErrHistory,'k-');
3.基于OLS 的RBF 网设计算法
SamNum = 100; % 训练样本数
TestSamNum = 101; % 测试样本数
SP = 0.6; % 隐节点扩展常数
ErrorLimit = 0.9; % 目标误差
% 根据目标函数获得样本输入输出
rand('state',sum(100*clock))
NoiseVar = 0.1;
Noise = NoiseVar*randn(1,SamNum);
SamIn = 8*rand(1,SamNum)-4;
SamOutNoNoise = 1.1*(1-SamIn+2*SamIn.^2).*exp(-SamIn.^2/2);
SamOut = SamOutNoNoise + Noise;
TestSamIn = -4:0.08:4;
TestSamOut = 1.1*(1-TestSamIn+2*TestSamIn.^2).*exp(-TestSamIn.^2/2);
figure
hold on
grid
plot(SamIn,SamOut,'k+')
plot(TestSamIn,TestSamOut,'k--')
xlabel('Input x');
ylabel('Output y');
[InDim,MaxUnitNum] = size(SamIn); % 样本输入维数和最大允许隐节点数
% 计算隐节点输出阵
Distance = dist(SamIn',SamIn);
HiddenUnitOut = radbas(Distance/SP);
PosSelected = [];
VectorsSelected = [];
HiddenUnitOutSelected = [];
ErrHistory = []; % 用于记录每次增加隐节点后的训练误差
VectorsSelectFrom = HiddenUnitOut;
dd = sum((SamOut.*SamOut)')';
for k = 1 : MaxUnitNum
% 计算各隐节点输出矢量与目标输出矢量的夹角平方值
PP = sum(VectorsSelectFrom.*VectorsSelectFrom)';
Denominator = dd * PP';
[xxx,SelectedNum] = size(PosSelected);
if SelectedNum>0,
[lin,xxx] = size(Denominator);
Denominator(:,PosSelected) = ones(lin,1);
end
Angle = ((SamOut*VectorsSelectFrom) .^ 2) ./ Denominator;
% 选择具有最大投影的矢量,得到相应的数据中心
[value,pos] = max(Angle);
PosSelected = [PosSelected pos];
% 计算RBF 网训练误差
HiddenUnitOutSelected = [HiddenUnitOutSelected; HiddenUnitOut(pos,];
HiddenUnitOutEx = [HiddenUnitOutSelected; ones(1,SamNum)];
W2Ex = SamOut*pinv(HiddenUnitOutEx); % 用广义逆求广义输出权值
W2 = W2Ex(:,1:k); % 得到输出权值
B2 = W2Ex(:,k+1); % 得到偏移
NNOut = W2*HiddenUnitOutSelected+B2; % 计算RBF 网输出
SSE = sumsqr(SamOut-NNOut)
% 记录每次增加隐节点后的训练误差
ErrHistory = [ErrHistory SSE];
if SSE < ErrorLimit, break, end
% 作Gram-Schmidt 正交化
NewVector = VectorsSelectFrom(:,pos);
ProjectionLen = NewVector' * VectorsSelectFrom / (NewVector'*NewVector);
VectorsSelectFrom = VectorsSelectFrom - NewVector * ProjectionLen;
end
UnitCenters = SamIn(PosSelected);%%%%%%%%%%%
% 测试
TestDistance = dist(UnitCenters',TestSamIn);%%%%%%%%
TestHiddenUnitOut = radbas(TestDistance/SP);
TestNNOut = W2*TestHiddenUnitOut+B2;
plot(TestSamIn,TestNNOut,'k-')
k
UnitCenters
W2
B2
三Elman神经网络
Elman网络一般不推荐大步训练方法比如trainlm和trainrp
Elman神经网络是一种带有反馈的两层BP网络结构,其反馈连接是从隐含层的输出到其输入端。这种反馈方式使得Elman网络能够探测和识别时变模式。
其隐含层又称为反馈层,神经元的传递函数为tansig,输出层为线性层,传递函数为purelin。这种特殊的两层网络可以任意精度逼近任意函数,唯一的要求是其隐含层必须具有足够的神经元数目。隐含层神经元数越多,则逼近复杂函数的精度就越高。
Elman网络和传统的两层神经网络的不同之处在于其第一层具有反馈连接,它可以存储前一次的值,并应用到本次计算中。反馈状态不同,则输出结果不同。因为网络可以存储信息,所以它不但可以存储空间模式,也可以学习时间模式。
构建Elman网络:
应用函数newelm()可以构建两层或者多层Elman网络,隐含层函数通常应用tansig传递函数,输出层通常是purelin传递函数。
缺省BP训练函数为trainbfg,也可以用trainlm(),但是因为训练速度较快不太适合Elman网络。缺省BP学习规则为learngdm,缺省表现函数为mse。
应用initnw()函数可以对网络进行初始化,网络权值和阈值应用Nguyen-Widrow方法初始化。假设构建Elman网络的语句如下:
net=newelm([0 1], [5 1], {'tansig', 'logsig'})
表示网络层中隐含层有5个神经元节点,节点函数为tansig,输出层有一个神经元,节点函数logsig,输入向量范围为[0 1]。
网络仿真:
随机产生8维二值向量作为输入向量:
P=round(rand(1,8));
转换成单元排列形式。
Pseq=con2seq(P);
应用初始化网络对输入向量仿真计算。
Y=sim(net, Pseq);
然后输出向量转换成向量形式:
z=seq2con(Y);
输出向量为z{1,1}
Elman神经网络的训练:
训练Elman神经网络可以用train()或者adapt()。两个函数不同之处在于,train()函数应用反向传播训练函数进行权值修正,通常选用traingdx训练函数;adapt()函数应用学习规则函数进行权值修正,通常选用learngdm函数。
Elman神经网络的可靠性要比一些其他类型网络差一些,这是因为在训练和调整时,应用误差梯度的估计值。恰恰因为这一点,构建网络时,为了达到这一精度,Elman神经网络隐含层神经元的数目比其他网络结构相对较多。
%训练的MATLAB程序如下:
%其输入输出样本如下:
P=round(rand(1,8));
T=[0 (P(1:end-1)+P(2:end)==2)];
%输入向量为随机生成的二值向量,只有当连续两个输入为1时输出向量才为1,否则为0。
%构建Elman网络:
net=newelm([0 1], [5 1], {'tansig', 'logsig'}, 'trainbfg');
diff1=T-z{1,1}
四 线性神经网路
线性层一般用于信号处理和预测中的自适应滤波器。
Newlin,net=newlin([-1,1],s,td,0.01),s为输出向量数目,td延迟向量默认为[0]
例子net=newlin([-1,1],1,[0 1],0.01),p=[0 -1 1 1 0 -1 1 0 01];y=sim(net,p);y.
[net,y,e,pf]=adapt(net,p,t)
Net=newlind(p,t)