www.pudn.com > zzznet.rar > Som.m, change:2007-01-09,size:2760b


function Weight=Som(Sam,Nlong,Nwide,ITER) 
% 输入样本为 Sam , 样本数目为 N_sam 
% 权向量为 Weight , 权向量数目为 N_w 
% 样本为 N 维 
% 采用欧氏距离 
 
% ************************************************************************* 
% 算法分析:由于样本采用了归一化,则分类器只对角度起作用,对于尺度上的变化无法区分 
% 初始权值是从样本中随机选择的,这样可以加快收敛速度,解决了不知道样本分布带来的麻烦 
% ************************************************************************* 
 
% ************************************************************************* 
%  设置竞争层的结点分布,假设竞争层的结点构成一个矩形(Nlong*Nwide),并将直线分布看作是矩形分布的特殊情况 
%  用向量数组来表示逻辑上表示矩形 
% ************************************************************************* 
 
N_w=Nlong*Nwide; 
[N,N_sam]=size(Sam); 
 
% ************************************************************************* 
%  初始化(样本、权值归一化;设置学习率变化函数和邻域变化函数以及二者的初始值) 
% ************************************************************************* 
 
ita0=0.7;                                          % 初始学习率 
         % Weight=randn(N,N_w);                               % 随机生成初始权向量 
         % Weight=Weight./(ones(N,1)*sqrt(sum(Weight.^2)));   % 初始权向量归一化 
Sam=Sam./(ones(N,1)*sqrt(sum(Sam.^2)));           % 样本归一化 
Weight=zeros(N,N_w); 
sel=randperm(N_sam); 
sel1=sort(sel(1:N_w)); 
Weight=Sam(:,sel1); 
ita=ita0*(1-[1:ITER]/ITER); 
 
areaLong0=Nlong/2; 
areaWide0=Nwide/2; 
areaL=floor(areaLong0*(1-[1:ITER]/ITER));     % 每次迭代的初始范围长设置 
areaW=floor(areaWide0*(1-[1:ITER]/ITER));     % 每次迭代的初始宽设置 
if(Nwide==1) 
    areaW=zeros(1,ITER);                           % 若是只有一行的竞争层,权值变化只在行方向变化 
end 
 
i=1; 
while(i<ITER) 
    for j=1:N_sam  
        [maxDot,maxTab]=max(Weight'*Sam(:,j));     % 竞争层排列行方向为 Nlong,列方向为 Nwide,且权值按照先行后列的顺序 
        centerL=mod(maxTab,Nlong); 
        centerW=ceil(maxTab/Nlong); 
        L_left=centerL-areaL(i); 
        L_right=centerL+areaL(i); 
        W_up=centerW-areaW(i); 
        W_down=centerW+areaW(i); 
        if(L_left<1) 
            L_left=1; 
        end 
        if(L_right>Nlong) 
            L_right=Nlong; 
        end 
        if(W_up<1) 
            W_up=1; 
        end 
        if(W_down>Nwide) 
            W_down=Nwide; 
        end 
        for m=W_up:W_down                                    % 校正并归一化新的权重系数 
            for n=L_left:L_right 
                tran=[Weight(:,(m-1)*Nlong+n)]; 
                tran=tran+ita(i)*(Sam(:,j)-tran); 
                Weight(:,(m-1)*Nlong+n)=tran/norm(tran);                               
            end 
        end 
    end 
    i=i+1; 
end