BP神经网络进行模式识别

具体的BP神经网络详细说明请参考博客:https://www.jianshu.com/p/3d96dbf3f764
神经网络的基础编程可参考博客:https://www.cnblogs.com/heaad/archive/2011/03/07/1976443.html

例题详解

利用BP网络进行模式识别,训练样本如下:
在这里插入图片描述
最后测试的样本为输入:
1 0
0.5 0.5
0.1 1
那么我们这次使用的是matlab编程来训练该神经网络达到分类的效果
由于数据太简单,对输入数据没必要进行预处理或者归一化,若其他项目需要用到,请参考博客:
https://blog.csdn.net/qq_42517365/article/details/102924232
首先我们输入训练集

[input1,input2,class]=textread('data1.txt','%n%n%n',3);

训练集的text的文本格式如下:
在这里插入图片描述
input1和input2中为矩阵:
[ 1 [ 0
0 0
0 ] 1 ]
input1 input2

其中class即为输出:
[ 1
0
-1 ]
由于博主实验过后,若是输出我们直接用一个3x1的矩阵进行输出,也就是标签用这三个数字来训练的话,会陷入局部最优的情况,因为数据库太少了,于是我使用另一种方式表达,分类总共为3类,则第一类为-1,第二类为0,第三类为1,我们用一个3x3的矩阵来表示,若输出为:
1 0 0
则为第一类别,对应输出为-1;
若输出为:
0 1 0
则为第二类别,对应输出为0;
若输出为:
0 0 1
则为第三类别,对应输出为1。
因此我们则需先建立3x3的输出矩阵:
循环中的是将训练集中的对应输出放入这个矩阵中。

s=length(class);
Ouput=zeros(s,3); %设置输出标志的矩阵
for i=1:s
    num_ji=class(i)+2
    output(i,num_ji)=1;
end

然后我们建立bp神经网络:

net = newff(minmax(input),[6 3],{'logsig' 'logsig'},'traingdx');%此处为一个隐藏层为六个神经元的网络,输出为三个
net.trainparam.show = 1;%一步一显示
net.trainParam.min_grad=1e-30;%最低梯度值设置
net.trainparam.epochs=5000;%步进数
net.trainparam.goal=0.00000000001;%误差最小值
net.trainParam.lr=0.01;%学习率

随后我们开始训练网络:

net=train(net,input,output');%没什么讲的,自己看

训练结束后我们可以测试一下网络是否真的训练完了
最好的方法就是用训练集中的数据进行测试,若是训练完成,那么识别率应该是百分百的

testinput=[input1,input2]';%测试集就选择原有的训练集
Y=sim(net,testinput);%进行测试
[s1,s2] = size(Y) ;%存放Y的行和列的值
hitNum = 0 ;%识别正确个数
for i = 1 : s2
    [m,Index]= max(Y(:,i));%存放Y每列最大值和最大值所在列的位置
    [m1,Index1]=max(output(:,i));%存放output最大值和最大值做所在列的位置
    if(Index ==Index1) %若相同则说明识别类别正确
        hitNum =hitNum + 1 ;
    end
end
sprintf('识别率是 %3.3f%%',100 * hitNum / s2 )

随后我们完成题目的要求,对测试集的样本进行分类:

%计算数值
[c1,c2]=textread('test.txt','%n%n',3);
cinput=[c1,c2]';
S=sim(net,cinput);

得到s为:
在这里插入图片描述
可以看到第一个数据为第三类
第二个数据为第二类
第三个数据为第一类
因此输入1 0的输出为1
输入0.5 0.5的输出为0
输入0.1 1的输出为-1

到此bp神经网络分类的任务完成,以下是完整的程序代码。

clear all
close all
load data1.dat
[input1,input2,class]=textread('data1.txt','%n%n%n',3);
%[input,mini,maxl]=premnmx([input1,input2]');%归一化处理
input=[input1,input2]';
s=length(class);
Ouput=zeros(s,3); %设置输出标志的矩阵
for i=1:s
    num_ji=class(i)+2
    output(i,num_ji)=1;
end
net = newff(minmax(input),[6 3],{'logsig' 'logsig'},'traingdx');
net.trainparam.show = 1;
net.trainParam.min_grad=1e-30;
net.trainparam.epochs=5000;
net.trainparam.goal=0.00000000001;
net.trainParam.lr=0.01;
net=train(net,input,output');
%识别率检测
testinput=[input1,input2]';
Y=sim(net,testinput);
[s1,s2] = size(Y) ;
hitNum = 0 ;
for i = 1 : s2
    [m,Index]= max(Y(:,i));
    [m1,Index1]=max(output(:,i));
    if(Index ==Index1) 
        hitNum =hitNum + 1 ;
    end
end
sprintf('识别率是 %3.3f%%',100 * hitNum / s2 )
%计算数值
[c1,c2]=textread('test.txt','%n%n',3);
cinput=[c1,c2]';
S=sim(net,cinput);

训练图像

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

补充:

博主也尝试了直接将题干的输出作为标签进行训练但是都无法收敛,以下是程序:

load data1.dat
[input1,input2,class]=textread('data1.txt','%n%n%n',3);
%[input,mini,maxl]=premnmx([input1,input2]');
[input,minl,maxl]=premnmx([input1,input2]');
net = newff(minmax(input),[10 1],{'logsig' 'logsig'},'traingdx');
net.trainparam.show = 50;
net.trainParam.min_grad=1e-30;
net.trainparam.epochs=10000;
net.trainparam.goal=0.01;
net.trainParam.lr=0.01;
net=train(net,input,class');
%识别率检测
testinput=[input1,input2]';
Y=sim(net,testinput);
%Y=round(Y);

%sprintf('识别率是 %3.3f%%',100 * hitNum / s2 )
%计算数值
[c1,c2]=textread('test.txt','%n%n',2);
cinput=[c1,c2]';
S=sim(net,cinput);

若有高手能看出问题,也欢迎评论指出。是无论迭代次数和调参误差都无法下降。
训练图像如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐