传送门(全部的实验都使用python实现)python
实验5 遗传算法求解tsp问题eclipse
实验9 模拟退火算法求解背包问题.net
1、实验目的
了解使用som算法
2、实验内容
(描述实验任务)
试设计一个具备5*5神经元平面阵的SOM网,建议学习率(t)在前1000步训练中从0.5线性降低至0.04,而后在训练到10,000步时减少至0。优胜邻域半径初值设为2个节点(即优胜邻域覆盖整个输出平面),1000个训练步时减至0(即只含获胜节点)。每训练200步保留一次权向量,观察其在训练过程当中的变化。给出训练结束后,5个输入模式在输出平面的映射图。
3、实验环境
(描述实验的软件、硬件环境)
使用Python3.0 在 eclipse进行编辑
4、实验步骤
(描述实验步骤及中间的结果或现象。在实验中作了什么事情,怎么作的,发生的现象和中间结果)
通过迭代学习10000次,获得的权重矩阵以下:
画图的结果以下:
未进行归一化所画的图
归一化以后画的图
5、总结
(说明实验过程当中遇到的问题及解决办法;新发现或我的的收获;未解决/需进一步研讨的问题或建议新实验方法等)
对于python3,没有自带的numpy和pylab控件,要本身去下载安装包有点麻烦。输出层若是设置的点数过多会致使颜色不够用,在点数太少的状况下,输出的图归一化不明显。
python源码
# -*- coding: UTF-8 -*- import numpy as np import pylab as pl def draw(C): #画图函数 colValue = ['r', 'y', 'g', 'b', 'c', 'k', 'm'] for i in range(len(C)): coo_X = [] coo_Y = [] for j in range(len(C[i])): coo_X.append(C[i][j][0]) coo_Y.append(C[i][j][1]) pl.scatter(coo_X, coo_Y, marker='x', color=colValue[i % len(colValue)], label=i) pl.legend(loc='upper right') pl.show() class myson(object): def __init__(self, X, output, times, size): self.X = X #输入样例 self.output = output #输出 self.times = times #迭代次数 self.size = size #数据长度 self.W = np.random.rand(X.shape[1], output[0] * output[1]) print(self.W.shape) def reE(self, t, n): return np.power(np.e, -n) / (t + 2) def reN(self, t): # 返回拓扑距离 a = min(self.output) return int(a - float(a) * t / self.times) def nei(self, index, N): #肯定获胜区域点 a, b = self.output length = a * b def dis(index1, index2): #计算距离 i1_a, i1_b = index1 // a, index1 % b i2_a, i2_b = index2 // a, index2 % b return np.abs(i1_a - i2_a), np.abs(i1_b - i2_b) def upW(self, X, t, winner): #更新权值 N = self.reN(t) for x, i in enumerate(winner): to_update = self.nei(i[0], N) for j in range(N + 1): e = self.reE(t, j) for w in to_update[j]: self.W[:, w] = np.add(self.W[:, w], e * (X[x, :] - self.W[:, w])) ans = [set() for i in range(N + 1)] for i in range(length): dist_a, dist_b = dis(i, index) if dist_a <= N and dist_b <= N: ans[max(dist_a, dist_b)].add(i) #将获胜节点加入集合 return ans def train(self): #训练函数 count = 0 while self.times > count: train_X = self.X[np.random.choice(self.X.shape[0], self.size)] normal_W(self.W) normal_X(train_X) train_Y = train_X.dot(self.W) winner = np.argmax(train_Y, axis=1).tolist() self.upW(train_X, count, winner) count += 1 return self.W def af_train(self): #返回训练结果 normal_X(self.X) train_Y = self.X.dot(self.W) winner = np.argmax(train_Y, axis=1).tolist() print(winner) return winner def normal_X(X): #输入归一化处理 N, D = X.shape for i in range(N): temp = np.sum(np.multiply(X[i], X[i])) X[i] /= np.sqrt(temp) return X def normal_W(W): #初始权值归一化处理 for i in range(W.shape[1]): temp = np.sum(np.multiply(W[:, i], W[:, i])) W[:, i] /= np.sqrt(temp) return W if __name__ == '__main__': data = """1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1;""" a = data.split(',') dataset = np.mat([[float(a[i]), float(a[i + 1]),float(a[i+2]),float(a[i+3]),] for i in range(0, len(a) - 1, 4)]) dataset_old = dataset.copy() myson = myson(dataset, (5, 5), 1,5) myson.train() res = myson.af_train() classify = {} for i, win in enumerate(res): if not classify.get(win[0]): classify.setdefault(win[0], [i]) else: classify[win[0]].append(i) A = [] # 未归一化的数据分类结果 B = [] # 归一化的数据分类结果 for i in classify.values(): A.append(dataset_old[i].tolist()) B.append(dataset[i].tolist()) draw(A) #未归一化画出的图 draw(B) #归一化以后画出的图