matlab2019a
CMAC最大特点是局部逼近,因此它具有特殊的结构。
如上图,假设输入是二维,即X=(x1,x2)X=(x1,x2),x1,x2∈[0,5]x1,x2∈[0,5](即使不是也可以先标准化,[0,5][0,5]不是固定的,可以是其他,本文只是为了好理解而使用这个范围)。
(1)每一维的输入xixi都具有层mm和块nbnb的概念(注意,这个层的意思和一般神经网络层的意思不一样)。在图中Tier是层的意思,也就是每一维具有m=4m=4层,每层有nb=2nb=2块,例如第一层Tier1具有两个块A、B。根据mm和nbnb确定每一维等分切片的个数,即m⋅(nb−1)+1m⋅(nb−1)+1,例如上图中,每维被切分为4*(2-1)+1=5等份。
(2)输入的维度之间,相同的层所激活的块联合起来对应一个权值地址空间。如上图,当前X=(3.5,3.3)X=(3.5,3.3),x1x1在不同层激活的块是B、D、F、G,x2x2是b、d、f、g,此时所对应的权值索引是Bb、Dd、Ff、Gg,把这4个权值加起来就是输出。由此可以看出,有多少层就激活多少个权值。同时,不存在同维度块联合、不同维度不同层块联合的情况,也就是说不存在AB、AC、Ad等情况。由此算来,可能使用到的权值个数为m⋅nbnm⋅nbn,nn为输入的维度。
(4)一般CMAC网络的整体构架如下图,第一层是输入层;第二层是虚拟联想空间,即对应上图的Aa、Ab、Ba、Bb……;第三层是物理存储空间,即根据第二层给出的索引找到对应的权值;第四层即输出层。
(5)如果输入维度很大,根据m⋅nbnm⋅nbn,权值个数指数增长,然而也许只有少部分的权值被使用(有些权值从来没被激活),所以可以使用哈希表方法存储权值,减小无用空间的开支。
(6)权值更新公式为
wt+1=wt+α/m⋅ewt+1=wt+α/m⋅e
αα为学习率,mm是层的个数,ee为样本真值与网络预测的误差,只有激活的权值被更新。其实可以把mm拿掉,看成使用一般神经网络的梯度下降法。
function [Weight,Error,Ypre2] = func_CMAC_train(x,y,Iters,Learn_rate,Goals);
[R,C] = size(x);
%最小值
Vmin = 0*ones(1,C);
%最大值
Vmax = 1*ones(1,C);
%位数
Xwidth = numel(x(:,1));
%量化
Qlen = 200;
%S空间
S_space = [1:Qlen];
%用于训练的样本个数
kk = 1;
Len_train = kk*R;
%误差
Error = [];
%状态关联单元个数
Nuints1 = 7;
%相同关联单元个数
Nuints2 = 4;
%总关联单元数
Nuints_all= Qlen*Nuints1-(Qlen-1)*Nuints2;
%权值
Weight = zeros(C,Nuints_all);
%获取训练样本
P_train=zeros(Len_train,C);
T_train=zeros(Len_train,1);
for i=1:Len_train
P_train(i,:) = x(floor((i-1)*Xwidth/Len_train+1),:);
T_train(i) = y(floor((i-1)*Xwidth/Len_train+1));
end
%训练
for i=1:Iters
i
for j=1:Len_train
%量化S空间
for jj = 1:C
S_idx = floor((P_train(j,jj)-Vmin(jj))/(Vmax(jj)-Vmin(jj))*(Qlen-1)) + 1;
W_idx(jj) = (S_idx-1)*(Nuints1-Nuints2)+1;
%输出
T_predict(jj,j) = sum(Weight(jj,W_idx(jj):W_idx(jj)+Nuints1-1));
end
for jj = 1:C
%CMAC权值更新
for k=W_idx(jj):W_idx(jj)+Nuints1-1
Weight(jj,k) = Weight(jj,k) + P_train(j,jj)/sum(P_train(j,:))*Learn_rate * (T_train(j)-sum(T_predict(:,j)));
end
end
end
error = 0;
for j=1:Len_train
error = error + abs(T_train(j)-sum(T_predict(:,j)));
Ypre(j) = sum(T_predict(:,j));
end
Error(i)=error;
end
Ypre2=Ypre(1:kk:end);
function Y_cmac2 = func_CMAC_test(x,Weight);
[R,C] = size(x);
%位数
Xwidth = numel(x(:,1));
Vmin = 0*ones(1,C);
Vmax = 1*ones(1,C);
%量化等级
Qlen = 200;
Nuints1= 7;
Nuints2= 4;
for i=1:Xwidth
for jj = 1:C
S_space = floor((x(i,jj)-Vmin(jj))/(Vmax(jj)-Vmin(jj))*(Qlen-1))+1;
W_space =(S_space-1)*(Nuints1-Nuints2)+1;
Y_cmac(jj,i) = sum(Weight(jj,W_space:W_space+Nuints1-1));
end
Y_cmac2(i) = sum(Y_cmac(:,i));
end
[1]施光林, 沈伟. 气动人工肌肉并联平台自适应模糊CMAC姿态跟踪控制[J]. 中国机械工程, 2012, 23(2):6.A05-74