Advertisement
here2share

# pureNN.py

Apr 2nd, 2021
741
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.81 KB | None | 0 0
  1. # pureNN.py
  2.  
  3. import math
  4. import random
  5.  
  6. random.seed(0)
  7.  
  8. # calculate a random number where:  a <= rand < b
  9. def rand(a, b):
  10.     return (b-a)*random.random() + a
  11.  
  12. # Make a matrix (we could use NumPy to speed this up)
  13. def makeMatrix(I, J, fill=0.0):
  14.     m = []
  15.     for i in range(I):
  16.         m.append([fill]*J)
  17.     return m
  18.  
  19. # our sigmoid function, tanh is a little nicer than the standard 1/(1+e^-x)
  20. def sigmoid(x):
  21.     return math.tanh(x)
  22.  
  23. # derivative of our sigmoid function, in terms of the output (i.e. y)
  24. def dsigmoid(y):
  25.     return 1.0 - y**2
  26.  
  27.  
  28. def plot(inputs, outputs, actual):
  29.     """Plot a given function.  
  30.    
  31.    The actual function will be plotted with a line and the outputs with
  32.    points.  Useful for visualizing the error of the neural networks attempt
  33.    at function interpolation."""
  34.     try:
  35.         import matplotlib.pyplot
  36.     except:
  37.         raise ImportError, "matplotlib package not found."
  38.     fig = matplotlib.pyplot.figure()
  39.     ax1 = fig.add_subplot(111)
  40.     ax1.plot(inputs, actual, 'b-')
  41.     ax1.plot(inputs, outputs, 'r.')
  42.     matplotlib.pyplot.draw()
  43.    
  44.    
  45.  
  46. class NN:
  47.     def __init__(self, ni, nh, no, regression = False):
  48.         """NN constructor.
  49.        
  50.        ni, nh, no are the number of input, hidden and output nodes.
  51.        regression is used to determine if the Neural network will be trained
  52.        and used as a classifier or for function regression.
  53.        """
  54.        
  55.         self.regression = regression
  56.        
  57.         #Number of input, hidden and output nodes.
  58.         self.ni = ni  + 1 # +1 for bias node
  59.         self.nh = nh  + 1 # +1 for bias node
  60.         self.no = no
  61.  
  62.         # activations for nodes
  63.         self.ai = [1.0]*self.ni
  64.         self.ah = [1.0]*self.nh
  65.         self.ao = [1.0]*self.no
  66.        
  67.         # create weights
  68.         self.wi = makeMatrix(self.ni, self.nh)
  69.         self.wo = makeMatrix(self.nh, self.no)
  70.        
  71.         # set them to random vaules
  72.         for i in range(self.ni):
  73.             for j in range(self.nh):
  74.                 self.wi[i][j] = rand(-1, 1)
  75.         for j in range(self.nh):
  76.             for k in range(self.no):
  77.                 self.wo[j][k] = rand(-1, 1)
  78.  
  79.         # last change in weights for momentum  
  80.         self.ci = makeMatrix(self.ni, self.nh)
  81.         self.co = makeMatrix(self.nh, self.no)
  82.  
  83.  
  84.     def update(self, inputs):
  85.         if len(inputs) != self.ni-1:
  86.             raise ValueError, 'wrong number of inputs'
  87.  
  88.         # input activations
  89.         for i in range(self.ni - 1):
  90.             self.ai[i] = inputs[i]
  91.  
  92.         # hidden activations
  93.         for j in range(self.nh - 1):
  94.             total = 0.0
  95.             for i in range(self.ni):
  96.                 total += self.ai[i] * self.wi[i][j]
  97.             self.ah[j] = sigmoid(total)
  98.  
  99.         # output activations
  100.         for k in range(self.no):
  101.             total = 0.0
  102.             for j in range(self.nh):
  103.                 total += self.ah[j] * self.wo[j][k]
  104.             self.ao[k] = total
  105.             if not self.regression:
  106.                 self.ao[k] = sigmoid(total)
  107.            
  108.        
  109.         return self.ao[:]
  110.  
  111.  
  112.     def backPropagate(self, targets, N, M):
  113.         if len(targets) != self.no:
  114.             raise ValueError, 'wrong number of target values'
  115.  
  116.         # calculate error terms for output
  117.         output_deltas = [0.0] * self.no
  118.         for k in range(self.no):
  119.             output_deltas[k] = targets[k] - self.ao[k]
  120.             if not self.regression:
  121.                 output_deltas[k] = dsigmoid(self.ao[k]) * output_deltas[k]
  122.  
  123.        
  124.         # calculate error terms for hidden
  125.         hidden_deltas = [0.0] * self.nh
  126.         for j in range(self.nh):
  127.             error = 0.0
  128.             for k in range(self.no):
  129.                 error += output_deltas[k]*self.wo[j][k]
  130.             hidden_deltas[j] = dsigmoid(self.ah[j]) * error
  131.  
  132.         # update output weights
  133.         for j in range(self.nh):
  134.             for k in range(self.no):
  135.                 change = output_deltas[k]*self.ah[j]
  136.                 self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k]
  137.                 self.co[j][k] = change
  138.  
  139.         # update input weights
  140.         for i in range(self.ni):
  141.             for j in range(self.nh):
  142.                 change = hidden_deltas[j]*self.ai[i]
  143.                 self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j]
  144.                 self.ci[i][j] = change
  145.  
  146.         # calculate error
  147.         error = 0.0
  148.         for k in range(len(targets)):
  149.             error += 0.5*((targets[k]-self.ao[k])**2)
  150.         return error
  151.  
  152.  
  153.     def test(self, patterns, verbose = False):
  154.         tmp = []
  155.         for p in patterns:
  156.             if verbose:
  157.                 print p[0], '->', self.update(p[0])
  158.             tmp.append(self.update(p[0]))
  159.  
  160.         return tmp
  161.  
  162.        
  163.     def weights(self):
  164.         print 'Input weights:'
  165.         for i in range(self.ni):
  166.             print self.wi[i]
  167.         print
  168.         print 'Output weights:'
  169.         for j in range(self.nh):
  170.             print self.wo[j]
  171.  
  172.     def train(self, patterns, iterations=1000, N=0.5, M=0.1, verbose = False):
  173.         """Train the neural network.  
  174.        
  175.        N is the learning rate.
  176.        M is the momentum factor.
  177.        """
  178.         for i in xrange(iterations):
  179.             error = 0.0
  180.             for p in patterns:
  181.                 self.update(p[0])
  182.                 tmp = self.backPropagate(p[1], N, M)
  183.                 error += tmp
  184.                
  185.             if i % 100 == 0:
  186.                 print 'error %-14f' % error
  187.            
  188.  
  189. def demoRegression():
  190.     data = []
  191.     inputs = []
  192.     actual = []
  193.  
  194.     domain = [-1, 1]
  195.     steps = 50
  196.     stepsize = (domain[1] - domain[0]) / ((steps - 1)*1.0)
  197.  
  198.     #Teach the network the function y = x**2
  199.     for i in range(steps):
  200.         x = domain[0] + stepsize * i
  201.         y = x**2
  202.        
  203.         data.append([[x], [y]])
  204.         inputs.append(x)
  205.         actual.append(y)
  206.        
  207.     n = NN(1, 4, 1, regression = True)
  208.    
  209.     #Train and test the nural network.
  210.     n.train(data, 1000, 0.2, 0.1, False)
  211.     outputs = n.test(data, verbose = True)
  212.    
  213.     #Plot the function.
  214.     try:
  215.         plot(inputs, outputs, actual)
  216.         print "Press a key to quit."
  217.         value = raw_input()
  218.     except:
  219.         print "Must have matplotlib to plot."
  220.  
  221.  
  222. def demoClassification():
  223.     # Teach network XOR function
  224.     pat = [
  225.         [[0,0], [0]],
  226.         [[0,1], [1]],
  227.         [[1,0], [1]],
  228.         [[1,1], [0]]
  229.     ]
  230.  
  231.     # create a network with two input, two hidden, and one output nodes
  232.     n = NN(2, 2, 1, regression = False)
  233.  
  234.     # train it with some patterns then test it.
  235.     n.train(pat, 1000, 0.5, 0.2)
  236.     n.test(pat, verbose = True)
  237.  
  238.  
  239. if __name__ == '__main__':
  240.     #demoRegression()
  241.     demoClassification()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement