fork download
  1. # Python backpropagation neural network 16 first prime numbers simulation
  2. # Originally from http://a...content-available-to-author-only...x.com/nas/python/bpnn.py
  3.  
  4. import math
  5. import random
  6. import string
  7.  
  8. random.seed(0)
  9.  
  10. def rand(a, b):
  11. return (b-a)*random.random() + a
  12.  
  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. # Orginally tanh, changed to unipolar sigmoid function
  20. def sigmoid(x):
  21. return 1 / (1 + math.exp(-x))
  22.  
  23. # derivative of unipolar sigmoid function
  24. def dsigmoid(y):
  25. return y - y**2
  26.  
  27. class NN:
  28. def __init__(self, ni, nh, no):
  29. self.ni = ni + 1 # +1 for bias node
  30. self.nh = nh
  31. self.no = no
  32.  
  33. self.ai = [1.0]*self.ni
  34. self.ah = [1.0]*self.nh
  35. self.ao = [1.0]*self.no
  36.  
  37. self.wi = makeMatrix(self.ni, self.nh)
  38. self.wo = makeMatrix(self.nh, self.no)
  39.  
  40. for i in range(self.ni):
  41. for j in range(self.nh):
  42. self.wi[i][j] = rand(-0.2, 0.2)
  43. for j in range(self.nh):
  44. for k in range(self.no):
  45. self.wo[j][k] = rand(-2.0, 2.0)
  46.  
  47. self.ci = makeMatrix(self.ni, self.nh)
  48. self.co = makeMatrix(self.nh, self.no)
  49.  
  50. def update(self, inputs):
  51. if len(inputs) != self.ni-1:
  52. raise ValueError('wrong number of inputs')
  53.  
  54. for i in range(self.ni-1):
  55. self.ai[i] = inputs[i]
  56.  
  57. for j in range(self.nh):
  58. sum = 0.0
  59. for i in range(self.ni):
  60. sum = sum + self.ai[i] * self.wi[i][j]
  61. self.ah[j] = sigmoid(sum)
  62.  
  63. for k in range(self.no):
  64. sum = 0.0
  65. for j in range(self.nh):
  66. sum = sum + self.ah[j] * self.wo[j][k]
  67. self.ao[k] = sigmoid(sum)
  68.  
  69. return self.ao[:]
  70.  
  71.  
  72. def backPropagate(self, targets, N, M):
  73. if len(targets) != self.no:
  74. raise ValueError('wrong number of target values')
  75.  
  76. output_deltas = [0.0] * self.no
  77. for k in range(self.no):
  78. error = targets[k]-self.ao[k]
  79. output_deltas[k] = dsigmoid(self.ao[k]) * error
  80.  
  81. hidden_deltas = [0.0] * self.nh
  82. for j in range(self.nh):
  83. error = 0.0
  84. for k in range(self.no):
  85. error = error + output_deltas[k]*self.wo[j][k]
  86. hidden_deltas[j] = dsigmoid(self.ah[j]) * error
  87.  
  88. for j in range(self.nh):
  89. for k in range(self.no):
  90. change = output_deltas[k]*self.ah[j]
  91. self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k]
  92. self.co[j][k] = change
  93.  
  94. for i in range(self.ni):
  95. for j in range(self.nh):
  96. change = hidden_deltas[j]*self.ai[i]
  97. self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j]
  98. self.ci[i][j] = change
  99.  
  100. error = 0.0
  101. for k in range(len(targets)):
  102. error = error + 0.5*(targets[k]-self.ao[k])**2
  103. return error
  104.  
  105. # changed to display prime numbers test
  106. def test(self, patterns):
  107. for p in patterns:
  108. output = self.update(p[0])
  109. number = p[0][0] * 8 + p[0][1] * 4 + p[0][2] * 2 + p[0][3]
  110. prime = round(p[1][0]) * 32 + round(p[1][1]) * 16 + round(p[1][2]) * 8 \
  111. + round(p[1][3]) * 4 + round(p[1][4]) * 2 + round(p[1][5])
  112. print('%d -> %d' % (number + 1, int(prime)))
  113.  
  114. def train(self, patterns, iterations=1000, N=0.5, M=0.1):
  115. # N: learning rate
  116. # M: momentum factor
  117. for i in range(iterations):
  118. error = 0.0
  119. for p in patterns:
  120. inputs = p[0]
  121. targets = p[1]
  122. self.update(inputs)
  123. error = error + self.backPropagate(targets, N, M)
  124. if i % 100 == 0:
  125. print('error %-.5f' % error)
  126.  
  127.  
  128. def demo():
  129. # Teach network prime number function
  130. pat = [
  131. [[0,0,0,0], [0,0,0,0,1,0]], #2
  132. [[0,0,0,1], [0,0,0,0,1,1]], #3
  133. [[0,0,1,0], [0,0,0,1,0,1]], #5
  134. [[0,0,1,1], [0,0,0,1,1,1]], #7
  135. [[0,1,0,0], [0,0,1,0,1,1]], #11
  136. [[0,1,0,1], [0,0,1,1,0,1]], #13
  137. [[0,1,1,0], [0,1,0,0,0,1]], #17
  138. [[0,1,1,1], [0,1,0,0,1,1]], #19
  139. [[1,0,0,0], [0,1,0,1,1,1]], #23
  140. [[1,0,0,1], [0,1,1,1,0,1]], #29
  141. [[1,0,1,0], [0,1,1,1,1,1]], #31
  142. [[1,0,1,1], [1,0,0,1,0,1]], #37
  143. [[1,1,0,0], [1,0,1,0,0,1]], #41
  144. [[1,1,0,1], [1,0,1,0,1,1]], #43
  145. [[1,1,1,0], [1,0,1,1,1,1]], #47
  146. [[1,1,1,1], [1,1,0,1,0,1]], #53
  147. ]
  148.  
  149. n = NN(4, 8, 6)
  150. n.train(pat, 3000)
  151. n.test(pat)
  152.  
  153. if __name__ == '__main__':
  154. demo()
  155.  
Success #stdin #stdout 3.86s 9864KB
stdin
Standard input is empty
stdout
error 13.44947
error 4.87555
error 1.65567
error 0.95727
error 0.74491
error 0.66142
error 0.61891
error 0.59352
error 0.57676
error 0.56492
error 0.55613
error 0.54937
error 0.54401
error 0.53966
error 0.53607
error 0.53305
error 0.53049
error 0.52828
error 0.52636
error 0.52467
error 0.52318
error 0.52185
error 0.52066
error 0.51959
error 0.51863
error 0.51775
error 0.51694
error 0.51620
error 0.51553
error 0.51490
1 -> 2
2 -> 3
3 -> 5
4 -> 7
5 -> 11
6 -> 13
7 -> 17
8 -> 19
9 -> 23
10 -> 29
11 -> 31
12 -> 37
13 -> 41
14 -> 43
15 -> 47
16 -> 53