傳送門(所有的實驗都使用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次,得到的權重矩陣如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CO0QTM1MjMiNTNyYGMiZGNzYzX2IDMxYTM5EzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
畫圖的結果如下:
未進行歸一化所畫的圖
歸一化之後畫的圖
五、總結
# -*- 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) #歸一化之後畫出的圖