MATLAB实现BP神经网络

来源:互联网 发布:数据库课程设计报告 编辑:程序博客网 时间:2024/05/19 19:30

        毕业设计做SAR特征提取时提取完SAR图像特征后需要用分类器验证特征的有效性,一般k-NN就能有很好的效果了,作为对比我尝试了一下BP神经网络。MATLAB里自带了神经网络工具箱,特征维数如果太大会需要很大的内存,而且速度也比较慢,于是试着自己写了一个BP神经网络的程序,并在Iris数据集上做了验证。

        这里学习算法用的是标准BP算法,本质是梯度下降,代码如下:

function net = BP(Input, Output, HideNum, epochs, lr)% lr:learn rate.% e:Mean square error.% Predict = Activation(w2*Activation(w1*x+b1)+b2);.[InNum, TrainNum] = size(Input);OutNum = size(Output, 1);sigmoid = @(x) 1./(1 + exp(-x));alpha = 0.9;w1 = rand([HideNum InNum]);b1 = rand([HideNum 1]);w2 = rand([OutNum HideNum]);b2 = rand([OutNum 1]);for i = 1:epochs    Index = randperm(TrainNum);    Input = Input(:,Index);    Output = Output(:,Index);    nabla2 = zeros([OutNum HideNum]);    nabla1 = zeros([HideNum InNum]);    for j = 1:TrainNum        Y = sigmoid(w1*Input(:,j)+b1); % 隐含层输出.HideNum*1        Predict = sigmoid(w2*Y+b2); % OutNum*1        delta2 = (Output(:,j) - Predict).*Predict.*(1-Predict);   % OutNum*1        delta1 = w2'*delta2.*Y.*(1-Y);   % HideNum*1        nabla2 = lr*(1-alpha)*delta2*Y' + alpha*nabla2; % OutNum*HideNum        nabla1 = lr*(1-alpha)*delta1*Input(:,j)' + alpha*nabla1; % HideNum*InNum        w2 = w2 + nabla2;        w1 = w1 + nabla1;        b2 = b2 + lr*(1-alpha)*delta2 + alpha*delta2;        b1 = b1 + lr*(1-alpha)*delta1 + alpha*delta1;    end    if mod(i,100) == 0        Predict = sigmoid(w2*sigmoid(w1*Input+b1*ones([1 TrainNum]))+b2*ones([1 TrainNum]));        mserror = 0.5*sum(mean((Predict-Output).^2,2));        fprintf('Epoch:%d error:%f\n',i,mserror);    endendif mod(i,100) ~= 0    Predict = sigmoid(w2*sigmoid(w1*Input+b1*ones([1 TrainNum]))+b2*ones([1 TrainNum]));    mserror = 0.5*sum(mean((Predict-Output).^2,2));    fprintf('Epoch:%d error:%f\n',i,mserror);endnet.w1 = w1;net.b1 = b1;net.w2 = w2;net.b2 = b2;end
       程序返回一个结构体net,包含了训练得到的网络参数。

       经测试在Iris数据集上的准确率为97%,测试代码如下:

clear[ftrain1,ftrain2,ftrain3,ftrain4,SpeciesTrain] = textread('TrainData.txt','%f%f%f%f%f');[ftest1,ftest2,ftest3,ftest4,SpeciesTest] = textread('TestData.txt','%f%f%f%f%f');TrainIn = [ftrain1 ftrain2 ftrain3 ftrain4]';TestIn = [ftest1 ftest2 ftest3 ftest4]';TrainIn = mapminmax(TrainIn,-4,4);TestIn = mapminmax(TestIn,-4,4);TrainLabels = [[1;0;0]*ones([1 25]) [0;1;0]*ones([1 25]) [0;0;1]*ones([1 25])];net = BP(TrainIn,TrainLabels,10,200,0.04);sigmoid = @(x) 1./(1 + exp(-x));Predict = sigmoid(net.w2*sigmoid(net.w1*TestIn+net.b1*ones([1 75]))+net.b2*ones([1 75]));cnt = 0;for i = 1:75    if SpeciesTest(i) == find(Predict(:,i) == max(Predict(:,i)))        cnt = cnt + 1;    endendfprintf('Correct predict:%d\nAccuracy:%f\n',cnt,cnt/75);
      运行后可以看到正确分类数为73,准确率为97.3%,不低于MATLAB自带的神经网络的结果。但是在MSTAR数据中,BP神经网络的表现不如k-NN,具体做法是首先对SAR图像进行小波分解,选用LL2低频分量然后用二维PCA进行降维,最后分类。经测试BP神经网络最好只能达到73%的准确率,而k-NN则惊人地有94+%的准确率,这与我看的一些文献的结果不相符(文献中大多都是BP性能优于k-NN的),经过反复验证我的k-NN分类等代码是没有问题的,这个问题令我很费解。
附上Iris数据:链接:http://pan.baidu.com/s/1pLpZKLX 密码:uyrc

0 0