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