本文主要内容为SOM神经网络原理的介绍,并结合实例给出相应的MATLAB代码实现,方便初学者接触学习,本人才疏学浅,如有纰漏,还望各路大神积极指点。

一、SOM神经网络介绍

自组织映射神经网络, 即Self Organizing Maps (SOM), 可以对数据进行无监督学习聚类。它的思想很简单,本质上是一种只有输入层--隐藏层的神经网络。隐藏层中的一个节点代表一个需要聚成的类。训练时采用“竞争学习”的方式,每个输入的样例在隐藏层中找到一个和它最匹配的节点,称为它的激活节点,也叫“winning neuron”。 紧接着用随机梯度下降法更新激活节点的参数。同时,和激活节点临近的点也根据它们距离激活节点的远近而适当地更新参数。

所以,SOM的一个特点是,隐藏层的节点是有拓扑关系的。这个拓扑关系需要我们确定,如果想要一维的模型,那么隐藏节点依次连成一条线;如果想要二维的拓扑关系,那么就行成一个平面,如下图所示(也叫Kohonen Network):

既然隐藏层是有拓扑关系的,所以我们也可以说,SOM可以把任意维度的输入离散化到一维或者二维(更高维度的不常见)的离散空间上。 Computation layer里面的节点与Input layer的节点是全连接的。

拓扑关系确定后,开始计算过程,大体分成几个部分:

1) 初始化:每个节点随机初始化自己的参数。每个节点的参数个数与Input的维度相同。

2)对于每一个输入数据,找到与它最相配的节点。假设输入时D维的, 即 X={x_i, i=1,...,D},那么判别函数可以为欧几里得距离:

3) 找到激活节点I(x)之后,我们也希望更新和它临近的节点。令S_ij表示节点i和j之间的距离,对于I(x)临近的节点,分配给它们一个更新权重:

简单地说,临近的节点根据距离的远近,更新程度要打折扣。

4)接着就是更新节点的参数了。按照梯度下降法更新:

迭代,直到收敛。

二、问题描述

用26个英文字母作为SOM输入样本。每个字符对应一个5维向量,各字符与向量的关系如表4-2所示。由表4-2可以看出,代表A、B、C、D、E的各向量中有4个分量相同,即,因此,A、B、C、D、E应归为一类;代表F、G、H、I、J的向量中有3个分量相同,同理也应归为一类;依此类推。这样就可以由表4-2中输入向量的相似关系,将对应的字符标在图4-8所示的树形结构图中。用SOM网络对其他进行聚类分析。

三、MATLAB代码实现

SOM_mian.m

%%% 神经网络之自组织网络SOM练习
%%%作者:xd.wp
%%%时间:2016.10.02 19:16
%% 程序说明:
%%%          1、本程序中,输出层为二维平面,
%%%          2、几何邻域确定及调整权值采用exp(-distant^2/delta^2)函数
%%%          3、样本维数为5,输出层结点为70
%%%          4、输入数据,归一化为单位向量
clear all;
clc;
%% 网络初始化及相应参数初始化
%加载数据并归一化
[train_data,train_label]=SOM_data_process();
data_num=size(train_data,2);%权值初始化
% weight_temp=ones(5,70)/1000;
weight_temp=rand(5,70)/1000;%结点个数
node_num=size(weight_temp,2);%权值归一化
for i=1:node_numweight(:,i)=weight_temp(:,i)/max(weight_temp(:,i));
end%邻域函数参数
delta=2;%调整步幅
alpha=0.6;
%% Kohonen算法学习过程
for t=4:-1:1                                    %%总体迭代次数index_active=ones(1,node_num);              %%结点活跃标志for n=1:data_num                            %%每个样本的输入% 竞争部分,根据最小距离确定获胜神经元[j_min]=SOM_compare(weight,train_data(:,n),node_num,index_active);%去激活,确保数据结点1对1映射index_active(1,j_min)=0;%为后续绘图部分服务index_plot(1,n)=j_min;[x,y]=line_to_array(j_min);fprintf('坐标[%d,%d]处为字符%s \n',x,y,train_label(1,n));% 学习部分网络权值调整st=num2str(t-1);switch   stcase '3'[weight]=SOM_neighb3(weight,train_data(:,n),j_min,delta,alpha);case '2'[weight]=SOM_neighb2(weight,train_data(:,n),j_min,delta,alpha);case '1'[weight]=SOM_neighb1(weight,train_data(:,n),j_min,delta,alpha);otherwise[weight]=SOM_neighb0(weight,train_data(:,n),j_min,alpha);endend
end
%% 绘制结点分布图像
figure(1);
for n=1:data_num[x,y]=line_to_array(index_plot(1,n));axis([0,12,0,12]);text(x,y,'*');text(x+0.2,y+0.2,train_label(1,n));hold on;
end

SOM_data_process.m

function [train_data,train_label]=SOM_data_process()
train_data=[1 0 0 0 0;2 0 0 0 0;3 0 0 0 0;4 0 0 0 0;5 0 0 0 0;3 1 0 0 0;3 2 0 0 0;3 3 0 0 0;3 4 0 0 0;3 5 0 0 0;3 3 1 0 0;3 3 2 0 0;3 3 3 0 0;3 3 4 0 0;3 3 5 0 0;3 3 3 1 0;3 3 3 2 0;3 3 3 3 0;3 3 3 4 0;3 3 3 5 0;3 3 3 3 1;3 3 3 3 2;3 3 3 3 3;3 3 3 3 4;3 3 3 3 5;3 3 3 3 6];
train_label=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6'];
train_data=train_data';
length=size(train_data,2);
for i=1:lengthtrain_data(:,i)=train_data(:,i)/sqrt(sum(train_data(:,i).*train_data(:,i)));
% train_data(:,i)=train_data(:,i)/max(train_data(:,i));
end
end

SOM_compare.m

function [j_min]=SOM_compare(weight,train_data_active,node_num,index_active)
for j=1:node_numdistant(j,1)=sum((weight(:,j)-train_data_active).^2);
end
[~,j_min]=min(distant);
while(index_active(1,j_min)==0)distant(j_min,1)=10000000;[~,j_min]=min(distant);
endend

SOM_neighb3.m

function [weight]=SOM_neighb3(weight,train_data_active,j_min,delta,alpha)%% 权值调整幅度分布
%                          -0.2
%                           0.2
%                           0.6
%        -0.2   0.2   0.6    1    0.6   0.2   -0.2
%                           0.6
%                           0.2
%                          -0.2
% 单位距离转化比例为0.4
%% 坐标转换
[x,y]=line_to_array(j_min);
% 将1*70向量中的坐标转化为7*10矩阵中的坐标
%    1   8    ···
%    7   14   ···%% 权值调整过程
%结点靠上边情况
if (x<=3)for m=1:1:x+3if (y<=3)          %结点靠左边for n=1:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=8)      %结点靠右边for n=y-3:1:10distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-3:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend%结点靠下边情况
elseif (x>=5)for m=x-3:1:7if (y<=3)          %结点靠左边for n=1:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=8)      %结点靠右边for n=y-3:1:10distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-3:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend%结点正好在中间
elsefor m=1:7if (y<=3)          %结点靠左边for n=1:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=8)      %结点靠右边for n=y-3:1:10distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-3:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend
end
end

SOM_neighb2.m

function [weight]=SOM_neighb2(weight,train_data_active,j_min,delta,alpha)%% 权值调整幅度分布
%                          -0.2
%                           0.2
%                           0.6
%        -0.2   0.2   0.6    1    0.6   0.2   -0.2
%                           0.6
%                           0.2
%                          -0.2
% 单位距离转化比例为0.4
%% 坐标转换
[x,y]=line_to_array(j_min);
% 将1*70向量中的坐标转化为7*10矩阵中的坐标
%    1   8    ···
%    7   14   ···%% 权值调整过程
%结点靠上边情况
if (x<=2)for m=1:1:x+2if (y<=2)          %结点靠左边for n=1:1:y+2distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=9)      %结点靠右边for n=y-2:1:10distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-2:1:y+2distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend%结点靠下边情况
elseif (x>=6)for m=x-2:1:7if (y<=2)          %结点靠左边for n=1:1:y+2distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=9)      %结点靠右边for n=y-2:1:10distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-2:1:y+2distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend%结点正好在中间
elsefor m=x-2:1:x+2if (y<=2)          %结点靠左边for n=1:1:y+2distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=9)      %结点靠右边for n=y-2:1:10distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-2:1:y+2distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend
end
end

SOM_neighb1.m

function [weight]=SOM_neighb1(weight,train_data_active,j_min,delta,alpha)%% 权值调整幅度分布
%                          -0.2
%                           0.2
%                           0.6
%        -0.2   0.2   0.6    1    0.6   0.2   -0.2
%                           0.6
%                           0.2
%                          -0.2
% 单位距离转化比例为0.4
%% 坐标转换
[x,y]=line_to_array(j_min);
% 将1*70向量中的坐标转化为7*10矩阵中的坐标
%    1   8    ···
%    7   14   ···%% 权值调整过程
%结点靠上边情况
if (x<=1)for m=1:1:x+1if (y<=1)          %结点靠左边for n=1:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=10)      %结点靠右边for n=y-1:1:10distant=sqrt((x-m)^2+(y-n)^2);
weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-1:1:y+1distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend%结点靠下边情况
elseif (x>=7)for m=x-3:1:7if (y<=1)          %结点靠左边for n=1:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=10)      %结点靠右边for n=y-1:1:10distant=sqrt((x-m)^2+(y-n)^2);
weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-1:1:y+1distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend%结点正好在中间
elsefor m=x-1:1:x+1if (y<=1)          %结点靠左边for n=1:1:y+3distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelseif (y>=10)      %结点靠右边for n=y-1:1:10distant=sqrt((x-m)^2+(y-n)^2);
weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endelsefor n=y-1:1:y+1distant=sqrt((x-m)^2+(y-n)^2);weight(:,(n-1)*7+m)=weight(:,(n-1)*7+m)-alpha*exp(-distant^2/delta^2)*(weight(:,(n-1)*7+m)-train_data_active);endendend
end
end

SOM_neighb0.m

function [weight]=SOM_neighb0(weight,train_data_active,j_min,alpha)
weight(:,j_min)=weight(:,j_min)+alpha*(weight(:,j_min)-train_data_active);
end

line_to_array.m

function [x,y]=line_to_array(j_min)
% 将1*70向量中的坐标转化为7*10矩阵中的坐标
%    1   8    ···
%    7   14   ···
y=ceil(j_min/7);
x=rem(j_min,7);
end

四、结果显示

不同初始条件的结果图

自组织神经网络SOM原理——结合例子MATLAB实现相关推荐

  1. 自组织神经网络SOM——MATLAB

    Kohonen网络的拓扑结构 下图是1维和2维的两个SOM网络示意图. 网络上层为输出结点(假设为m个),按二维形式排成一个结点矩阵. 输入结点处于下方,若输入向量由n个元素,则输入端共有n个结点. ...

  2. 自组织神经网络SOM算法对Iris数据集进行聚类的matlab实现

    SOM算法原理 SOM算法是一种将高维数据通过两层神经网络(输入层和竞争层)映射至用户定义的拓扑结构中,一般常用2D矩阵拓扑结构.下图是对SOM的形象展示: 所以算法一般分为以下几步: 第一:用户自定 ...

  3. 递归神经网络LSTM原理——结合实例MATLAB实现

    最近正在看递归神经网络,看了网上很多博文,算是鱼龙混杂,并且基本都是使用Python实现,要不就是使用Matlab中的函数库等.对于使用Matlab的同学,甚为不方便.所以我将结合实例,使用matla ...

  4. 人工神经网络的算法原理,深度神经网络工作原理

    AI是否可以被精神分析?人工智能运行的基础原理到底是什么? AI不可以被精神分析,人工智能的工作原理是,计算机使用传感器(或人工输入),将收集有关一个场景的事实.计算机将把这些信息与已经存储的信息进行 ...

  5. MATLAB机器学习系列-6 竞争神经网络与SOFM(SOM)神经网络原理及其例子代码

    竞争神经网络 结构上和RBF等网络是比较像的.这里的距离是负数距离,||ndist||中带一个n,表示negative.在matlab中计算方法是ngedist. 它的计算过程是:待分类样本输入后,和 ...

  6. SOM自组织神经网络

    SOM自组织神经网络是神经网络的一种.个人感觉属于仿生学的一种方法.这种网络是基于生理学和脑科学研究成果提出的.与前向神经网络不同,它是一种无监督的学习.适用于数据聚类. 应用:数据聚类,数据降维(如 ...

  7. 神经网络算法原理图解,神经网络算法原理图集

    神经网络算法原理 一共有四种算法及原理,如下所示:1.自适应谐振理论(ART)网络自适应谐振理论(ART)网络具有不同的方案.一个ART-1网络含有两层一个输入层和一个输出层. 这两层完全互连,该连接 ...

  8. 神经网络算法基本介绍,简单神经网络算法原理

    神经网络是什么? 生物神经网络主要是指人脑的神经网络,它是人工神经网络的技术原型. 人脑是人类思维的物质基础,思维的功能定位在大脑皮层,后者含有大约10^11个神经元,每个神经元又通过神经突触与大约1 ...

  9. 机器学习(二)——竞争神经网络-SOM

    竞争神经网络(无导师学习) 竞争型神经网络是基于无监督学习(Unsupervised learning)方法的神经网络的一种重要类型,它经常作为基本的网络形式,构成其它一些具有自组织能力的网络,如自组 ...

最新文章

  1. Android Studio添加代码头注释使用
  2. 批量更新日期字段中的年
  3. Mybaits 运行原理流程图
  4. MVC, MVP, MVVM比较以及区别(下)
  5. 实现Profile购物车的匿名用户迁移
  6. Android Service被系统回收的解决方法
  7. 领悟非凡,只有西方人才能做出来的效果。。。不是技术,而是人文和胸怀
  8. 子网规划与组网实验_交换机四种组网方式,你都清楚吗
  9. linux fstab 权限,linux中fstab文件配置简介
  10. java如何实现游戏暂停和恢复_Android:游戏循环暂停/恢复问题
  11. UDP实现简单的超时重传
  12. 南大计算机专业考研2019分数,南京大学2019考研分数线公布
  13. 微信小程序人脸识别认证-微信开放接口
  14. catia v5法矢数据软件_CATIA V5 Start Model车身建模
  15. 什么是微信WXID数据?
  16. [TransactionInterceptor] [ERROR] Applicationexception overridden by rollback exception
  17. bch verilog代码_BCH源码学习笔记 | 第一步:搭建BCH的源码学习环境
  18. C++ priority_queue的使用及模拟实现
  19. 通过X11转发在服务器上用IGV
  20. python回测代码_python实现马丁策略回测3000只股票的实例代码

热门文章

  1. Button节流、防抖
  2. 企业微信开发:使用 JS-SDK 实现图像接口功能(六)
  3. 【redis】详解布隆过滤器BloomFilter的原理,使用场景和注意事项
  4. python加权最小二乘_用Python实现最小二乘算法
  5. 如何解决eclipse乱码问题?
  6. Radiology第12期:淋巴系统及其相关疾病的成像和干预
  7. win10本地利用docker搭建FATE【快速方法】
  8. redis的set数据类型相关命令介绍及使用
  9. 二进制颜色代码大全(含图)透明度与十六进制代码转换
  10. Python数据分析数据预处理特征值独热编码