MATLAB BP_神经网络(鸢尾花数据分类自编代码)

学习了周志华《机器学习》中的BP神经网络,编代码的时候想找别人的作参考,发现好多人都直接调用工具箱。所得非所求,只能是自己写了代码,仅供新手参考,其中大部分是矩阵直接运算,对鸢尾花2/3数据训练,1/3数据训练。准确率在96%左右
说明:代码的直接矩阵运算也是我坐那里耗费一些时间自己去想的,所以新手要看懂可能需要一些时间。一些人可能没读过这本书也会感觉云里雾里,鉴于篇幅问题,我在我的资源了上传了直接运行的代码、数据集和《机器学习》相应的理论说明,那里面有详细的梯度项理论推导,地址如下:https://download.csdn.net/download/weixin_44405310/11530170 有书的人自然心领神会。
以下是我的一些学习心得:
**什么是梯度下降法:**在这里我推一篇博文:https://blog.csdn.net/pengchengliu/article/details/80932232 大家可以参考,讲这个的人很多。
数据归一化问题: 有人不理解为什么要数据归一化,我举一个浅显的例子:一个属性集的数据数量级是10 4 ^4 4,它的阈值是0.1;另一个属性集的数据数量级是10,就算它的阈值是1,把它们分别乘起来;我们发现数量级是10的那个属性集分明就是鸡肋嘛!影响不了大局。
而matlab自带归一化函数mapminmax好像只能对行归一化,我不想转置,就自己写了一段程序。
分类: 鸢尾花是要分类的,那么输出神经元该怎么办。我们可以这样,看它有几个类别,那就定义几个输出神经元。对本例而言:[0 1 0]就可以说是第二类,刚开始的类别标签也要这么处理。当然计算的输出神经元不可能那么准确,但是非常接近1。总之,就是取最大的位置作为它的类别。其实我还有一个想法,就是把最后的激活函数乘3,只设置一个输出神经元,如果输出是0~1就是第一类, 输出在1~2就判定第二类。
隐层神经元的数目我是随便设的,这个我也不知道设置多少。

clear 
clc
f=fopen('C:\Users\HP\Desktop\iris.data');
Iris=textscan(f,'%f%f%f%f%s','delimiter',',');
fclose(f);
[~,n]=size(Iris);
for i=1:n-1
    data(:,i)=Iris{1,i};
end
[m,n]=size(data);
for i=1:m
    if strcmp(Iris{1,5}{i,1},'Iris-setosa')
        data(i,5:7)=[1 0 0];
    elseif  strcmp(Iris{1,5}{i,1}, 'Iris-versicolor')
        data(i,5:7)=[0 1 0];
    else 
        data(i,5:7)=[0 0 1];
    end
end
%数据归一化处理[0,1]区间内,
x_max=max(data);
x_min=min(data);
data=(data-ones(m,1)*x_min)./(ones(m,1)*(x_max-x_min));
% 这里可用函数data=mapminmax(data,0,1)替换
%但data需要转置因为mapminmax只能对行进行归一化
%%
%划分训练样本和测试样本 大约2/3用作训练,1/3用作测试
num=round(m/3/3);
for i=1:3
    temp=data(1+50*(i-1):50*i,:);
    sel=randperm(50,num);
    test(1+num*(i-1):num*i,:)=temp(sel,1:4);
    test_label(1+num*(i-1):num*i,:)=temp(sel,5:7);
    temp(sel,:)=[];
    train(1+(50-num)*(i-1):(50-num)*i,:)=temp(:,1:4);
    train_label(1+(50-num)*(i-1):(50-num)*i,:)=temp(:,5:7);
end
%%
[m,n]=size(train);
alpha=4;%输入神经元数目
beta=8;%隐层神经元数目
lamda=3;%输出神经元数目
rng('shuffle')
W1=rand(alpha,beta);%输入层和隐层之间的权值矩阵
W2=rand(beta,lamda);%隐层和输出层间的权值矩阵
B1=rand(1,beta);%隐层阈值矩阵
B2=rand(1,lamda);%输出层阈值矩阵
B22=B2;
W11=W1;
Eta=1;%学习率
iter_max=10000;%最大迭代次数
iter=1;
%BP神经网络,每次仅针对一个训练样例更新连接权和阈值
while iter<=iter_max
   for i=1:m
    hidden_in=train(i,:)*W1;%隐层输入
    hidden_out=sigmod(hidden_in-B1);%隐层输出
    output_in=hidden_out*W2;%输出层输入
    output_out=sigmod(output_in-B2);%输出层输出
    %计算误差
    E(i)=sum((output_out-train_label(i,:)).^2);%求平方和可用sumsqr函数
    %%
    %更新参数,BP神经网络中最核心的部分
   g=output_out.*(1-output_out).*(train_label(i,:)-output_out);%计算输出层神经元的梯度项
   e=hidden_out.*(1-hidden_out).*(g*W2');%计算隐层神经元的梯度项
   Deta_W2=Eta*hidden_out'*g;
   Deta_B2=-Eta*g;
   Deta_W1=Eta*train(i,:)'*e;
   Deta_B1=-Eta*e;
   W1=W1+Deta_W1;
   W2=W2+Deta_W2;
   B1=B1+Deta_B1;
   B2=B2+Deta_B2;
   end
%计算训练集的累积误差
E=mean(E);
if E<1e-4  %目标误差
    iter
    break
end
if mod(iter,1000)==0
       iter
end
   iter=iter+1;%更新迭代次数
end
%%
%测试
[result,accuracy]=BP_test(test,test_label,W1,W2,B1,B2);
disp('结果为:')
result';
disp(strcat('准确率为',num2str(accuracy*100),'%'))
function [result,accuracy]=BP_test(test,test_label,W1,W2,B1,B2)
%返回分类的结果
%accuracy准确率
Hidden_in=test*W1;%隐层输入
Hidden_out=sigmod(Hidden_in-B1);%隐层输出
Output_in=Hidden_out*W2;%输入层输入
Output_out=sigmod(Output_in-B2);
[~,result]=max(Output_out,[],2);
[~,index2]=max(test_label,[],2);
right=sum(result==index2);%统计分类正确的个数
total=size(test,1);%总个数
accuracy=right/total;
end
%sigmod函数在matlab里是logsig函数
function [Y]=sigmod(X)
Y=1./(1+exp(-1).^X);
end     

这是结果:
ans =

1 至 19 列

 1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     2     2

20 至 38 列

 2     2     2     3     2     2     3     2     2     2     2     2     2     2     2     3     3     3     3

39 至 51 列

 3     3     3     3     3     3     3     3     3     3     3     3     3

准确率为96.0784%

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值