Advertisement
Guest User

Kohonen self organising map

a guest
Mar 1st, 2015
280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.52 KB | None | 0 0
  1. import numpy as np
  2. from matplotlib import pyplot as plt
  3.  
  4.  
  5. class Kohonen(object):
  6.     """ Here be docstring ...
  7.    Or ideally, there would be. Sorry. There isn't. This code works, but the
  8.    convergence is not optimised and there are loads of magic numbers. I'll
  9.    be happy to answer questions, and a co-worker has derived a more apt
  10.    algorithm for convergence, which I'll see if he'd be willing to share.
  11.  
  12.    Meanwhile, share and enjoy this under an MIT license!
  13.    
  14.    -- Skymandr
  15.    skymandr sprialgalaxy fripost pinprick org
  16.    http://eintrittverboten.wordpress.com/
  17.    """
  18.  
  19.     def __init__(self, domain, eta_0=-1, tau_0=-1, T_o=-1, sigma_0=-1,
  20.                  nneurons=-1, T_c=-1):
  21.         self.domain = self.load_image(domain)
  22.  
  23.         self.tau_0 = tau_0
  24.         self.eta_0 = eta_0
  25.         self.T_o = T_o
  26.  
  27.         if nneurons <= 0:
  28.             self.nneurons = self.get_nneurons()
  29.         else:
  30.             self.nneurons = nneurons
  31.  
  32.         if sigma_0 <= 0:
  33.             self.sigma_0 = 0.25 * self.nneurons
  34.         else:
  35.             self.sigma_0 = sigma_0
  36.  
  37.         if T_o <= 0:
  38.             self.T_o = 42 * self.nneurons
  39.         else:
  40.             self.T_o = T_o
  41.  
  42.         if T_c <= 0:
  43.             self.T_c = 420 * self.nneurons
  44.         else:
  45.             self.T_c = T_c
  46.  
  47.         if tau_0 <= 0:
  48.             self.tau_0 = self.T_o
  49.         else:
  50.             self.tau_0 = tau_0
  51.  
  52.         if eta_0 <= 0:
  53.             ny, nx = self.domain.shape
  54.             self.eta_0 = np.sqrt(nx * ny / self.nneurons)
  55.         else:
  56.             self.eta_0 = eta_0
  57.  
  58.         self.tau_1 = self.tau_0 / np.log(self.sigma_0)
  59.         self.tau_2 = self.tau_0
  60.  
  61.         self.eta = self.eta_0
  62.         self.sigma = self.sigma_0
  63.  
  64.         self.reset_sim()
  65.  
  66.     def get_winner(self, point, neurons):
  67.         #Delta2 = self.get_Delta(point, neurons) ** 2).sum(0)
  68.         DeltaChess = np.abs(self.get_Delta(point, neurons)).min(1)
  69.  
  70.         #return Delta2.argmin()
  71.         return DeltaChess.argmin()
  72.  
  73.     def get_point(self, domain):
  74.         thresh = np.random.random()
  75.         ny, nx = domain.shape
  76.  
  77.         val = -1
  78.         while val < thresh:
  79.             x = np.random.random() * nx - 0.5
  80.             y = np.random.random() * ny - 0.5
  81.             // Simple probability function:
  82.             val = domain[np.int(y), np.int(x)]
  83.             // Better contrast:
  84.             val = 1 - (1 - val) ** 2
  85.  
  86.         return np.array([x, y])
  87.  
  88.     def get_points(self, N):
  89.         P = self.get_point(self.domain)
  90.  
  91.         for n in xrange(N - 1):
  92.             P = np.vstack((P, self.get_point(self.domain)))
  93.  
  94.         return P.T
  95.  
  96.     def get_distance_penalty(self, winner, neurons, sigma):
  97.         arg_Delta = np.arange(neurons.shape[1]) - winner
  98.  
  99.         Lambda = np.exp(-arg_Delta ** 2 / (2 * sigma ** 2)) / \
  100.                        (np.sqrt(2 * np.pi * sigma ** 2))
  101.  
  102.         return np.array([Lambda])
  103.  
  104.     def get_Delta(self, point, neurons):
  105.         Delta = np.array([point[0] - neurons[0], point[1] - neurons[1]])
  106.  
  107.         return Delta
  108.  
  109.     def do_step(self):
  110.         neurons = self.neurons
  111.         sigma   = self.sigma
  112.         eta     = self.eta
  113.         domain  = self.domain
  114.  
  115.         point  = self.get_point(domain)
  116.         winner = self.get_winner(point, neurons)
  117.  
  118.         Delta = (eta * self.get_distance_penalty(winner, neurons, sigma) *
  119.                  self.get_Delta(point, neurons))
  120.         neurons += Delta
  121.  
  122.         if self.state == 'Ordering':
  123.             self.t += 1
  124.             self.sigma = self.sigma_0 * np.exp(-self.t / self.tau_1)
  125.             self.eta   = self.eta_0 * np.exp(-self.t / self.tau_2)
  126.             if self.t > self.T_o:
  127.                 self.t = 0
  128.                 self.state = 'Convergence'
  129.                 self.sigma = 1.0
  130.                 self.eta = 0.5 * self.eta_0
  131.         elif self.state == 'Convergence':
  132.             self.t += 1
  133.             if self.t > self.T_c:
  134.                 return 42
  135.         else:
  136.             print "Got invalid state: {0}".format(self.state)
  137.             raise OptionError(self.state)
  138.  
  139.         return 0
  140.  
  141.     def run_sim(self, debug=False):
  142.         if debug:
  143.             while self.do_step() != 42:
  144.                 if self.state == 'Ordering':
  145.                     T = self.T_o
  146.                 elif self.state == 'Convergence':
  147.                     T = self.T_c
  148.                 else:
  149.                     print "Got invalid state: {0}".format(self.state)
  150.                     raise OptionError(self.state)
  151.                 print "{0}: {1} ({2}%)".format(self.state, self.t,
  152.                                         np.int(100 * np.float(self.t) / T))
  153.                 pass
  154.         else:
  155.             while self.do_step() != 42:
  156.                 pass
  157.  
  158.     def reset_sim(self):
  159.         self.t = 0
  160.         self.state = 'Ordering'
  161.         self.neurons = self.get_points(self.nneurons)
  162.         self.neurons = 0.1 * self.neurons + np.array([self.neurons.mean(1)]).T
  163.  
  164.     def load_image(self, image):
  165.         image = plt.imread(image)
  166.  
  167.         while len(image.shape) > 2:
  168.             image = image.mean(-1)
  169.  
  170.         image -= image.min()
  171.         image /= image.max()
  172.         image = (1 - image) ** 2
  173.  
  174.         return image
  175.  
  176.     def get_nneurons(self, courant=1.0):
  177.         N = (1 - self.domain).sum()
  178.         return np.int(np.ceil(N * courant))
  179.  
  180.  
  181. class OptionError(Exception):
  182.     r""" Error raised if invalid option is passed to a function.
  183.    """
  184.  
  185.     def __init__(self, value):
  186.         self.value = value
  187.  
  188.     def __str__(self):
  189.         return repr(self.value)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement