%---------------------------------------------%
% %
% 工作室提供代做matlab仿真 %
% %
% 详情请访问:http://cn.mikecrm.com/5k6v1DP %
% %
%---------------------------------------------%
clear all
close all
clc
rand('seed',2);
nSampDim=2; %样本是二维的
t1=rand(1000,1).*pi;
t2=rand(1000,1).*pi+pi;
r=3*rand(1000,1)+5;
x1=r.*cos(t1);
y1=r.*sin(t1)-1;
x2=r.*cos(t2)+5;
y2=r.*sin(t2)+4;
%p1=[x1,y1]*[cos(pi/50),sin(pi/50);-sin(pi/50),cos(pi/50)];
%p2=[x2,y2]*[cos(pi/50),sin(pi/50);-sin(pi/50),cos(pi/50)];
%A1=p1(:,1); %旋转后x轴的坐标
%A2=p1(:,2); %旋转后y轴的坐标
%C1=p2(:,1);
%C2=p2(:,2);
A=[x1,y1];
C=[x2,y2];
%AB各取150个进行训练
train_num_A=750;
train_num_C=750;
nTrainNum=train_num_A+train_num_C;
NUM_A=1000;
NUM_C=1000;
% A随机选取训练与测试的数据
r=randperm(NUM_A); %随机打乱A序列
traind(1:train_num_A,:)=A(r(1:train_num_A),:); %选A中的150个进行训练
testd(1:NUM_A-train_num_A,:)=A(r(train_num_A+1:NUM_A),:); %选A中剩下的150个进行测试
%C随机选取训练与测试的数据
r=randperm(NUM_C); %随机打乱C的序列
traind(train_num_A+1:train_num_A+train_num_C,:)=C(r(1:train_num_C),:);
testd(NUM_A-train_num_A+1:NUM_A+NUM_C-train_num_A-train_num_C,:)=C(r(train_num_C+1:NUM_C),:);
%赋值
train1=zeros(1,train_num_A+train_num_C);
train1(1:train_num_A)=1;
test1=zeros(1,NUM_A+NUM_C-train_num_A-train_num_C);
test1(1:NUM_A-train_num_A)=1;
%%构造网络
net.nIn=2; %两个输入层节点
net.nHidden=10; %3个隐含层节点
net.nOut=1; %一个输出层节点
w=2*(rand(net.nHidden,net.nIn)-1/2);
b=2*(rand(net.nHidden,1)-1/2);
net.w1=[w,b];
W=2*(rand(net.nOut,net.nHidden)-1/2);
B=2*(rand(net.nOut,1)-1/2);
net.w2=[W,B];
%%训练数据归一化
%mm=mean(traind);
%均值平移
%traind_s=zeros(nTrainNum,2);
%for i=1:2
%traind_s(:,i)=traind(:,i)-mm(i);
%end
%方差标准化
%m1(1)=std(traind_s(:,1));
%m1(2)=std(traind_s(:,2));
%for i=1:2
%traind_s(:,i)=traind_s(:,i)/m1(i);
%end
%%训练
SampleInEx=[traind';ones(1,nTrainNum)];
expectedOut=train1;
eb=0.01; %误差容限
eta=0.1; %学习率
mc=0.1; %动量因子
maxiter=5000; %最大迭代次数
iteration=0; %第一代
errRec=zeros(1,maxiter);
outRec=zeros(nTrainNum,maxiter);
NET=[];%记录
%开始迭代
for i=1:maxiter
hid_input=net.w1*SampleInEx; %隐含层的输入
hid_out=sigmoid(hid_input); %隐含层的输出
ou_input1=[hid_out;ones(1,nTrainNum)]; %输出层的输入
ou_input2=net.w2*ou_input1;
out_out=sigmoid(ou_input2);
outRec(:,i)=out_out';
err=expectedOut-out_out; %误差
sse=sumsqr(err);
errRec(i)=sse; %保存误差值
fprintf('第 %d 次迭代 误差: %f\n', i, sse);
iteration=iteration + 1;
%判断是否收敛
if sse<=eb
break;
end
%误差反向传播
%隐含层与输出层之间的局部梯度
DELTA=err.*sigmoid(ou_input2).*(1-sigmoid(ou_input2));
%输入层与隐层之间的局部梯度
delta=net.w2(:,1:end-1)'*DELTA.*sigmoid(hid_input).*(1-sigmoid(hid_input));
%权值修改量
dWEX=DELTA*ou_input1';
dwex=delta*SampleInEx';
%修改权值,如果不是第一次修改,则使用动量因子
if i==1
net.w2=net.w2+eta*dWEX;
net.w1=net.w1+eta*dwex;
else
net.w2=net.w2+(1-mc)*eta*dWEX+mc*dWEXOld;
net.w1=net.w1+(1-mc)*eta*dwex+mc*dwexOld;
end
%记录上一次的权值修改量
dWEXOld=dWEX;
dwexOld=dwex;
end
%%测试
%测试数据归一化
%for i=1:2
%testd_s(:,i)=testd(:,i)-mm(i);
%end
%for i=1:2
%testd_s(:,i)=testd_s(:,1)/m1(i);
%end
%计算测试输出
InEx=[testd';ones(1,2000-nTrainNum)];
hid_input=net.w1*InEx;
hid_out=sigmoid(hid_input);
ou_input1=[hid_out;ones(1,2000-nTrainNum)];
ou_input2=net.w2*ou_input1;
out_out=sigmoid(ou_input2);
outout1=out_out;
%取整
out_out(out_out<0.5)=0;
out_out(out_out>=0.5)=1;
%正确率
rate=sum(out_out==test1)/length(out_out);
%%显示
%显示训练样本
train_A=traind(train1==1,:);
train_A=train_A';
train_C=traind(train1==0,:);
train_C=train_C';
x=-15:0.1:25;
[xx,yy]=meshgrid(x);
for i=1: length(xx)
for j=1:length(yy)
xi=[xx(i,j),yy(i,j),1];
hp=net.w1*xi';
tau=sigmoid(hp);
tauex=[tau',1]';
HM=net.w2*tauex;
out=sigmoid(HM);
z(i,j)=out;
end
end
figure(3)
plot(train_A(1,:),train_A(2,:),'bo');
hold on;
plot(train_C(1,:),train_C(2,:),'r*');
[c,h]=contour(x,x,z,0.5,'b');
clabel(c,h);
xlabel('x')
ylabel('y')
axis([-15 25 -15 25])
title('训练样本分布')
legend('A','C')
M(i)=getframe;
figure(2)
mesh(x,x,z);
figure(5)
plot(x1,y1,'k*')
hold on;
plot(x2,y2,'ro')
figure(4)
axis on
hold on
grid
[nRow,nCol]=size(errRec);
plot(1:nCol,errRec,'b-','LineWidth',1.5);
legend('误差平方和')
xlabel('迭代次数','FontName','Times','FontSize',10);
ylabel('误差')
fprintf('-------错误分类表----------\n')
fprintf(' 编号 标签 x y\n')
ind= find(out_out ~=test1);
for i=1:length(ind)
fprintf(' %d %d %f %f \n', ind(i),test1(ind(i)), testd(ind(i),1), testd(ind(i),2));
end
fprintf('最终迭代次数\n %d\n', iteration);
fprintf('正确率:\n %f%%\n',rate*100);