Welcome, guest | Sign In | My Account | Store | Cart
from math import *
import random
from random import random as r

class NN:
  def __init__(self):
    # initialize node-activations
    self.ai = [1.0]*ni
    self.ah = [1.0]*nh
    self.ao = [1.0]*no
    self.Aah = [0.0]*nh
    self.Aao = [0.0]*no
    self.Ach, self.Aco = [0]*nh, [0]*no
    self.wi = [ [r() for j in range(nh)] for i in range(ni) ]
    self.wo = [ [r() for k in range(no)] for j in range(nh) ]
    self.ci = [[0.0]*nh]*ni
    self.co = [[0.0]*no]*nh
    
  def runNN (self, inputs):
    self.ai = inputs
    self.ah = [ sig(sum([ self.ai[i]*self.wi[i][j] for i in range(ni) ])) for j in range(nh)]
    self.ao = [ sig(sum([ self.ah[j]*self.wo[j][k] for j in range(nh) ])) for k in range(no)]
    return self.ao
      
  
  def backPropagate (self, targets, N, M):
    output_deltas = [0.0] * no
    for k in range(no):
      error = targets[k] - self.ao[k]
      output_deltas[k] =  error * dsig(self.ao[k]) 

    for j in range(nh):
      for k in range(no):
        change = output_deltas[k] * self.ah[j]
        self.wo[j][k] += N*change + M*self.co[j][k]
        self.co[j][k] = change

    # calc hidden deltas
    hidden_deltas = [0.0] * nh
    for j in range(nh):
      error = 0.0
      for k in range(no):
        error += output_deltas[k] * self.wo[j][k]
      hidden_deltas[j] = error * dsig(self.ah[j])
    
    #update input weights
    for i in range (ni):
      for j in range (nh):
        change = hidden_deltas[j] * self.ai[i]
        self.wi[i][j] += N*change + M*self.ci[i][j]
        self.ci[i][j] = change
        
    # calc combined error
    # 1/2 for differential convenience & **2 for modulus
    error = 0.0
    for k in range(len(targets)):
      error = 0.5 * (targets[k]-self.ao[k])**2
    return error
  
  def test(self, patterns):
    for p in patterns:
      inputs = p[0]
      print 'Inputs:', p[0], '-->', self.runNN(inputs), '\tTarget', p[1]

  def BP(self, patterns, N, M,i):
    for p in patterns:
      inputs = p[0]
      targets = p[1]
      self.runNN(inputs)
      error = self.backPropagate(targets, N, M)
    if i % 50 == 0:
      print str(i).zfill(len(str(max_iterations-1))),'Combined error', error

  def NGA(self, pat,i ):
    for p in pat:
      inputs = p[0]
      targets = p[1]
      self.astrocyteactions(inputs)

  def astrocyteactions (self, inputs):
    for m in range(M_iters):
      self.ai = inputs
      for j in range(nh):
        self.ah[j] = sig(sum([ self.ai[i]*self.wi[i][j] for i in range(ni) ]))
        if self.ah[j] > 0: self.Aah[j] +=1
        else: self.Aah[j] -=1
        if self.Aah[j] == Athresh:
          self.Ach[j] = Adur
        elif self.Aah[j] == -Athresh:
          self.Ach[j] = -Adur  
        if self.Ach[j] > 0:
          for i in range(ni):
            self.wi[i][j] += self.wi[i][j]*0.25
          self.Ach[j] -=1
        elif self.Ach[j] < 0:
          for i in range(ni):
            self.wi[i][j] += self.wi[i][j]*-0.5
          self.Ach[j] +=1
         
      for k in range(no):
        self.ao[k] = sig(sum([ self.ah[j]*self.wo[j][k] for j in range(nh) ]))
        if self.ao[k] > 0: self.Aao[k] +=1
        else: self.Aao[k] -=1
        if self.Aao[k] == Athresh:
          self.Aco[k] = Adur
        elif self.Aao[k] == -Athresh:
          self.Aco[k] = -Adur
        if self.Aco[k] > 0:
          for j in range(nh):
            self.wo[j][k] += self.wo[j][k]*0.25
          self.Aco[k] -=1
        elif self.Aco[k] < 0:
          for j in range(nh):
            self.wo[j][k] += self.wo[j][k]*-0.5
          self.Aco[k] +=1
    return self.ao
      
  def weights(self):
    print 'Input weights:'
    for i in range(ni):
      print map(lambda x: round(x,2),self.wi[i])
    print
    print 'Output weights:'
    for j in range(nh):
      print map(lambda x: round(x,2),self.wo[j])
    print ''
  
  def train (self, patterns):
    for i in range(max_iterations):
      self.BP(patterns, N, M,i)
      self.NGA(patterns,i)
    self.test(patterns)
    self.weights()



def sig (x):
  return tanh(x)

def dsig (y):
  return 1 - y**2

max_iterations = 10000
N=0.2
M=0.1
M_iters = 8
Athresh, Adur = 2, 3
ni, nh, no = 2,2,1
 pat = [
   [[0,0], [0]],
   [[0,1], [1]],
   [[1,0], [1]],
   [[1,1], [0]]
 ]
def main ():
  myNN = NN()
  myNN.train(pat)
  
  

if __name__ == "__main__":
    main()

Diff to Previous Revision

--- revision 2 2012-10-03 09:07:06
+++ revision 3 2012-10-03 20:59:44
@@ -3,12 +3,7 @@
 from random import random as r
 
 class NN:
-  def __init__(self, NI, NH, NO):
-    # number of nodes in layers
-    self.ni = NI
-    self.nh = NH
-    self.no = NO
-    
+  def __init__(self):
     # initialize node-activations
     self.ai = [1.0]*ni
     self.ah = [1.0]*nh
@@ -29,28 +24,28 @@
       
   
   def backPropagate (self, targets, N, M):
-    output_deltas = [0.0] * self.no
-    for k in range(self.no):
+    output_deltas = [0.0] * no
+    for k in range(no):
       error = targets[k] - self.ao[k]
       output_deltas[k] =  error * dsig(self.ao[k]) 
 
-    for j in range(self.nh):
-      for k in range(self.no):
+    for j in range(nh):
+      for k in range(no):
         change = output_deltas[k] * self.ah[j]
         self.wo[j][k] += N*change + M*self.co[j][k]
         self.co[j][k] = change
 
     # calc hidden deltas
-    hidden_deltas = [0.0] * self.nh
-    for j in range(self.nh):
+    hidden_deltas = [0.0] * nh
+    for j in range(nh):
       error = 0.0
-      for k in range(self.no):
+      for k in range(no):
         error += output_deltas[k] * self.wo[j][k]
       hidden_deltas[j] = error * dsig(self.ah[j])
     
     #update input weights
-    for i in range (self.ni):
-      for j in range (self.nh):
+    for i in range (ni):
+      for j in range (nh):
         change = hidden_deltas[j] * self.ai[i]
         self.wi[i][j] += N*change + M*self.ci[i][j]
         self.ci[i][j] = change
@@ -74,7 +69,7 @@
       self.runNN(inputs)
       error = self.backPropagate(targets, N, M)
     if i % 50 == 0:
-      print 'Combined error', error
+      print str(i).zfill(len(str(max_iterations-1))),'Combined error', error
 
   def NGA(self, pat,i ):
     for p in pat:
@@ -122,11 +117,11 @@
       
   def weights(self):
     print 'Input weights:'
-    for i in range(self.ni):
+    for i in range(ni):
       print map(lambda x: round(x,2),self.wi[i])
     print
     print 'Output weights:'
-    for j in range(self.nh):
+    for j in range(nh):
       print map(lambda x: round(x,2),self.wo[j])
     print ''
   
@@ -151,14 +146,14 @@
 M_iters = 8
 Athresh, Adur = 2, 3
 ni, nh, no = 2,2,1
+ pat = [
+   [[0,0], [0]],
+   [[0,1], [1]],
+   [[1,0], [1]],
+   [[1,1], [0]]
+ ]
 def main ():
-  pat = [
-      [[0,0], [0]],
-      [[0,1], [1]],
-      [[1,0], [1]],
-      [[1,1], [0]]
-  ]
-  myNN = NN(ni, nh, no)
+  myNN = NN()
   myNN.train(pat)
   
   

History