SOM神经网络进行模式识别

clc
close all
clear all
X=[1 0 0 0
   1 1 0 0
   1 1 1 0
   0 1 0 0
   1 1 1 1];          % 输入向量

pos=gridtop(5,5);     % 输出层定义为二维5*5的矩阵 %定义25个2维数据,其实是存储了25个神经元的位置信息 
y=boxdist(pos);       % 25*25  y的每一列为第n个神经元到其他神经元的距离,可以搜索距离小于某个值的调整权值
figure(1)
plotsom(pos);         % 画出pos的二维平面图
axis([0 4 0 4]);  % 定义坐标轴为0到4
hold on
w_matrix=rand(25,4);  % 权值随机初始化
dn=zeros(5,25);       % 定义输出神经元之间距离

fid=fopen('Som_Weight.txt', 'wt');%留待下面保存权值
fid2=fopen('Som_Weightanlys.txt','wt');
epoch=10000;%迭代/训练次数


for num=1:epoch     
%--------------------每训练200次记录输出权值,生成txt文件--------------------

    if (num==1)||(rem(num,200)==0)              %rem(x,y)表示的是x除以y后的余数,x,y都是整数;初始值、每200次记录输出权值
        fprintf(fid,'第%d次训练\n',num);         
        fprintf(fid,'\n');  %\n相当于一个回车
     
        for j=1:25
            w_matrix_out=w_matrix(j,1:4);
           % w_anlysis=[w_anlysis;w_matrix(j,1:4)];%分析权值变化用的矩阵,第一行无用,注意作图时舍去
            fprintf(fid2,'%d  %d  %d  %d\n',w_matrix_out);
            w_matrix_out=[j w_matrix_out];
            fprintf(fid,'%d    %d    %d    %d    %d\n',w_matrix_out);%注意:fid1和2里面存的其实是一样的,只是1有换行和描述便于观察,2没有换行利于处理和画图
             
        end
        fprintf(fid,'\n');
    end

%-----------------------------调整学习系数&邻域-----------------------------
    if num<=1000
        lr=(0.04-0.5)/(1000-1)*(num-1)+0.5; %定义1000步以内学习率的调整,从0.5线性下降到0.04
        nf=(0-2)/(1000-1)*(num-1)+2;        %定义1000步以内的邻域调整
        nf=round(nf);                       %邻域取整 
    else
        lr=(0-0.04)/(10000-1000)*(num-1000)+0.04; %定义1000以后的系学习系数,在10000次时降为0
        nf=0;               %1000步以后学习系数在0到0.04之间调整,邻域半径为0%
    end

%-----求输入模式到网络中每一个神经元之间的距离dn,以最小距离者为胜出神经元,并按照经典SOM法调整邻域的权值------
    for ni=1:5      %5类样本
        for no=1:25  %25个输出神经元
          dn(ni,no)=norm(X(ni,:)-w_matrix(no,:));%计算输入样本与相应权值欧氏距离,5个样本中每个样本求其25个神经元中最小距离
        end

        [mindn(ni),Index(ni)]=min(dn(ni,:)); %欧氏距离最小,确定胜出神经元的位置Index(ni):0-24和最小值

        for nS=1:25
            if y(Index(ni),nS)<=nf   %确定邻域内的其他神经元,邻域中的神经元需要调整权值
               w_matrix(nS,:)=w_matrix(nS,:)+lr*(X(ni,:)-w_matrix(nS,:));  %根据通用SOM算法调整权值  
            end
        end   
    end
   handles.weight=w_matrix;   %记录最后的权值%
end
save fid
save fid2
fclose(fid2);
fclose(fid);

for ni=1:5  %5个输入样本
    x2(ni)=floor((Index(ni)-1)/5); %坐标2:0-4
    x1(ni)=rem(Index(ni)-1,5);     %坐标1:0-4
end

plot(pos(1,:),pos(2,:),'og','markersize',10);
hold on;
for ni=1:5
    plot(x1(ni),x2(ni),'.b','markersize',50);%蓝色的大点画出的是5种模式在神经网络中的位置
    text(x1(ni),x2(ni),num2str(ni));
    h=text(x1(ni),x2(ni),num2str(ni));
    str(x1(ni)+1,x2(ni)+1)=get(h,'string');
end
hold on;

Som_Weightanlys=load('Som_Weightanlys.txt');

for j=1:5

        for i=0:50
            w_line=i*25+Index(j);
            n1=Som_Weightanlys(w_line,1);
            n2=Som_Weightanlys(w_line,2);
            n3=Som_Weightanlys(w_line,3);
            n4=Som_Weightanlys(w_line,4);
            x=i*200;
            figure(j+1);
            h1=subplot(2,2,1);
            plot(x,n1,'R*');
            title('输入层神经元与竞争层胜出神经元权值变化');%注意:这里一共只取了5个神经元,也即胜出神经元只有5个(只分5类,也即有5个神经元节点)
            hold on;
            h2=subplot(2,2,2);
            plot(x,n2,'R*');
             hold on;
            h3=subplot(2,2,3);
            plot(x,n3,'R*');
             hold on;
            h4=subplot(2,2,4);
            plot(x,n4,'R*');
             hold on;      
        end
      hold off;
end

%命令行窗口
% while 1
%     data_in = input('请输入测试样本:');
%     if size(data_in) == 1 & data_in==1 
%         break
%     elseif size(data_in,2) == 4 & size(data_in,1)==1
%         for no=1:25  %25 output neurons
%         dnt(no)=norm(data_in-handles.weight(no,:)); %用最后训练完成的权值测试输入样本%
%         end
%        [mindnt,Indext]=min(dnt); %确定胜出神经元的位置
%        xx2=floor((Indext-1)/5); %坐标2:0-4
%        xx1=rem(Indext-1,5);     %坐标1:0-4  %转化为坐标%
%       
%        if xx2 == x2(1) | xx2 == x2(2) | xx2 == x2(3) | xx2 == x2(4) | xx2 == x2(5)
%            if xx1 == xx1(1) | xx2 == xx1(2) | xx1 == xx1(3) | xx1 == x1(4) | xx1 == x1(5)
%            fprintf('该输入的模式为:%s\n',str(xx1+1,xx2+1));%输出为第几类模式%
%            end
%        else fprintf('不属于其中任一模式\n');
%        end
%     else continue
%   end
% end





你可能感兴趣的:(SOM神经网络进行模式识别)