欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python實(shí)現(xiàn)SOM算法

 更新時(shí)間:2018年02月23日 09:01:46   作者:_almost_  
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)SOM算法,聚類算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

算法簡(jiǎn)介

SOM網(wǎng)絡(luò)是一種競(jìng)爭(zhēng)學(xué)習(xí)型的無監(jiān)督神經(jīng)網(wǎng)絡(luò),將高維空間中相似的樣本點(diǎn)映射到網(wǎng)絡(luò)輸出層中的鄰近神經(jīng)元。

訓(xùn)練過程簡(jiǎn)述:在接收到訓(xùn)練樣本后,每個(gè)輸出層神經(jīng)元會(huì)計(jì)算該樣本與自身攜帶的權(quán)向量之間的距離,距離最近的神經(jīng)元成為競(jìng)爭(zhēng)獲勝者,稱為最佳匹配單元。然后最佳匹配單元及其鄰近的神經(jīng)元的權(quán)向量將被調(diào)整,以使得這些權(quán)向量與當(dāng)前輸入樣本的距離縮小。這個(gè)過程不斷迭代,直至收斂。

  • 網(wǎng)絡(luò)結(jié)構(gòu):輸入層和輸出層(或競(jìng)爭(zhēng)層),如下圖所示。
  • 輸入層:假設(shè)一個(gè)輸入樣本為X=[x1,x2,x3,…,xn],是一個(gè)n維向量,則輸入層神經(jīng)元個(gè)數(shù)為n個(gè)。
  • 輸出層(競(jìng)爭(zhēng)層):通常輸出層的神經(jīng)元以矩陣方式排列在二維空間中,每個(gè)神經(jīng)元都有一個(gè)權(quán)值向量。
  • 假設(shè)輸出層有m個(gè)神經(jīng)元,則有m個(gè)權(quán)值向量,Wi = [wi1,wi2,....,win], 1<=i<=m。

算法流程:

1. 初始化:權(quán)值使用較小的隨機(jī)值進(jìn)行初始化,并對(duì)輸入向量和權(quán)值做歸一化處理
          X' = X/||X||
          ω'i= ωi/||ωi||, 1<=i<=m
          ||X||和||ωi||分別為輸入的樣本向量和權(quán)值向量的歐幾里得范數(shù)。

2.將樣本輸入網(wǎng)絡(luò):樣本與權(quán)值向量做點(diǎn)積,點(diǎn)積值最大的輸出神經(jīng)元贏得競(jìng)爭(zhēng),
(或者計(jì)算樣本與權(quán)值向量的歐幾里得距離,距離最小的神經(jīng)元贏得競(jìng)爭(zhēng))記為獲勝神經(jīng)元。

3.更新權(quán)值:對(duì)獲勝的神經(jīng)元拓?fù)溧徲騼?nèi)的神經(jīng)元進(jìn)行更新,并對(duì)學(xué)習(xí)后的權(quán)值重新歸一化。
        ω(t+1)= ω(t)+ η(t,n) * (x-ω(t))
        η(t,n):η為學(xué)習(xí)率是關(guān)于訓(xùn)練時(shí)間t和與獲勝神經(jīng)元的拓?fù)渚嚯xn的函數(shù)。
        η(t,n)=η(t)e^(-n)
        η(t)的幾種函數(shù)圖像如下圖所示。

4.更新學(xué)習(xí)速率η及拓?fù)溧徲騈,N隨時(shí)間增大距離變小,如下圖所示。

5.判斷是否收斂。如果學(xué)習(xí)率η<=ηmin或達(dá)到預(yù)設(shè)的迭代次數(shù),結(jié)束算法。

python代碼實(shí)現(xiàn)SOM

import numpy as np
import pylab as pl

class SOM(object):
  def __init__(self, X, output, iteration, batch_size):
    """
    :param X: 形狀是N*D, 輸入樣本有N個(gè),每個(gè)D維
    :param output: (n,m)一個(gè)元組,為輸出層的形狀是一個(gè)n*m的二維矩陣
    :param iteration:迭代次數(shù)
    :param batch_size:每次迭代時(shí)的樣本數(shù)量
    初始化一個(gè)權(quán)值矩陣,形狀為D*(n*m),即有n*m權(quán)值向量,每個(gè)D維
    """
    self.X = X
    self.output = output
    self.iteration = iteration
    self.batch_size = batch_size
    self.W = np.random.rand(X.shape[1], output[0] * output[1])
    print (self.W.shape)

  def GetN(self, t):
    """
    :param t:時(shí)間t, 這里用迭代次數(shù)來表示時(shí)間
    :return: 返回一個(gè)整數(shù),表示拓?fù)渚嚯x,時(shí)間越大,拓?fù)溧徲蛟叫?
    """
    a = min(self.output)
    return int(a-float(a)*t/self.iteration)

  def Geteta(self, t, n):
    """
    :param t: 時(shí)間t, 這里用迭代次數(shù)來表示時(shí)間
    :param n: 拓?fù)渚嚯x
    :return: 返回學(xué)習(xí)率,
    """
    return np.power(np.e, -n)/(t+2)

  def updata_W(self, X, t, winner):
    N = self.GetN(t)
    for x, i in enumerate(winner):
      to_update = self.getneighbor(i[0], N)
      for j in range(N+1):
        e = self.Geteta(t, j)
        for w in to_update[j]:
          self.W[:, w] = np.add(self.W[:,w], e*(X[x,:] - self.W[:,w]))

  def getneighbor(self, index, N):
    """
    :param index:獲勝神經(jīng)元的下標(biāo)
    :param N: 鄰域半徑
    :return ans: 返回一個(gè)集合列表,分別是不同鄰域半徑內(nèi)需要更新的神經(jīng)元坐標(biāo)
    """
    a, b = self.output
    length = a*b
    def distence(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)

    ans = [set() for i in range(N+1)]
    for i in range(length):
      dist_a, dist_b = distence(i, index)
      if dist_a <= N and dist_b <= N: ans[max(dist_a, dist_b)].add(i)
    return ans



  def train(self):
    """
    train_Y:訓(xùn)練樣本與形狀為batch_size*(n*m)
    winner:一個(gè)一維向量,batch_size個(gè)獲勝神經(jīng)元的下標(biāo)
    :return:返回值是調(diào)整后的W
    """
    count = 0
    while self.iteration > count:
      train_X = self.X[np.random.choice(self.X.shape[0], self.batch_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.updata_W(train_X, count, winner)
      count += 1
    return self.W

  def train_result(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):
  """
  :param X:二維矩陣,N*D,N個(gè)D維的數(shù)據(jù)
  :return: 將X歸一化的結(jié)果
  """
  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):
  """
  :param W:二維矩陣,D*(n*m),D個(gè)n*m維的數(shù)據(jù)
  :return: 將W歸一化的結(jié)果
  """
  for i in range(W.shape[1]):
    temp = np.sum(np.multiply(W[:,i], W[:,i]))
    W[:, i] /= np.sqrt(temp)
  return W

#畫圖
def draw(C):
  colValue = ['r', 'y', 'g', 'b', 'c', 'k', 'm']
  for i in range(len(C)):
    coo_X = []  #x坐標(biāo)列表
    coo_Y = []  #y坐標(biāo)列表
    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()

#數(shù)據(jù)集:每三個(gè)是一組分別是西瓜的編號(hào),密度,含糖量
data = """
1,0.697,0.46,2,0.774,0.376,3,0.634,0.264,4,0.608,0.318,5,0.556,0.215,
6,0.403,0.237,7,0.481,0.149,8,0.437,0.211,9,0.666,0.091,10,0.243,0.267,
11,0.245,0.057,12,0.343,0.099,13,0.639,0.161,14,0.657,0.198,15,0.36,0.37,
16,0.593,0.042,17,0.719,0.103,18,0.359,0.188,19,0.339,0.241,20,0.282,0.257,
21,0.748,0.232,22,0.714,0.346,23,0.483,0.312,24,0.478,0.437,25,0.525,0.369,
26,0.751,0.489,27,0.532,0.472,28,0.473,0.376,29,0.725,0.445,30,0.446,0.459"""

a = data.split(',')
dataset = np.mat([[float(a[i]), float(a[i+1])] for i in range(1, len(a)-1, 3)])
dataset_old = dataset.copy()

som = SOM(dataset, (5, 5), 1, 30)
som.train()
res = som.train_result()
classify = {}
for i, win in enumerate(res):
  if not classify.get(win[0]):
    classify.setdefault(win[0], [i])
  else:
    classify[win[0]].append(i)
C = []#未歸一化的數(shù)據(jù)分類結(jié)果
D = []#歸一化的數(shù)據(jù)分類結(jié)果
for i in classify.values():
  C.append(dataset_old[i].tolist())
  D.append(dataset[i].tolist())
draw(C)
draw(D)

由于數(shù)據(jù)比較少,就直接用的訓(xùn)練集做測(cè)試了,運(yùn)行結(jié)果圖如下,分別是對(duì)未歸一化的數(shù)據(jù)和歸一化的數(shù)據(jù)進(jìn)行的展示。

參考內(nèi)容:

1.《機(jī)器學(xué)習(xí)》周志華
2.自組織競(jìng)爭(zhēng)神經(jīng)網(wǎng)絡(luò)SOM

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python控制臺(tái)輸出俄羅斯方塊移動(dòng)和旋轉(zhuǎn)功能

    Python控制臺(tái)輸出俄羅斯方塊移動(dòng)和旋轉(zhuǎn)功能

    這篇文章主要介紹了Python控制臺(tái)輸出俄羅斯方塊移動(dòng)和旋轉(zhuǎn)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 基于Opencv制作的美顏相機(jī)帶你領(lǐng)略美顏特效的效果

    基于Opencv制作的美顏相機(jī)帶你領(lǐng)略美顏特效的效果

    最關(guān)于美顏類相機(jī)最重要的是第一步:人臉檢測(cè),本篇文章中是采用openCV開源庫實(shí)現(xiàn),文中給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值
    2021-09-09
  • pip安裝提示Twisted錯(cuò)誤問題(Python3.6.4安裝Twisted錯(cuò)誤)

    pip安裝提示Twisted錯(cuò)誤問題(Python3.6.4安裝Twisted錯(cuò)誤)

    這篇文章主要介紹了pip安裝提示Twisted錯(cuò)誤問題(Python3.6.4安裝Twisted錯(cuò)誤),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Python利用Rows快速操作csv文件

    Python利用Rows快速操作csv文件

    Rows?是一個(gè)專門用于操作表格的第三方Python模塊。只要通過?Rows?讀取?csv?文件,她就能生成可以被計(jì)算的?Python?對(duì)象。本文將通過示例為大家詳細(xì)講講Python如何利用Rows快速操作csv文件,需要的可以參考一下
    2022-09-09
  • 淺談Tensorflow2對(duì)GPU內(nèi)存的分配策略

    淺談Tensorflow2對(duì)GPU內(nèi)存的分配策略

    本文主要介紹了Tensorflow2對(duì)GPU內(nèi)存的分配策略,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • python如何終止死循環(huán)和開啟死循環(huán)

    python如何終止死循環(huán)和開啟死循環(huán)

    這篇文章主要介紹了python如何終止死循環(huán)和開啟死循環(huán)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Python簡(jiǎn)單實(shí)現(xiàn)enum功能的方法

    Python簡(jiǎn)單實(shí)現(xiàn)enum功能的方法

    這篇文章主要介紹了Python簡(jiǎn)單實(shí)現(xiàn)enum功能的方法,簡(jiǎn)單分析了Python實(shí)現(xiàn)enum功能的相關(guān)技巧,需要的朋友可以參考下
    2016-04-04
  • Python計(jì)算信息熵實(shí)例

    Python計(jì)算信息熵實(shí)例

    這篇文章主要介紹了Python計(jì)算信息熵實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • Python中裝飾器學(xué)習(xí)總結(jié)

    Python中裝飾器學(xué)習(xí)總結(jié)

    這篇文章主要介紹了Python中裝飾器學(xué)習(xí)總結(jié),分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • python服務(wù)器中發(fā)送外部請(qǐng)求的基本步驟

    python服務(wù)器中發(fā)送外部請(qǐng)求的基本步驟

    在Python中,服務(wù)器發(fā)送外部請(qǐng)求是一個(gè)常見的操作,尤其是在需要集成不同服務(wù)或API時(shí),有多種庫可以幫助你完成這項(xiàng)任務(wù),但最流行和廣泛使用的庫之一是requests,下面給大家分享python服務(wù)器中發(fā)送外部請(qǐng)求的基本步驟,感興趣的朋友一起看看吧
    2024-08-08

最新評(píng)論