BP神经网络的数据分类_MATLAB源代码
- 格式:docx
- 大小:16.85 KB
- 文档页数:4
变量mu确定了学习是根据牛顿法还是梯度法来完成,下式为更新参数的L-M规则:% jj = jX * jX% je = jX * E% dX = -(jj+I*mu) \ je随着mu的增大,LM的项jj可以忽略。
因此学习过程主要根据梯度下降即mu/je项,只要迭代使误差增加,mu也就会增加,直到误差不再增加为止,但是,如果mu太大,则会使学习停止,当已经找到最小误差时,就会出现这种情况,这就是为什么当mu达到最大值时要停止学习的原因。
mu为u的初始值,默认为0.001mu_dec为u的减小率,默认为0.1mu_inc为u的增长率,默认为10mu_max为u的最大值,默认为1e10BP神经网络Matlab实例(1)采用Matlab工具箱函数建立神经网络,对一些基本的神经网络参数进行了说明,深入了解参考Matlab帮助文档。
% 例1 采用动量梯度下降算法训练 BP 网络。
% 训练样本定义如下:% 输入矢量为% p =[-1 -2 3 1% -1 1 5 -3]% 目标矢量为 t = [-1 -1 1 1]close allclearclc% ---------------------------------------------------------------% NEWFF——生成一个新的前向神经网络,函数格式:% net = newff(PR,[S1 S2...SNl],{TF1 TF2...TFNl},BTF,BLF,PF) takes,% PR -- R x 2 matrix of min and max values for R input elements% (对于R维输入,PR是一个R x 2 的矩阵,每一行是相应输入的边界值)% Si -- 第i层的维数% TFi -- 第i层的传递函数, default = 'tansig'% BTF -- 反向传播网络的训练函数, default = 'traingdx'% BLF -- 反向传播网络的权值/阈值学习函数, default = 'learngdm'% PF -- 性能函数, default = 'mse'% ---------------------------------------------------------------% TRAIN——对 BP 神经网络进行训练,函数格式:% train(NET,P,T,Pi,Ai,VV,TV),输入参数:% net -- 所建立的网络% P -- 网络的输入% T -- 网络的目标值, default = zeros% Pi -- 初始输入延迟, default = zeros% Ai -- 初始网络层延迟, default = zeros% VV -- 验证向量的结构, default = []% TV -- 测试向量的结构, default = []% 返回值:% net -- 训练之后的网络% TR -- 训练记录(训练次数及每次训练的误差)% Y -- 网络输出% E -- 网络误差% Pf -- 最终输入延迟% Af -- 最终网络层延迟% ---------------------------------------------------------------% SIM——对 BP 神经网络进行仿真,函数格式:% [Y,Pf,Af,E,perf] = sim(net,P,PiAi,T)% 参数与前同。
求用matlab编BP神经网络预测程序求一用matlab编的程序P=[。
];输入T=[。
];输出% 创建一个新的前向神经网络net_1=newff(minmax(P),[10,1],{'tansig','purelin'},'traingdm')% 当前输入层权值和阈值inputWeights=net_1.IW{1,1}inputbias=net_1.b{1}% 当前网络层权值和阈值layerWeights=net_1.LW{2,1}layerbias=net_1.b{2}% 设置训练参数net_1.trainParam.show = 50;net_1.trainParam.lr = 0.05;net_1.trainParam.mc = 0.9;net_1.trainParam.epochs = 10000;net_1.trainParam.goal = 1e-3;% 调用TRAINGDM 算法训练BP 网络[net_1,tr]=train(net_1,P,T);% 对BP 网络进行仿真A = sim(net_1,P);% 计算仿真误差E = T - A;MSE=mse(E)x=[。
]';%测试sim(net_1,x) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%不可能啊我200928对初学神经网络者的小提示第二步:掌握如下算法:2.最小均方误差,这个原理是下面提到的神经网络学习算法的理论核心,入门者要先看《高等数学》(高等教育出版社,同济大学版)第8章的第十节:“最小二乘法”。
3.在第2步的基础上看Hebb学习算法、SOM和K-近邻算法,上述算法都是在最小均方误差基础上的改进算法,参考书籍是《神经网络原理》(机械工业出版社,Simon Haykin著,中英文都有)、《人工神经网络与模拟进化计算》(清华大学出版社,阎平凡,张长水著)、《模式分类》(机械工业出版社,Richard O. Duda等著,中英文都有)、《神经网络设计》(机械工业出版社,Martin T. Hargan等著,中英文都有)。
matlab神经⽹络多分类(模式识别神经⽹络nprtool)⼀、模式识别神经⽹络在matlab命令窗⼝输⼊:nnstart 或 nprtool 就可以进⼊matlab神经⽹络GUI⼆、鸢尾花数据集iris⽰例1.输⼊数据集,划分训练集、测试集load fisheriris;[m,n]=size(meas);data=zeros(m,n+1);data(:,1:n)=meas;for i=1:m %将字符串类别标签⽤数值形式表⽰if strcmp(species{i},'setosa') %strcmp('A','B')⽤于⽐较字符串,找出特定的字符串;类⽐find(a==b)⽤来找出特定数值data(i,n+1)=1;elseif strcmp(species{i},'versicolor')data(i,n+1)=2;elseif strcmp(species{i},'virginica')data(i,n+1)=3;endend%选择训练样本个数num_train = 60; %共150个样本,60个训练集,90个测试集%构造随机选择序列choose = randperm(length(data)); %随机种⼦打乱数据样本的顺序train_data = data(choose(1:num_train),:); %随机选取60个样本label_temp = train_data(:,end); %提取训练数据的标签 train(:,end)提取最后⼀列;label_train = zeros(length(train_data),3); %创建矩阵以储存向量形式的标签;%把输出分类标签1,2,3 改为⼯具箱要求的格式1=[100],2=[010],3=[001]for i = 1:length(train_data)label_train(i,label_temp(i)) = 1;endtrain_data = train_data(:,1:end-1)'; %提取数据集特征(剔除标签),并进⾏转置(转置也可以不必,后续GUI中转化为⾏形式即可)label_train = label_train'; %将向量形式表⽰的标签进⾏转置(也⽽不必,理由同上)test_data = data(choose(num_train+1:end),:); %提取测试集数据label_temp = test_data(:,end); %提取测试集数据的标签label_test = zeros(length(test_data),3); %创建矩阵,准备存放向量形式的测试数据的标签%把输出分类标签改为⼯具箱要求的格式for i = 1:length(test_data)label_test(i,label_temp(i)) = 1;endtest_data = test_data(:,1:end-1)'; %提取测试数据的特征,并进⾏转置label_test = label_test'; %提取测试数据的标签,并进⾏转置2. 三种⽅法进⾏模式识别神经⽹络搭建2.1 ⼿动编写m函数法法1操作⽅法:⼿动编写m函数如下(借鉴参考资料)%有三种⽅式%法1.命令窗⼝输⼊nnstart,选择pattern recognition app,⽤matlab⾃带GUI进⾏⽹络设置(最简单)%法2.完成法1后,⾃动⽣成代码,将创建⽹络的代码⽤m⽂件保存,下次要调⽤该⽹络可直接调⽤该m⽂件%法3.编写如下代码% Create a Pattern Recognition NetworkhiddenLayerSize = 10; %隐藏层神经元个数设置为10net = patternnet(hiddenLayerSize); %创建模式识别神经⽹络patternnet% 将训练集再按⽐例70:15:15分为训练集、验证集、测试集net.divideParam.trainRatio = 70/100;net.divideParam.valRatio = 15/100;net.divideParam.testRatio = 15/100;% Train the Network[net,tr] = train(net,train_data,label_train); %tr为训练过程参数?% Test the Networkpredict = net(test_data); %得到每个样本属于第⼀类、第⼆类、第三类的概率[~,predict] = max(predict); %选择概率最⼤的类别作为某⼀个测试样本的类别%% show the result --testingsfig=figure;gscatter(test_data(1,:),test_data(2,:),predict);[~,label_test] = max(label_test);accuracy = length(find(predict==label_test))/length(test_data);title(['predict the testing data and the accuracy is :',num2str(accuracy)]);法1结果:准确率:93.3%,分类效果不错。
用MATLAB的神经网络工具箱实现三层BP网络用MATLAB的神经网络工具箱实现三层BP网络% 读入训练数据和测试数据Input = [];Output = [];str = {'Test','Check'};Data = textread([str{1},'.txt']);% 读训练数据Input = Data(:,1:end-1);% 取数据表的前五列(主从成分)Output = Data(:,end);% 取数据表的最后一列(输出值)Data = textread([str{2},'.txt']);% 读测试数据CheckIn = Data(:,1:end-1);% 取数据表的前五列(主从成分)CheckOut = Data(:,end);% 取数据表的最后一列(输出值)Input = Input';Output = Output';CheckIn = CheckIn';CheckOut = CheckOut';% 矩阵赚置[Input,minp,maxp,Output,mint,maxt] = premnmx(Input,Output);% 标准化数据%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% 神经网络参数设置%====可以修正处Para.Goal = 0.0001;% 网络训练目标误差Para.Epochs = 800;% 网络训练代数Para.LearnRate = 0.1;% 网络学习速率%====Para.Show = 5;% 网络训练显示间隔Para.InRange = repmat([-1 1],size(Input,1),1);% 网络的输入变量区间Para.Neurons = [size(Input,1)*2+1 1];% 网络后两层神经元配置Para.TransferFcn= {'logsig' 'purelin'};% 各层的阈值函数Para.TrainFcn = 'trainlm';% 网络训练函数赋值% traingd : 梯度下降后向传播法% traingda : 自适应学习速率的梯度下降法% traingdm : 带动量的梯度下降法% traingdx :% 带动量,自适应学习速率的梯度下降法Para.LearnFcn = 'learngdm';% 网络学习函数Para.PerformFcn = 'sse';% 网络的误差函数Para.InNum = size(Input,1);% 输入量维数Para.IWNum = Para.InNum*Para.Neurons(1);% 输入权重个数Para.LWNum = prod(Para.Neurons);% 层权重个数Para.BiasNum = sum(Para.Neurons);% 偏置个数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%Net = newff(Para.InRange,Para.Neurons,Para.TransferFcn,...Para.TrainFcn,Para.LearnFcn,Para.PerformFcn);% 建立网络%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%Net.trainParam.show = Para.Show;% 训练显示间隔赋值Net.trainParam.goal = Para.Goal;% 训练目标误差赋值Net.trainParam.lr = Para.LearnRate;% 网络学习速率赋值Net.trainParam.epochs = Para.Epochs;% 训练代数赋值Net.trainParam.lr = Para.LearnRate;Net.performFcn = Para.PerformFcn;% 误差函数赋值%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 调试Out1 =sim(Net,Input);% 仿真刚建立的网络Sse1 =sse(Output-Out1);% 刚建立的网络误差%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [Net TR] = train(Net,Input,Output);% 训练网络并返回%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Out3 =sim(Net,Input);% 对学习训练后的网络仿真。
PSO优化的BP神经⽹络(Matlab版)前⾔:最近接触到⼀些神经⽹络的东西,看到很多⼈使⽤PSO(粒⼦群优化算法)优化BP神经⽹络中的权值和偏置,经过⼀段时间的研究,写了⼀些代码,能够跑通,嫌弃速度慢的可以改⼀下训练次数或者适应度函数。
在我的理解⾥,PSO优化BP的初始权值w和偏置b,有点像数据迁徙,等于⽤粒⼦去尝试作为⽹络的参数,然后训练⽹络的阈值,所以总是会看到PSO优化了权值和阈值的说法,(⼀开始我是没有想通为什么能够优化阈值的),下⾯是我的代码实现过程,关于BP和PSO的原理就不⼀⼀赘述了,⽹上有很多⼤佬解释的很详细了……⾸先是利⽤BP作为适应度函数function [error] = BP_fit(gbest,input_num,hidden_num,output_num,net,inputn,outputn)%BP_fit 此函数为PSO的适应度函数% gbest:最优粒⼦% input_num:输⼊节点数⽬;% output_num:输出层节点数⽬;% hidden_num:隐含层节点数⽬;% net:⽹络;% inputn:⽹络训练输⼊数据;% outputn:⽹络训练输出数据;% error : ⽹络输出误差,即PSO适应度函数值w1 = gbest(1:input_num * hidden_num);B1 = gbest(input_num * hidden_num + 1:input_num * hidden_num + hidden_num);w2 = gbest(input_num * hidden_num + hidden_num + 1:input_num * hidden_num...+ hidden_num + hidden_num * output_num);B2 = gbest(input_num * hidden_num+ hidden_num + hidden_num * output_num + 1:...input_num * hidden_num + hidden_num + hidden_num * output_num + output_num);net.iw{1,1} = reshape(w1,hidden_num,input_num);net.lw{2,1} = reshape(w2,output_num,hidden_num);net.b{1} = reshape(B1,hidden_num,1);net.b{2} = B2';%建⽴BP⽹络net.trainParam.epochs = 200;net.trainParam.lr = 0.05;net.trainParam.goal = 0.000001;net.trainParam.show = 100;net.trainParam.showWindow = 0;net = train(net,inputn,outputn);ty = sim(net,inputn);error = sum(sum(abs((ty - outputn))));end 然后是PSO部分:%%基于多域PSO_RBF的6R机械臂逆运动学求解的研究clear;close;clc;%定义BP参数:% input_num:输⼊层节点数;% output_num:输出层节点数;% hidden_num:隐含层节点数;% inputn:⽹络输⼊;% outputn:⽹络输出;%定义PSO参数:% max_iters:算法最⼤迭代次数% w:粒⼦更新权值% c1,c2:为粒⼦群更新学习率% m:粒⼦长度,为BP中初始W、b的长度总和% n:粒⼦群规模% gbest:到达最优位置的粒⼦format longinput_num = 3;output_num = 3;hidden_num = 25;max_iters =10;m = 500; %种群规模n = input_num * hidden_num + hidden_num + hidden_num * output_num + output_num; %个体长度w = 0.1;c1 = 2;c2 = 2;%加载⽹络输⼊(空间任意点)和输出(对应关节⾓的值)load('pfile_i2.mat')load('pfile_o2.mat')% inputs_1 = angle_2';inputs_1 = inputs_2';outputs_1 = outputs_2';train_x = inputs_1(:,1:490);% train_y = outputs_1(4:5,1:490);train_y = outputs_1(1:3,1:490);test_x = inputs_1(:,491:500);test_y = outputs_1(1:3,491:500);% test_y = outputs_1(4:5,491:500);[inputn,inputps] = mapminmax(train_x);[outputn,outputps] = mapminmax(train_y);net = newff(inputn,outputn,25);%设置粒⼦的最⼩位置与最⼤位置% w1阈值设定for i = 1:input_num * hidden_numMinX(i) = -0.01*ones(1);MaxX(i) = 3.8*ones(1);end% B1阈值设定for i = input_num * hidden_num + 1:input_num * hidden_num + hidden_numMinX(i) = 1*ones(1);MaxX(i) = 8*ones(1);end% w2阈值设定for i = input_num * hidden_num + hidden_num + 1:input_num * hidden_num + hidden_num + hidden_num * output_numMinX(i) = -0.01*ones(1);MaxX(i) = 3.8*ones(1);end% B2阈值设定for i = input_num * hidden_num+ hidden_num + hidden_num * output_num + 1:input_num * hidden_num + hidden_num + hidden_num * output_num + output_num MinX(i) = 1*ones(1);MaxX(i) = 8*ones(1);end%%初始化位置参数%产⽣初始粒⼦位置pop = rands(m,n);%初始化速度和适应度函数值V = 0.15 * rands(m,n);BsJ = 0;%对初始粒⼦进⾏限制处理,将粒⼦筛选到⾃定义范围内for i = 1:mfor j = 1:input_num * hidden_numif pop(i,j) < MinX(j)pop(i,j) = MinX(j);endif pop(i,j) > MaxX(j)pop(i,j) = MaxX(j);endendfor j = input_num * hidden_num + 1:input_num * hidden_num + hidden_numif pop(i,j) < MinX(j)pop(i,j) = MinX(j);endif pop(i,j) > MaxX(j)pop(i,j) = MaxX(j);endendfor j = input_num * hidden_num + hidden_num + 1:input_num * hidden_num + hidden_num + hidden_num * output_numif pop(i,j) < MinX(j)pop(i,j) = MinX(j);endif pop(i,j) > MaxX(j)pop(i,j) = MaxX(j);endendfor j = input_num * hidden_num+ hidden_num + hidden_num * output_num + 1:input_num * hidden_num + hidden_num + hidden_num * output_num + output_num if pop(i,j) < MinX(j)pop(i,j) = MinX(j);endif pop(i,j) > MaxX(j)pop(i,j) = MaxX(j);endendend%评估初始粒⼦for s = 1:mindivi = pop(s,:);fitness = BP_fit(indivi,input_num,hidden_num,output_num,net,inputn,outputn);BsJ = fitness; %调⽤适应度函数,更新每个粒⼦当前位置Error(s,:) = BsJ; %储存每个粒⼦的位置,即BP的最终误差end[OderEr,IndexEr] = sort(Error);%将Error数组按升序排列Errorleast = OderEr(1); %记录全局最⼩值for i = 1:m %记录到达当前全局最优位置的粒⼦if Error(i) == Errorleastgbest = pop(i,:);break;endendibest = pop; %当前粒⼦群中最优的个体,因为是初始粒⼦,所以最优个体还是个体本⾝for kg = 1:max_iters %迭代次数for s = 1:m%个体有52%的可能性变异for j = 1:n %粒⼦长度for i = 1:m %种群规模,变异是针对某个粒⼦的某⼀个值的变异if rand(1)<0.04pop(i,j) = rands(1);endendend%r1,r2为粒⼦群算法参数r1 = rand(1);r2 = rand(1);%个体位置和速度更新V(s,:) = w * V(s,:) + c1 * r1 * (ibest(s,:)-pop(s,:)) + c2 * r2 * (gbest(1,:)-pop(s,:));pop(s,:) = pop(s,:) + 0.3 * V(s,:);%对更新的位置进⾏判断,超过设定的范围就处理下。
GA-BP神经网络应用实例之MATLAB程序% gap.xls中存储训练样本的原始输入数据 37组% gat.xls中存储训练样本的原始输出数据 37组% p_test.xls中存储测试样本的原始输入数据 12组% t_test.xls中存储测试样本的原始输出数据 12组% 其中gabpEval.m适应度值计算函数,gadecod.m解码函数%--------------------------------------------------------------------------nntwarn off;% nntwarn函数可以临时关闭神经网络工具箱的警告功能,当代码使用到神经% 网络工具箱的函数时会产生大量的警告而这个函数可以跳过这些警告但% 是,为了保证代码可以在新版本的工具箱下运行,我们不鼓励这么做pc=xlsread('gap.xls');tc=xlsread('gat.xls');p_test=xlsread('p_test.xls');t_test=xlsread('t_test.xls');p=pc';t=tc';p_test=p_test';t_test=t_test';% 归一化处理for i=1:2P(i,:)=(p(i,:)-min(p(i,:)))/(max(p(i,:))-min(p(i,:))); endfor i=1:4T(i,:)=(t(i,:)-min(t(i,:)))/(max(t(i,:))-min(t(i,:))); endfor i=1:2P_test(i,:)=(p_test(i,:)-min(p_test(i,:)))/(max(p_test(i,:))-min(p_test(i,:)));end%--------------------------------------------------------------------------% 创建BP神经网络,隐含层节点数为12net=newff(minmax(P),[12,4],{'tansig','purelin'},'trainlm'); %-------------------------------------------------------------------------- % 下面使用遗传算法对网络进行优化R=size(P,1);% BP神经网络输入层节点数S2=size(T,1);% BP神经网络输出层节点数S1=12;% 隐含层节点数S=R*S1+S1*S2+S1+S2;% 遗传算法编码长度aa=ones(S,1)*[-1,1];popu=100;% 种群规模initPop=initializega(popu,aa,'gabpEval');% 初始化种群gen=500;% 遗传代数% 下面调用gaot工具箱,其中目标函数定义为gabpEval[x,endPop,bPop,trace]=ga(aa,'gabpEval',[],initPop,[1e-6 11],'maxGenTerm',...gen,'normGeomSelect',[0.09],['arithXover'],[2],'nonUnifMutation',[2 gen 3]);%--------------------------------------------------------------------------% 绘收敛曲线图figure;plot(trace(:,1),1./trace(:,3),'r-'); hold on;plot(trace(:,1),1./trace(:,2),'b-'); xlabel('遗传代数');ylabel('平方和误差');figure;plot(trace(:,1),trace(:,3),'r-'); hold on;plot(trace(:,1),trace(:,2),'b-'); xlabel('遗传代数');ylabel('适应度');legend('平均适应度值','最优适应度值'); %-------------------------------------------------------------------------- % 下面将初步得到的权值矩阵赋给尚未开始训练的BP网络[W1,B1,W2,B2,P,T,A1,A2,SE,val]=gadecod(x); net.IW{1,1}=W1;net.LW{2,1}=W2;net.b{1}=B1;net.b{2}=B2;% 设置训练参数net.trainParam.epochs=3000;net.trainParam.goal=1e-6;% 训练网络net=train(net,P,T);w1=net.IW{1,1};w2=net.LW{2,1};b1=net.b{1};b2=net.b{2};% 测试网络性能temp=sim(net,P_test);yuce1=[temp(1,:);temp(2,:),;temp(3,:);temp(4,:)];for i=1:4yuce(i,:)=yuce1(i,:)*(max(t_test(i,:))-min(t_test(i,:)))+min(t_test(i,:));end%--------------------------------------------------------------------------% 测试输出结果之一figure;plot(1:12,yuce(1,:),'bo-');ylabel('切口外径 mm');hold on;plot(1:12,t_test(1,:),'r*-'); legend('测试结果','测试样本');figure;plot(1:12,yuce(1,:)-t_test(1,:),'b-');ylabel('误差 mm');title('测试结果与测试样本误差');figure;plot(1:12,((yuce(1,:)-t_test(1,:))/t_test(1,:))*100,'b*'); ylabel('百分比');title('测试结果与测试样本误差');% 测试输出结果之二figure;plot(1:12,yuce(2,:),'bo-'); ylabel('切口内径 mm');hold on;plot(1:12,t_test(2,:),'r*-'); legend('测试结果','测试样本'); figure;plot(1:12,yuce(2,:)-t_test(2,:),'b-');ylabel('误差 mm');title('测试结果与测试样本误差');figure;plot(1:12,((yuce(2,:)-t_test(2,:))/t_test(2,:))*100,'b*'); ylabel('百分比');title('测试结果与测试样本误差');% 测试输出结果之三figure;plot(1:12,yuce(3,:),'bo-'); ylabel('最大滚切力 N');hold on;plot(1:12,t_test(3,:),'r*-'); legend('测试结果','测试样本'); figure;plot(1:12,yuce(3,:)-t_test(3,:),'b-');ylabel('误差 N');title('测试结果与测试样本误差');figure;plot(1:12,((yuce(3,:)-t_test(3,:))/t_test(3,:))*100,'b*');ylabel('百分比');title('测试结果与测试样本误差');% 测试输出结果之四figure;plot(1:12,yuce(4,:),'bo-'); ylabel('切断时间 s');hold on;plot(1:12,t_test(4,:),'r*-');legend('测试结果','测试样本');figure;plot(1:12,yuce(4,:)-t_test(4,:),'b-');ylabel('误差 s');title('测试结果与测试样本误差');figure;plot(1:12,((yuce(4,:)-t_test(4,:))/t_test(4,:))*100,'b*'); ylabel('百分比');title('测试结果与测试样本误差');%--------------------------------------------------------------------------。
基于MATLAB的BP人工神经网络设计目录
一、介绍1
1.1研究背景1
1.2BP神经网络1
二、BP神经网络的设计3
2.1BP神经网络模型原理3
2.2BP神经网络模型参数5
2.3权重偏置矩阵更新方法6
三、MATLAB实现BP神经网络8
3.1MATLAB软件环境8
3.2代码实现8
3.3实验结果10
四、结论及展望12
一、介绍
1.1研究背景
人工神经网络(ANNs)被归类为一种模拟生物神经网络的模型,具有高度学习能力和自适应性,用于解决有关模式识别、拟合曲线、识别图像、辨识声音、推理、预测等问题。
在这些任务中,Backpropagation (BP)神
经网络是应用最广泛的神经网络结构。
BP神经网络是一种反向传播的多
层前馈神经网络,它的结构简单、计算方法有效,可以学习训练集的特征,在测试集上取得较好的精度。
1.2BP神经网络
BP神经网络(或叫反向传播网络,BP网络)是一种多层前馈神经网络,它是由对神经网络训练的单步算法“反向传播算法”δ开发的。
BP神经
网络由输入层、隐层和输出层构成,它将被调节的参数及权值分配给每个
网络层,以调整网络性能的训练过程。
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>#define IN 2 //输入向量维数#define OUT 2 //输出向量维数#define NUM 20 //样本数量#define Loop_MAX 262140 //最大循环次数#define dot_MAX 20 //最大结点个数typedef struct //bp人工神经网络结构{int dot; //隐层节点数double v[IN][dot_MAX]; //输入层权矩阵double u[dot_MAX][dot_MAX]; //隐藏层权矩阵double w[dot_MAX][OUT]; //输出层权矩阵double rate; //学习率double error; //允许误差限}bp_net;double v[IN][3]={0.5,0.4,0.1,0.2,0.6,0.2}; //题目要求的权矩阵double u[3][3]={0.10,0.55,0.35,0.20,0.45,0.35,0.25,0.15,0.60}; //同上double w[3][OUT]={0.30,0.35,0.35,0.25,0.45,0.30}; //同上double fnet(double net) //Sigmoid函数{return 1/(1+exp(-net));}void Initialize_Bp(bp_net *bp) //初始化bp网络{printf("请输入隐层结点数:\n");scanf("%d", &(*bp).dot);printf("请输入学习率:\n");scanf("%lf", &(*bp).rate);printf("请输入允许误差限:\n");scanf("%lf", &(*bp).error);int i, j,flag;start: printf("请选择权矩阵输入形式:\n1、随机产生权矩阵\n2、手动输入权矩阵\n3、载入题目要求权矩阵\n");scanf("%d",&flag);if(flag==1){srand((unsigned)time(NULL)); //随机函数产生随机权矩阵for (i = 0; i < IN; i++)for (j = 0; j < (*bp).dot; j++)(*bp).v[i][j] = rand() / (double)(RAND_MAX);for (i = 0; i < (*bp).dot; i++)for (j = 0; j < (*bp).dot; j++)(*bp).u[i][j] = rand() / (double)(RAND_MAX);for (i = 0; i < (*bp).dot; i++)for (j = 0; j < OUT; j++)(*bp).w[i][j] = rand() / (double)(RAND_MAX);}else if(flag==2){printf("输入权矩阵:\n");for (i = 0; i < IN; i++)for (j = 0; j < (*bp).dot; j++)scanf("%lf",&(*bp).v[i][j]);printf("隐藏权矩阵:\n");for (i = 0; i < (*bp).dot; i++)for (j = 0; j < (*bp).dot; j++)scanf("%lf",&(*bp).u[i][j]);printf("输出权矩阵:\n");for (i = 0; i < (*bp).dot; i++)for (j = 0; j < OUT; j++)scanf("%lf",&(*bp).w[i][j]);}else if(flag==3){for (i = 0; i < IN; i++)for (j = 0; j < 3; j++)(*bp).v[i][j] = v[i][j];for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)(*bp).u[i][j] = u[i][j];for (i = 0; i < 3; i++)for (j = 0; j < OUT; j++)(*bp).w[i][j] = w[i][j];printf("载入完成!\n");}else{printf("输入错误!请重新输入!\n");goto start;}printf("初始化输入权矩阵:\n");for (i = 0; i < IN; i++){for (j = 0; j < (*bp).dot; j++)printf("%lf ",(*bp).v[i][j]);printf("\n");}printf("初始化隐藏层权矩阵:\n");for (i = 0; i < (*bp).dot; i++){for (j = 0; j < (*bp).dot; j++)printf("%lf ",(*bp).u[i][j]);printf("\n");}printf("初始化输出权矩阵:\n");for (i = 0; i < (*bp).dot; i++){for (j = 0; j < OUT; j++)printf("%lf ",(*bp).w[i][j]);printf("\n");}printf("\n");}void Train_Bp(bp_net *bp, double x[NUM][IN], int y[NUM][OUT]) //训练bp网络{double e = (*bp).error; //允许误差限double rate = (*bp).rate; //学习率int dot = (*bp).dot; //隐藏层结点double v[IN][dot_MAX],w[dot_MAX][OUT],u[dot_MAX][dot_MAX]; //权矩阵double Error_Input[dot_MAX],Error_hider[dot_MAX], Error_Output[OUT]; //各个结点的反向误差double Input[dot_MAX],hider[dot_MAX],Output[OUT]; //各个层的结点输出int i,j,k,n,flag; //flag为是否继续修改权矩阵标志量double temp;for (i = 0; i < IN; i++) //复制结构体中的权矩阵for (j = 0; j < dot; j++)v[i][j] = (*bp).v[i][j];for (i = 0; i < dot; i++)for (j = 0; j < dot; j++)u[i][j] = (*bp).u[i][j];for (i = 0; i < dot; i++)for (j = 0; j < OUT; j++)w[i][j] = (*bp).w[i][j];for (n = 0;n<Loop_MAX; n++) //反向误差计算{flag=1;for (i= 0; i < NUM; i++){for (k= 0; k < dot; k++) //计算输入层输出向量{temp = 0;for (j = 0; j < IN; j++)temp += x[i][j] * v[j][k];Input[k] = fnet(temp);}for (k= 0; k < dot; k++) //计算隐藏层输出向量{temp = 0;for (j = 0; j < dot; j++)temp +=Input[j] * u[j][k];hider[k] = fnet(temp);}for (k = 0; k < OUT; k++) //计算输出层输出向量{temp = 0;for (j = 0; j < dot; j++)temp += hider[j] * w[j][k];Output[k] = fnet(temp);}for (j = 0; j < OUT ; j++) //测试结果与是否在误差范围内{if(fabs(y[i][j]-Output[j])<e)continue; //如果满足精度要求,则继续测试下一个结点的情况else{flag=0; //修改了权矩阵for (j = 0; j < OUT; j++)Error_Output[j] = y[i][j] - Output[j];for (j = 0; j < dot; j++) //计算隐层权修改量{temp = 0;for (k = 0; k < OUT; k++)temp += w[j][k] * Error_Output[k];Error_hider[j] = temp * hider[j] * (1-hider[j]);}for (j = 0; j < dot; j++) //修改输出层权矩阵for (k = 0; k < OUT; k++)w[j][k] += rate * hider[j] * Error_Output[k];for(j = 0;j < dot;j ++) //计算输入层修改量{temp = 0;for(k = 0;k< dot; k++)temp += u[j][k] * Error_hider[k];Error_Input[j]= temp * Input[j] * (1-Input[j]);}for (j = 0; j < dot; j++) //修改隐藏层权矩阵for (k = 0; k < dot; k++)u[j][k] += rate * Input[j] * Error_hider[k];for(j = 0;j < IN; j++) //修改输入层权矩阵for(k =0 ;k< dot;k ++)v[j][k] += rate * x[i][j] * Error_Input[k];}}}if(!flag)continue; //若flag=0,标明修改了权矩阵,需重新训练实例直到满足精度条件else //相反,当所有实例均循环一次后,仍未修改权矩阵,标明满足要求,结束循环break;}printf("总共循环次数:%d\n", n);printf("\n");printf("修改后的输入权矩阵:\n"); //输出修改后的输入层权矩阵for (i = 0; i < IN; i++){for (j = 0; j < dot; j++)printf("%f ", v[i][j]);printf("\n");}printf("修改后的隐藏层权矩阵:\n"); //输出修改后的隐藏层权矩阵for (i = 0; i < dot; i++){for (j = 0; j < dot; j++)printf("%f ", u[i][j]);printf("\n");}printf("修改后的输出层权矩阵:\n"); //输出修改后的输出权矩阵for (i = 0; i < dot; i++){for (j = 0; j < OUT; j++)printf("%f ", w[i][j]);printf("\n");}for (i = 0; i < IN; i++) //将修改后的输入层权矩阵返回给bp结构体for (j = 0; j < dot; j++)(*bp).v[i][j] = v[i][j];for (i = 0; i < dot; i++) //将修改后的隐藏层权矩阵返回给bp结构体for (j = 0; j < dot; j++)(*bp).u[i][j] = u[i][j];for (i = 0; i < dot; i++) //将修改后的输出层权矩阵返回给bp结构体for (j = 0; j < OUT; j++)(*bp).w[i][j] = w[i][j];printf("bp网络训练结束!\n");}void Test_Bp(bp_net *bp) //使用bp网络测试结果{float Input[IN]; //输入实例double Output_In[dot_MAX]; //输入层输出double Output_Hi[dot_MAX]; //隐藏层输出double Output_Ou[OUT]; //输出层输出double temp;while (1){printf("请输入一个实例:\n");int i, j;for (i = 0; i <IN ; i++)scanf("%f", &Input[i]);for (i = 0; i < (*bp).dot; i++) //计算输入层输出{temp = 0;for (j = 0; j < IN; j++)temp += Input[j] * (*bp).v[j][i];Output_In[i] = fnet(temp);}for (i = 0; i < (*bp).dot; i++) //计算隐藏层输出{temp = 0;for (j = 0; j < (*bp).dot; j++)temp += Output_In[j] * (*bp).u[j][i];Output_Hi[i] = fnet(temp);}for (i = 0; i < OUT; i++) //计算输出层输出{temp = 0;for (j = 0; j < (*bp).dot; j++)temp += Output_Hi[j] * (*bp).w[j][i];Output_Ou[i] = fnet(temp);}printf("bp网络计算结果:\n");printf("\n");for (i = 0; i < OUT; i++){printf("%.6f ", Output_Ou[i]);if(Output_Ou[i]>=1)printf(" 肯定是!\n");elseswitch((int)(Output_Ou[i]*10)){case 0:printf(" 肯定不是!");break;case 1:printf(" 稍稍像是!");break;case 2:printf(" 有点像是!");break;case 3:printf(" 有些像是!");break;case 4:printf(" 比较像是!");break;case 5:printf(" 差不多是!");break;case 6:printf(" 相当是!");break;case 7:printf(" 很是!");break;case 8:printf(" 极是!");break;case 9:printf(" 几乎是!");break;}printf("\n");}}}void main(void){double x[NUM][IN]= //训练样本{{0.05,0.02},{0.09,0.11},{0.12,0.20},{0.15,0.22},{0.20,0.25},{0.75,0.75},{0.80,0.83},{0.82,0.80},{0.90,0.89},{0.95,0.89},{0.09,0.04},{0.10,0.10},{0.14,0.21},{0.18,0.24},{0.22,0.28},{0.77,0.78},{0.79,0.81},{0.84,0.82},{0.94,0.93},{0.98,0.99},};int y[NUM][OUT] = //理想输出{{1,0},{1,0},{1,0},{1,0},{1,0},{0,1},{0,1},{0,1},{0,1},{0,1},{1,0},{1,0},{1,0},{1,0},{1,0},{0,1},{0,1},{0,1},{0,1},{0,1},};bp_net bp; //定义bp结构体Initialize_Bp(&bp); //初始化bp网络结构Train_Bp(&bp, x, y); //训练bp神经网络Test_Bp(&bp); //测试bp神经网络}。
%%%清除空间
clc
clear all ;
close all ;
%%%训练数据预测数据提取以及归一化
%%%下载四类数据
load data1 c1
load data2 c2
load data3 c3
load data4 c4
%%%%四个特征信号矩阵合成一个矩阵
data ( 1:500 , : ) = data1 ( 1:500 , :) ;
data ( 501:1000 , : ) = data2 ( 1:500 , : ) ;
data ( 1001:1500 , : ) = data3 ( 1:500 , : ) ;
data ( 1501:2000 , : ) = data4 ( 1:500 , : ) ;
%%%%%%从1到2000间的随机排序
k = rand ( 1 , 2000 ) ;
[ m , n ] = sort ( k ) ; %%m为数值,n为标号
%%%%%%%%%%%输入输出数据
input = data ( : , 2:25 ) ;
output1 = data ( : , 1) ;
%%%%%%把输出从1维变到4维
for i = 1 : 1 :2000
switch output1( i )
case 1
output( i , :) = [ 1 0 0 0 ] ;
case 2
output( i , :) = [ 0 1 0 0 ] ;
case 3
output( i , :) = [ 0 0 1 0 ] ;
case 4
output( i , :) = [ 0 0 0 1 ] ;
end
end
%%%%随机抽取1500个样本作为训练样本,500个样本作为预测样本
input_train = input ( n( 1:1500 , : ) )’ ;
output_train = output ( n( 1:1500 , : ) )’ ;
input_test = input ( n( 1501:2000 , : ) )’ ;
output_test = output ( n( 1501:2000 , : ) )’ ;
%%%%输入输出数据归一化
[ inputn , inputps ] = mapminmax ( input_train ) ;
%%%网络结构初始化
innum = 24 ; %输入层
midnum = 25 ; %隐含层
outnum = 4 ; %输出层
%权值初始化
w1 = rands ( midnum , innum ) ;
b1 = rands ( midnum , 1 ) ;
w2 = rands ( midnum , outnum ) ;
b2 = rands ( outnum , 1) ;
w2_1 = w2 ; w2_2 = w2_1 ;
w1_1 = w1 ; w1_2 = w1_1 ;
b1_1 = b1 ; b1_2 = b1_1 ;
b2_1 = b2 ; b2_2 = b2_1 ;
%%%学习速率
xite = 0.1 ;
alfa = 0.01 ;
%%%%%网络训练
for ii = 1:10
E( ii ) = 0 ;
for i = 1:1:1500 ;
%%网络预测输出
x = inputn ( : , j ) ;
%%%隐含层输出
for j = 1:1:midnum
l (j) = inputn ( : , i )’*w1( j , : )’ + b1 (j) ;
lout (j) = 1/( 1 +exp( -1(j) ) ) ;
end
%%%%输出层输出
yn = w2’ * lout’ + b2 ;
%%%权值阈值修正
%计算权值变化率
dw2 = e * lout ;
db2 = e’ ;
for j = 1:1:midnum
S= 1/(1 + exp ( -l(j) ) ) ;
Fl (j) = S * ( 1- S) ;
end
for k = 1:1:innum
for j = 1:1:midnum
dw1( k, j ) = Fl (j) * x (k) *( e(1)*w2( j,1) + e(2)*w2( j,2) + e(3)*w2( j,3) + e(4)*w2( j,4) ) ;
db1( j ) = Fl (j) * *( e(1)*w2( j,1) + e(2)*w2( j,2) + e(3)*w2( j,3) + e(4)*w2( j,4) ) ;
end
end
w1=w1_1+xite*dw1';
b1=b1_1+xite*db1';
w2=w2_1+xite*dw2';
b2=b2_1+xite*db2';
w1_2=w1_1;w1_1=w1;
w2_2=w2_1;w2_1=w2;
b1_2=b1_1;b1_1=b1;
b2_2=b2_1;b2_1=b2;
end
end
%%%%语音特征信号分类
input_test = mapminmax ( ‘apply’ , input_test , inputps );
for ii = 1:1
for i = 1:500
%隐含层输出
for j = 1:1:midnum
l (j) = input_test ( : , i )’ * w1( j , : )’ + b1(j) ;
lout ( j ) = 1/ ( 1 + exp( -l(j) ) ) ;
end
fore( :,i ) = w2’ * lout’ + b2 ;
end
end
%%%结果分析
%%%%根据网络输出找出数据属于哪类
for i = 1:500
output_fore (i) = find ( fore (:,i) = =max (fore(:,i) ) ) ;
end
%%%%%BP网络预测输出
error = output_fore - output1 ( n( 1501:2000) )’ ;
%%画出分类图
figure (1)
plot ( output_fore , ‘r’ )
hold on
plot (output1( n (1501:2000))’ , ‘b’ ) ;
legend ( ‘预测语音类别’ , ‘实际语音类别’ )
%%%画出误差图
figure (2)
plot (error)
title ( ‘BP网络分类误差’ , ‘fontsize’ , 12 )
xlabel ( ‘语音信号’ , ‘fontsize’ , ‘12’ )
ylabel ( ‘分类误差’ , ‘fontsize’ , 12 )
%%%%%找出属于哪种类型
for i = 1:500
if error (i) ~= 0
[ b,c ] = max (output_test( :,i ) );
switch c
case 1
k(1) = k(1) + 1 ;
case 2
k(2) = k(2) + 1 ;
case 3
k(3) = k(3) + 1 ;
case 4
k(4) = k(4) + 1 ;
end
end
end
%%%%找出每一类的个体总和
kk = zeros ( 1,4 )
for i = 1:500
[ b,c ] = max ( output_test( :,i) ) ;
switch c
case 1
kk(1) = kk(1) + 1 ;
case 2
kk(2) = kk(2) + 1 ;
case 3
kk(3) = kk(3) + 1 ;
case 4
kk(4) = kk(4) + 1 ;
end
end
%%%正确率
nightridio = ( kk - k )./ kk