实验2 som网实验

传送门(全部的实验都使用python实现)python

实验1 BP神经网络实验算法

实验2 som网实验网络

实验3 hopfield实现八皇后问题app

实验4 模糊搜索算法预测薄冰厚度dom

实验5 遗传算法求解tsp问题eclipse

实验6 蚁群算法求解tsp问题函数

实验7 粒子群优化算法求解tsp问题学习

实验8 分布估计算法求解背包问题优化

实验9 模拟退火算法求解背包问题.net

实验10 禁忌搜索算法求解tsp问题

 

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)     #归一化以后画出的图