RSS
热门关键字:  数据挖掘  数据仓库  人工智能  搜索引擎  数据挖掘导论
当前位置 :| 首页>人工智能>神经网络>

【原创】关于CMAC的编程

来源: 作者: 时间:2008-01-18 点击:

初学CMAC,在网上搜了半天,找到的CMAC程序看起来效果可以的,发现实际上是《先进PID控制MATLAB仿真(第二版)》( 作者:刘金琨 著 出版社:电子工业出版社)P186页的例子。

对该例子进行整理,规划出了几个功能函数。例如,CMAC的网络输出计算函数,程序如下:

function ym=CmacOut(u,M,N,C,w_1,xmin,xmax)%(u(k),y(k),M,N,C,w_1,w_2,xite,alfa,xmin,xmax)
%计算给定权值下CMAC网络的输出
%SISO系统CMAC神经网络的训练函数,本函数是在网上下载例程的基础上修正而来
%在这一次计算中,可以计算出CMAC网络的权值,并可以依据前步w值估算出当前的y值,即ym
%来自于对《先进PID控制MATLAB仿真(第二版)》P186页的例子整理所得结果
%输入参数中,u为网络输入;M为量化系数;N为权向量的个数;C为泛化系数;w_1为权向量的初始值
%xmin和xmax为网络输入参数u的下限和上限
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
w=w_1; %权向量增值的初始值
k=1;

s(k)=round((u(k)-xmin)*M/(xmax-xmin)); %量化,其中xmax为输入u的最大值,
%其中xmin为输入u的最小值 数据挖掘研究院

sum=0;
for i=1:1:C %图形匹配和Hash变换:起始地址
ad(i)=mod(s(k)+i,N)+1; %Table mapping and Hash transfer:Start address
%i=1为C个地址中的起始地址
sum=sum+w(ad(i)); %对起始地址开始的C个连续地址中对应的权值叠加
end

ym(k)=sum; %叠加所得和为网络给出来的估值
ym=ym(k);

CMAC的网络权值更新函数,程序如下:
function w=CmacUpdate(u,err,M,N,C,w_1,w_2,xite,alfa,xmin,xmax)%(u(k),y(k),M,N,C,w_1,w_2,xite,alfa,xmin,xmax)
%依据偏差信号修正CMAC网络的权值
%SISO系统CMAC神经网络的训练函数,本函数是在网上下载例程的基础上修正而来
%在这一次计算中,可以计算出CMAC网络的权值,并可以依据前步w值估算出当前的y值,即ym
%来自于对《先进PID控制MATLAB仿真(第二版)》P186页的例子整理所得结果
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
w=w_1; %权向量增值的初始值
d_w=zeros(length(w),1); %权向量增值的初始值
k=1;
s(k)=round((u(k)-xmin)*M/(xmax-xmin)); %量化,其中xmax为输入u的最大值, 数据挖掘研究院
%其中xmin为输入u的最小值

d_w=xite*err(k)/C; %偏差与系数的乘积,参见42页式2.16

for i=1:1:C
ad(i)=mod(s(k)+i,N)+1; %i=1为C个地址中的起始地址
w(ad(i))=w_1(ad(i))+ d_w+alfa*(w_1(ad(i))-w_2(ad(i))); %权系数的更新
end

%%%% Parameters Update %%%%
w_2=w_1; %权向量的前两次值,进行更新
w_1=w; %权向量的前一次值,进行更新

然后,我发现CMAC的效果远不如例子给出的效果好。我发现书中给出的这个例子实际上是混淆了一个很重要的基本概念。

为了证明我的观点,不妨拿正弦函数为参考模型。
在已经建立前面的CMAC的两个函数后,采用以下程序进行分析和调用

%对CMAC网络的分块实现方法进行仿真
%对《先进PID控制MATLAB仿真(第二版)》P186页的例子整理所得
%这个算法有点问题
clear all;
close all;
%%%%%%%%%%%%%%%%%%%%%%%这部分为函数的参数设置过程%%%%%%%%%%%%%%%%%%%%%%%%
xite=1.5; %y和ym的偏差系数带来的权系数w的更新的比例系数η,参见42页式2.16
alfa=0.05; %权系数的前一步和前两步的变化差带来的比例系数,这个书上没有 数据挖掘研究院
M=1000; %量化时用到的系数
N=700; %权相量的维数,是不是就是A到AP映射的维数?
C=117; %泛化参数
ts=0.001; %采样时间T
xmin=-1.00; %其中xmin为输入u的最小值
xmax=1.00; %xmax为输入u的最大值,
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%采用正弦函数%%%%%%%%%%%%%%%%%%%%%%%%%%%
kk=1:1:755;
time=kk*ts; %计算给定的时间序列:t=kT
u=kk*ts;
y=sin(4*2*pi*u); %依据u和t之间的关系u=sin(4*2*pi*t)计算u的瞬时值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%这里是书中原本的非线性模型的生成过程,很弱智%%%%%
%u_1=0; %输入u(k-1)
%y_1=0; %输出y(k-1)
%for k=1:1:1000
%time(k)=k*ts; %计算给定的时间序列:t=kT
%u(k)=sin(4*2*pi*k*ts); %依据u和t之间的关系u=sin(4*2*pi*t)计算u的瞬时值
%y(k)=u_1^3+y_1/(1+y_1^2); %非线性模型
%u_1=u(k); %输入u(k-1)进行更新
%y_1=y(k); %输入y(k-1)进行更新 数据挖掘研究院
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%这部分为原来函数中与权向量有关的向量的初始化过程%%%%%%%%%%%%%%%
w0=zeros(N,1); %地址空间中对应的权向量的初始值
%w0=1*rands(N,1);
w=w0;
w_1=w0;
w_2=w0;
errvector=zeros(size(u));
for k = 1:1:length(u)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%训练CMAC网络%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%注意这里的输入中有上一次计算出的权向量w%%%%%%%%%%%%%%%%%%
ym(k)=CmacOut(u(k),M,N,C,w_1,xmin,xmax);
err=y(k)-ym(k);
errvector(k) = err;
w=CmacUpdate(u(k),err,M,N,C,w_1,w_2,xite,alfa,xmin,xmax);
%plot(w,"o");grid on
%[w,ym(k)]=buildcmac(u(k),y(k),M,N,C,w_1,w_2,xite,alfa,xmin,xmax); %这一步可以输出估值结果
w_2=w_1; %权向量的前两次值,进行更新
w_1=w; %权向量的前一次值,进行更新
end
%%%%%%%%%%%%%%%%%%%测试CMAC网络的输出结果和真实值之间的对应关系%%%%%%%%%%%%%%%
figure(1);

数据挖掘研究院


subplot(2,2,1)
plot(time,y,"b",time,ym,"r");
xlabel("time(s)");ylabel("y,ym");
grid on
subplot(2,2,2)
plot(time,y-ym,"r");
grid on
xlabel("time(s)");ylabel("delta=y-ym");
%%%%%%%%%%%%%%%%%%%固定权值w,测试网络输出%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%采用正弦函数%%%%%%%%%%%%%%%%%%%%%%%%%%%
%u_1=0; %输入u(k-1)
%y_1=0; %输出y(k-1)
deltak=200;
kk1=(kk(length(kk))-deltak):1"Sad"kk(length(kk))+deltak);
time1=kk1*ts; %计算给定的时间序列:t=kT
u1=kk1*ts;
y1=sin(4*2*pi*u1); %依据u和t之间的关系u=sin(4*2*pi*t)计算u的瞬时值
%y(k)=u_1^3+y_1/(1+y_1^2); %非线性模型
%u_1=u(k); %输入u(k-1)进行更新
%y_1=y(k); %输入y(k-1)进行更新
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k1 = 1:1:length(u1)

数据挖掘实验室


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%训练CMAC网络%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%注意这里的输入中有上一次计算出的权向量w%%%%%%%%%%%%%%%%%%
ym1(k1)=CmacOut(u1(k1),M,N,C,w,xmin,xmax);
%%%%%%%%%%%%%%%%%%%%%%%%%%%计算CMAC网络在给定输入的下的输出%%%%%%%%%%%%%%
%ym(k)=runcmac(u(k),w,M,N,C,xmin,xmax);%这一步多余了
end
%%%%%%%%%%%%%%%%%%%测试CMAC网络的输出结果和真实值之间的对应关系%%%%%%%%%%%%%%%
%figure(1);
subplot(2,2,3)
plot(time1,y1,"b",time1,ym1,"r");
xlabel("time1(s)");ylabel("y1,ym1");
grid on
%axis([time1(1),time1(length(time1)),-1,1])
subplot(2,2,4)
plot(time1,y1-ym1,"r");
grid on
xlabel("time1(s)");ylabel("delta=y1-ym1");
%axis([time1(1),time1(length(time1)),-2,2])
%%%%%%%%%%%%%%%%%%%固定权值w,测试网络输出%%%%%%%%%%%%%%%
figure;
plot(kk,errvector,"k")
hold on
plot(kk,y-ym,"r")
grid on

程序有点长,分得比较细,我现在来一步一步的进行讨论。 数据挖掘研究院
首先是SISO的CMAC的参数设置:%%%%%%%%%%%%%%%%%%%%%%%这部分为函数的参数设置过程%%%%%%%%%%%%%%%%%%%%%%%%
xite=1.5; %y和ym的偏差系数带来的权系数w的更新的比例系数η,参见42页式2.16
alfa=0.05; %权系数的前一步和前两步的变化差带来的比例系数,这个书上没有
M=1000; %量化时用到的系数
N=700; %权相量的维数,是不是就是A到AP映射的维数?
C=117; %泛化参数
ts=0.001; %采样时间T
xmin=-1.00; %其中xmin为输入u的最小值
xmax=1.00; %xmax为输入u的最大值,

然后建立正弦函数模型:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%采用正弦函数%%%%%%%%%%%%%%%%%%%%%%%%%%%
kk=1:1:755;
time=kk*ts; %计算给定的时间序列:t=kT
u=kk*ts;
y=sin(4*2*pi*u); %依据u和t之间的关系u=sin(4*2*pi*t)计算u的瞬时值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

CMAC网络权向量等向量的初始化

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%这部分为原来函数中与权向量有关的向量的初始化过程%%%%%%%%%%%%%%%
w0=zeros(N,1); %地址空间中对应的权向量的初始值 数据挖掘研究院
%w0=1*rands(N,1);
w=w0;
w_1=w0;
w_2=w0;
errvector=zeros(size(u));
for k = 1:1:length(u)

前面一部分的for语句应该是这个部分的

这个部分是对CMAC的输出进行计算,并对权向量进行训练的过程

for k = 1:1:length(u)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%训练CMAC网络%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%注意这里的输入中有上一次计算出的权向量w%%%%%%%%%%%%%%%%%%
ym(k)=CmacOut(u(k),M,N,C,w_1,xmin,xmax);
err=y(k)-ym(k);
errvector(k) = err;
w=CmacUpdate(u(k),err,M,N,C,w_1,w_2,xite,alfa,xmin,xmax);
w_2=w_1; %权向量的前两次值,进行更新
w_1=w; %权向量的前一次值,进行更新
end

上面的errvector只是用来观测误差的变化情况,我发现它并不收敛

现在开始是书中对所建立的CMAC网络的评价效果分析

%%%%%%%%%%%%%%%%%%%测试CMAC网络的输出结果和真实值之间的对应关系%%%%%%%%%%%%%%%
figure(1);
subplot(2,2,1)
plot(time,y,"b",time,ym,"r");
xlabel("time(s)");ylabel("y,ym");

数据挖掘研究院


grid on
subplot(2,2,2)
plot(time,y-ym,"r");
grid on
xlabel("time(s)");ylabel("delta=y-ym");

这个效果分析看起来很不错,大家可以自己做图看看。

但实际上,我发现这个例子纯粹是胡扯,简直是骗人。因为这个例子中所训练的权向量w立即被用来估算下一步u输入时网络的输出。因为步长很小, ts=0.001,只能说明所训练的CMAC网络在有限区间的范围内可以逼近被模拟的对象。为了证明我的观点。准备以下程序:

%%%%%%%%%%%%%%%%%%%固定权值w,测试网络输出%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%采用正弦函数%%%%%%%%%%%%%%%%%%%%%%%%%%%
kk1=(kk(length(kk))-deltak):1:(kk(length(kk))+deltak);
time1=kk1*ts; %计算给定的时间序列:t=kT
u1=kk1*ts;
y1=sin(4*2*pi*u1); %依据u和t之间的关系u=sin(4*2*pi*t)计算u的瞬时值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k1 = 1:1:length(u1)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%训练CMAC网络%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%注意这里的输入中有上一次计算出的权向量w%%%%%%%%%%%%%%%%%%

数据挖掘研究院


ym1(k1)=CmacOut(u1(k1),M,N,C,w,xmin,xmax);

end
%%%%%%%%%%%%%%%%%%%测试CMAC网络的输出结果和真实值之间的对应关系%%%%%%%%%%%%%%%
subplot(2,2,3)
plot(time1,y1,"b",time1,ym1,"r");
xlabel("time1(s)");ylabel("y1,ym1");
grid on
subplot(2,2,4)
plot(time1,y1-ym1,"r");
grid on
xlabel("time1(s)");ylabel("delta=y1-ym1");

上一部分打头漏了点东西:

deltak=200;

这个变量的作用是建立一个范围。以CMAC训练时的最后一个输入值为中心建立起一个范围,这个变量即表现了范围的大小。运行上一部分程序,可以发现,所建立起的CMAC网络实际上只是在很有限的范围内能逼近被跟踪的模型。

通过对这个模型的分析,我发现CMAC并不象传说的那样效果好。

是否很多人都在骗人?无论是书上给出的算法或证明都说其效果如何良好。但实际上并非如此。

有三本书讲的算法与这类似。除了《先进PID控制MATLAB仿真(第二版)》外,还有《非线性自适应逆控制及其应用》(卢志刚等,国防工业出版社),《人工神经网络的模型及其应用》(张立明,复旦大学出版社)。还有许多许多的论文。 数据挖掘研究院

我不知道我错在哪里,还是大家都错了?

Create By Any-Extract(WL-AE) 数据挖掘实验室

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
匿名?