Advertisement
Lempek

SOM.py

Jun 17th, 2014
934
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.40 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. #-------------------------------------------------------------------------------
  6. class Node(object):
  7.     def __init__(self, x, y, input_length):
  8.         self.x = x
  9.         self.y = y
  10.         self.weights = np.random.random(input_length)
  11.         np.random.rand
  12.         self.cluster = np.array([])
  13.    
  14.     def getWeights(self):
  15.         return self.weights
  16.    
  17.     def updateWeights(self, alpha, influence, difference):
  18.         self.weights += alpha * influence * difference
  19.    
  20.     def activate(self, input_vector):
  21.         return np.sqrt(np.sum(((self.weights - input_vector) ** 2)))
  22.    
  23.     def getDistance(self, x, y):
  24.         return np.sqrt((self.x - x) ** 2 + (self.y - y) ** 2)
  25.    
  26.     def getCluster(self):
  27.         return self.cluster
  28.    
  29.     def setCluster(self):
  30.         ones = (self.cluster == 1).sum()
  31.         zeros = (self.cluster == 0).sum()
  32.         if (ones > zeros):
  33.             self.cluster = 1
  34.         elif (ones == zeros):
  35.             self.cluster = np.random.randint(0, 2)
  36.         else:
  37.             self.cluster = 0
  38.        
  39. #-------------------------------------------------------------------------------
  40. class SOM:
  41.     def __init__(self, map_size, input_length, clusters, alpha_start, alpha_min, decay_rate):
  42.         self.map_size = map_size
  43.         self.input_length = input_length
  44.         self.clusters = np.zeros(clusters)
  45.         self.alpha = alpha_start
  46.         self.alpha_min = alpha_min
  47.         self.decay_rate = decay_rate
  48.         # Generowanie siatki neuronów
  49.         self.neurons = np.array([[Node(x, y, self.input_length) for y in range(self.map_size)] for x in range(self.map_size)])
  50.         # Generowanie macierzy odległości
  51.         self.distances = np.zeros([self.map_size, self.map_size])
  52.         self.neighbourhood_radius = map_size  # Promień sąsiedztwa. Tyle, bo wujek Kohonen tak zalecał.
  53.         self.t = 0  # iterator
  54.        
  55.     def activate(self, input_vector):
  56.         for x in range(self.map_size):
  57.             for y in range(self.map_size):
  58.                 self.distances[x][y] = self.neurons[x][y].activate(input_vector)
  59.     def adaptLearningRate(self):
  60.         self.alpha *= np.exp(-self.t / self.decay_rate)
  61.    
  62.     def calculateNeighbourhoodRadius(self):
  63.         self.neighbourhood_radius = self.map_size * np.exp(-self.t / self.decay_rate)
  64.    
  65.     def calculateInfluence(self, distance):
  66.         return np.exp(-distance ** 2 / (2 * self.neighbourhood_radius ** 2))
  67.        
  68.     def train(self, input_vector, clusters_vector):
  69.         self.t = 0
  70.         # Łączna liczba elementów zbioru uczącego,
  71.         # Czyli Liczba_wektorów x wymiar_wektora
  72.         size = np.size(input_vector)
  73.         vectors_num = size // self.input_length  # Liczba wektorów zbioru uczącego
  74.         while (self.alpha > self.alpha_min):
  75.             # Wybór losowego wektora
  76.             i = np.random.randint(0, vectors_num)
  77.             self.activate(input_vector[i])
  78.             winner_x, winner_y = np.unravel_index(self.distances.argmin(), self.distances.shape)
  79.             # Akutalizacja współczynników sieci
  80.             self.adaptLearningRate()
  81.             self.calculateNeighbourhoodRadius()
  82.             for x in range(self.map_size):
  83.                 for y in range(self.map_size):
  84.                     # Dla każdego węzła w sieci wyznacz jego odległość od węzła zwycięskiego
  85.                     distance = self.neurons[x][y].getDistance(winner_x, winner_y)
  86.                     if(distance <= self.neighbourhood_radius):
  87.                         influence = self.calculateInfluence(distance)
  88.                         difference = (input_vector[i] - self.neurons[x][y].getWeights())
  89.                         self.neurons[x][y].updateWeights(self.alpha, influence, difference)
  90.                         self.neurons[x][y].cluster = np.append(self.neurons[x][y].cluster, clusters_vector[i])
  91.             self.t += 1
  92.         for x in range(self.map_size):
  93.                 for y in range(self.map_size):
  94.                     self.neurons[x][y].setCluster()
  95.        
  96.     def test(self, input_vector, clusters_vector):
  97.         results = []
  98.         (vectors_num, vector_length) = input_vector.shape
  99.         for i in range(vectors_num):
  100.             self.activate(input_vector[i])
  101.             winner = np.unravel_index(self.distances.argmin(), self.distances.shape)
  102.             results.append(self.neurons[winner[0]][winner[1]].getCluster())
  103.         results = np.array(results)
  104.         accuracy = 1 - np.sum(np.abs(results - clusters_vector)) / len(results)
  105.         return accuracy
  106.  
  107. #-------------------------------------------------------------------------------
  108. if __name__ == '__main__':
  109.     map_size = 20
  110.     clusters = 2
  111.     input_length = 22
  112.     decay_rate = 5
  113.     alpha_min = 0.001
  114.     alpha_start = 1
  115.  
  116.     filename = "Data/SPECT.train"
  117.     data = np.loadtxt(filename, 'i8', delimiter = ',')
  118.     train_features = (data.T[1:]).T
  119.     train_overall_diagnosis = (data.T[:1][0])
  120.    
  121.     filename = "Data/SPECT.test"
  122.     data = np.loadtxt(filename, 'i8', delimiter = ',')
  123.     test_features = (data.T[1:]).T
  124.     test_overall_diagnosis = (data.T[:1]).T
  125.    
  126.     som = SOM(map_size, input_length, clusters, alpha_start, alpha_min, decay_rate)
  127.     som.train(train_features, train_overall_diagnosis)
  128.     print(som.test(train_features, train_overall_diagnosis))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement