【机器学习】竞争神经网络(Competitive Neural Network)的python实现
一、竞争神经网络原理1.1、生物学原理1.2、网络结构与模型训练二、竞争神经网络的python实现参考资料我们前面介绍过基于机器学习的分类与回归,分类与回归都是监督学习。除此之外,机器学习还有一个广泛的应用是聚类,聚类算法是无监督的机器学习算法,数据样本只有特征而没有标签,我们需要根据样本的特征将具有相似特征的样本划分到同一个类别中。本博文介绍竞争神经网络(Competitive Neural Network),它是一种模仿人眼视网膜神经细胞相互作用的聚类算法(参考资料【1】)。
一、竞争神经网络原理
1.1、生物学原理
生物神经网络存在一种侧抑制的现象,即一个神经细胞兴奋后,通过它的分支会对周围其他神经细脑产生抑制,这种抑制使神经细胞之间出现竞争:在开始阶段,各神经元对相同的输入具有相同的响应机会,但产生的兴奋程度不同,其中兴奋最强的一个神经细胞对周围神经细胞的抑制作用也最强,从而使其它神经元的兴奋得到最大程度的抑制,而兴奋最强的神经细胞却“战胜”了其它神经元的抑制作用脱颖而出,成为竞争的胜利者,并因为获胜其兴奋的程度得到进一步加强,正所谓“成者为王,败者为寇”(参考资料【2】)。
1.2、网络结构与模型训练
竞争神经网络结构如下图:
如上图所示,竞争神经网络是个两层的网络结构。假设样本X={Xi=(xi1,xi2,⋯ ,xin)}i=1,2,⋯ ,MX = {\left\{ {{X_i} = \left( {x{}_{i1},{x_{i2}}, \cdots ,{x_{in}}} \right)} \right\}_{i = 1,2, \cdots ,M}}X={Xi=(xi1,xi2,⋯,xin)}i=1,2,⋯,M,样本特征数为nnn,聚类类别个数为NNN。
输入层:节点个数等于样本特征数,每次输入每一个样本。
输出层:节点个数等于聚类类别个数,数值最大的输出节点的指针就是样本的类别。
输入层到输出层的权值矩阵WWW由NNN个权值向量组成,每个权值向量长度为nnn。所以对于样本XiX_iXi,网络的输出是:
ON×1=WN×nXi{O_{N \times 1}} = {W_{N \times n}}{X_i}ON×1=WN×nXi
网络输出ON×1O_{N \times 1}ON×1中的最大元素是在竞争中获胜的神经元(神经元j∈[1,2,⋯ ,N]j \in \left[ {1,2, \cdots ,N} \right]j∈[1,2,⋯,N]),对应的权值向量更新公式如下:
Wj(k)=Wj(k−1)+α[Xi−Wj(k−1)]{W_j}(k) = {W_j}(k - 1) + \alpha \left[ {{X_i} - {W_j}(k - 1)} \right]Wj(k)=Wj(k−1)+α[Xi−Wj(k−1)]
学习规则通过输入向量进行神经元权值的调整,因此在模式识别的应用中是很有用的。通过学习,那些最靠近输入向量的神经元权值向量被修正,使之更靠近,其结果是获胜的神经元在下一次相似的输入向量出现时,获胜的可能性会更大;而对于那些相差很远的输入向量,获胜的可能性将变得很小。
二、竞争神经网络的python实现
python代码与样本地址:/shiluqiang/Competitive-Neural-Network
代码参考资料【3】
import numpy as np# 导入数据def load_data(path):'''导入数据input: path(string)文件的存储位置output: data(array)特征'''f = open(path) # 打开文件data = []for line in f.readlines():lines = line.strip().split("\t")data_tmp = []for i in range(len(lines)):data_tmp.append(float(lines[i]))data.append(data_tmp)f.close() # 关闭文件return datadef sigmoid(x):'''sigmoid激活函数'''return 1/(1+np.exp(-x))def normalization(M):"""对行向量进行归一化:param M:行向量:【dim=len(M)】:return: 归一化后的行向量M"""M=M/np.sqrt(np.dot(M,M.T))return Mdef normalization_all(N):"""对矩阵进行归一化:param N: 矩阵:return: 归一化后的矩阵M_all"""M_all=[]for i in range(len(N)):K=normalization(N[i])M_all.append(K)return M_allclass competitive_network(object):def __init__(self,x_dim,output_num,a):'''类参数初始化'''W = np.random.rand(output_num,x_dim) * (-2) + 1self.W = normalization_all(W)self.a = a ## 权值更新参数def forward_propagation(self,x):'''前向传播input:self(object):类参数x(mat):一个训练样本output:argmax(int):被激活的权重向量指针'''z_layer=np.dot(self.W,x.T) ##矩阵相乘a_layer=sigmoid(z_layer) argmax= np.argmax(a_layer)return argmax,a_layerdef back_propagation(self,argmax,x):'''反向传播调整权重input:argmax(int):被激活的权重向量指针x(mat):一个训练样本'''self.W[argmax] = self.a * (x - self.W[argmax])self.W[argmax]=normalization(self.W[argmax])self.a-=self.decaydef train(self,X,num_iter):'''模型训练input:X(mat):全部训练样本num_iter(int):迭代次数'''X=np.array(X)self.decay=self.a / num_iterfor item in range(num_iter):for i in range(X.shape[0]):argmax=self.forward_propagation(X[i])self.back_propagation(argmax,X[i])def prediction(self,X_test):'''预测样本的类别input:self(object):类X_test(mat):测试样本output:predict_class(list):样本类别'''sample_num = np.shape(X_test)[0]predict_results = []for i in range(sample_num):predict_result = self.forward_propagation(X_test[i])predict_results.append(predict_result)return predict_resultsif __name__ == '__main__':print('---------------------1.Load Data---------------------')data = load_data('data')dataMat = np.mat(data)print('------------------2.Parameters Seting----------------')num_iter = 1000x_dim = np.shape(dataMat)[1]output_num = 2a = 0.3print('-------------------3.Model Train---------------------')cnn = competitive_network(x_dim,output_num,a)cnn.train(dataMat,num_iter)print('-------------------4.Prediction----------------------')predict_results = cnn.prediction(dataMat)
参考资料
1、/heifan/article/details/71076608
2、/guoyunlei/article/details/76935256
3、/qq_36389843/article/details/78806012