数据挖掘——线性神经网络的Matlab实现

% 线性神经网络
% 感知器的传输函数只能输出两种可能的值,而线性神经网络的输出可以是任意值
% 线性神经网络采用widow-hoff学习规则,即lms(least mean square)来更新权值和偏置

%% 1.newlind--设计一个线性层
%{
语法格式:   net=newlind(P,T,Pi)
P:          R×Q矩阵,包含Q个训练输入向量
T:          S×Q矩阵,包含Q个期望输出向量
Pi:         1×ID细胞数组,包括初始输入延迟
函数返回设计好的线性神经网络net.设计的方法是求一个线性方程组在最小均方误差下的最优解:
[w,b]×[P,1]=T
newlind函数一经调用就不需要别的函数重新训练了
%}
%举个栗子:用newlind创建一个线性层并进行仿真
x=-5:5;
y=3*x-7;
randn('state',2);   % 随机数种子,便于重复生成同样的随机数
y=y+randn(1,length(y))*1.5; % 加入噪声的直线
plot(x,y,'o');

P=x;T=y;
net=newlind(P,T);
new_x=-5:0.2:5;
new_y=sim(net,new_x);
hold on;plot(new_x,new_y);
legend('原始数据点','最小二乘拟合函数');
net.iw
net.b
title('newlind用于最小二乘拟合直线');

%% 2.newlin--构造一个线性层
%{
语法格式1:   net=newlin(P,S,ID,LR)
语法格式2:   net=newlin(P,T,ID,LR)

P:  输入变量的范围
S:  输出节点个数
ID: 输入延迟
LR: 学习率,默认为0.01
T:  S×Q2矩阵,包含Q2个输出向量的典型值,输出节点个数为S
%}
%举个栗子:用newlin实现上面newlind的直线拟合
x=-5:5;
y=3*x-7;
randn('state',2);
y=y+randn(1,length(y))*1.5;
plot(x,y,'o');
P=x;T=y;
net=newlin(minmax(P),1,0,maxlinlr(P));  %newlin创建线性网络,maxlinlr求最大学习率
tic;net=train(net,P,T);toc
new_x=-5:0.2:5;
new_y=sim(net,new_x);
hold on;plot(new_x,new_y);
legend('原始数据点','最小二乘拟合直线');
title('newlin用于最小二乘线性拟合')
net.iw
net.b

%% 3.purelin--线性传输函数

%{
语法格式1:   A=purelin(N,FP)
N:          S×Q矩阵,其中的向量按列存放,Q个S维的输入向量
FP:         函数参数的结构体

语法格式2:  dA_dN=purelin('dn',N,A,FP)?????
%}

%% 4.learnwh--LMS学习函数

%{
语法格式:   [dW,LS]=learnwh(W,P,Z,N,A,T,E,gW,gA,D,LP,LS)

输入:
W:          权值矩阵S×R
P:          输入向量R×Q
Z:          权值输入向量S×Q
N:          网络输入向量S×Q
A:          输出向量S×Q
T:          期望输出向量S×Q
E:          层误差向量S×Q
gW:         权重梯度S×R
gA:         输出梯度S×Q
D:          神经元距离S×S
LP:         学习参数,LP.lr为学习率,默认为0.01
LS:         学习状态,初始时为空矩阵[]

输出:
dW:         权值变化矩阵
LS:         新的学习状态

语法格式:   info=learnwh('code')
根据code值得不同返回一些有用的信息:
'pnames':       学习参数的名称
'pdefaults':    学习参数的默认值
'needg':        如果函数使用了gW或gA,返回1

%}
%举个栗子:用learnwh实现一个线性神经网络
P=-5:5;
d=3*P-7;

randn('state',2);
d=d+randn(1,length(d))*1.5  %期望输出

P=[ones(1,length(P));P] %P加上偏置
lp.lr=0.01  %学习率
MAX=150;    %最大迭代次数
ep1=0.1;    %均方差终止阈值
ep2=0.0001; %权值变化阈值

%初始化
w=[0,0];
%循环更新
for i=1:MAX
   fprintf('第%d次迭代:\n',i)
   e=d-purelin(w*P);    % 求得误差向量
   ms(i)=mse(e)        % 均方差
   if (ms(i)<ep1)   %如果均方差达到阈值则收敛,跳出循环
       fprintf('均方差小于指定数而终止\n');
       break;
   end
   dW=learnwh([],P,[],[],[],[],e,[],[],[],lp,[]);   %权值调整
   if (norm(dW)<ep2)
      fprintf('权值变化小于指定数而终止\n');
      break;
   end
   w=w+dW;
end

%显示
fprintf('算法收敛于:\nw=(%f,%f),MSE:%f\n',w(1),w(2),ms(i));
figure;
subplot(2,1,1); %绘制散点和直线
plot(P(2,:),d,'o');title('散点与直线拟合结果');
xlabel('x');ylabel('y');
axis([-6,6,min(d)-1,max(d)+1]);
x1=-5:0.2:5;
y1=w(1)+w(2)*x1;
hold on;plot(x1,y1);
subplot(2,1,2);
semilogy(1:i,ms,'-o');
xlabel('迭代次数');ylabel('MSE');title('均方差下降曲线');

%% 5.maxlinlr--最大学习率

%{
语法格式1:  lr=maxlinlr(P)  % lr=0.9999/max(eig(p*p')),eig计算矩阵的特征值
语法格式2:  lr=maxlinlr(P,'bias')   %把偏置作为1加入P,将偏置和权值统一计算
%}
X=[1 2 -4 7;0.1 3 10 6];
lr=maxlinlr(X,'bias')
lr2=maxlinlr(X)
lr3=0.9999/max(eig(X*X'))

%% 6.mse--均方误差性能函数
%{
语法格式:   perf=mse(E)=1/N∑(xi)^2,i=1,2,3,...N,N为E所有元素的个数
对E中所有的元素求均方误差(=均方平均值)
%}

%% 7.linearlayer--构造线性层的函数

%{
语法格式:       net=linearlayer(inptDelays,widrowHoffLR)
inputDelays:    输入延迟的行向量
widrowHffLR:    学习率
%}
%用linearlayer解决线性拟合问题
clear;clc;
x=-5:5;
y=3*x-7;
randn('state',2);
y=y+randn(1,length(y))*1.5;
plot(x,y,'o');
P=x;T=y;
lr=maxlinlr(P,'bias');
net=linearlayer(0,lr);
tic;net=train(net,P,T);toc
new_x=-5:0.2:5;
new_y=sim(net,new_x);
hold on;plot(new_x,new_y);
title('linearlayer用于最小二乘拟合直线');
legend('原始数据点','最小二乘拟合直线');
xlabel('x');ylabel('y');
s=sprintf('y=%f*x+%f',net.iw{1,1},net.b{1,1})
text(-2,-16,s);

%% 8.1手动实现二值逻辑--与
close all;clear;clc;
%定义变量
P=[0,0,1,1;0,1,0,1];
P=[ones(1,length(P));P];
d=[0,0,0,1];
%初始化
w=[0,0,0];%权值向量带偏置的初始化为0向量
lr=maxlinlr(P);%求最大学习率
MAX=200;%迭代上限
%循环迭代
for i=1:MAX
   fprintf('第%d次迭代\n',i);
   v=w*P;%求出输出
   y=purelin(v);
   yy=y>=0.5;   %强模拟输出转化为二值输出,0.5为阈值
   e=d-y;
   m(i)=mse(e);
   fprintf('均方误差:\n',m(i));
   dw=lr*e*P';
   w=w+dw;  %权值向量调整
end
%显示
plot([0,0,1],[0,1,0],'o');hold on;
plot(1,1,'d');
x=-2:.2:2;
y=1.5-x;
plot(x,y);
axis([-0.5,2,-0.5,2]);
xlabel('x');ylabel('y');
title('线性神经网络求解逻辑与');
legend('0','1','分类面');

%% 8.2函数实现二值逻辑--与
close all;clear;clc;
%定义变量
P=[0,0,1,1;0,1,0,1];
d=[0,0,0,1];
lr=maxlinlr(P,'bias');
%线性网络实现
net1=linearlayer(0,lr);
net1=train(net1,P,d);
%感知器实现
net2=newp([-1,1;-1,1],1,'hardlim');
net2=train(net2,P,d);
%显示
disp('线性网络输出');
Y1=sim(net1,P);
disp('线性网络二值输出')
YY1=Y1>=0.5;
disp('线性网络最终权值:');
w1=[net1.iw{1,1},net1.b{1,1}];
disp('感知器输出');
Y2=sim(net2,P);
disp('感知器二值输出');
YY2=Y2>=0.5
disp('感知器最终权值:');
w2=[net2.iw{1,1},net2.b{1,1}];

plot([0,0,1],[0,1,0],'o');
hold on;
plot(1,1,'d');
x=-2:0.2:2;
y1=1/2/w1(2)-w1(1)/w1(2)*x-w1(3)/w1(2);
plot(x,y1,'-');
y2=-w2(1)/w2(2)*x-w2(3)/w2(2);
plot(x,y2,'--');
axis([-0.5,2,-0.5,2]);
xlabel('x');ylabel('y');
title('线性神经网络用于求解逻辑与');
legend('0','1','线性神经网络分类面','感知器分类面');

%% 9.1实现二值逻辑--异或--添加非线性输入--to be continue
%% 9.2实现二值逻辑--异或--使用Madaline--to be continue
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值