天天看點

實驗2 som網實驗

傳送門(所有的實驗都使用python實作)

​​實驗1 BP神經網絡實驗​​

​​實驗2 som網實驗​​

​​實驗3 hopfield實作八皇後問題​​

​​實驗4 模糊搜尋算法預測薄冰厚度​​

​​實驗5 遺傳算法求解tsp問題​​

​​實驗6 蟻群算法求解tsp問題​​

​​實驗7 粒子群優化算法求解tsp問題​​

​​實驗8 分布估計算法求解背包問題​​

​​實驗9 模拟退火算法求解背包問題​​

​​實驗10 禁忌搜尋算法求解tsp問題​​

一、實驗目的

    了解使用som算法

二、實驗内容

(描述實驗任務)

試設計一個具有5*5神經元平面陣的SOM網,建議學習率(t)在前1000步訓練中從0.5線性下降至0.04,然後在訓練到10,000步時減小至0。優勝鄰域半徑初值設為2個節點(即優勝鄰域覆寫整個輸出平面),1000個訓練步時減至0(即隻含獲勝節點)。每訓練200步保留一次權向量,觀察其在訓練過程中的變化。給出訓練結束後,5個輸入模式在輸出平面的映射圖。

三、實驗環境

(描述實驗的軟體、硬體環境)

使用Python3.0 在 eclipse進行編輯

四、實驗步驟

(描述實驗步驟及中間的結果或現象。在實驗中做了什麼事情,怎麼做的,發生的現象和中間結果)

經過疊代學習10000次,得到的權重矩陣如下:

實驗2 som網實驗

畫圖的結果如下:

未進行歸一化所畫的圖

實驗2 som網實驗

歸一化之後畫的圖

實驗2 som網實驗

五、總結

# -*- 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)     #歸一化之後畫出的圖