Guest User

Untitled

a guest
Sep 25th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.37 KB | None | 0 0
  1. class Synapse
  2. attr_accessor :weight, :prev_weight
  3. attr_accessor :source_neuron, :dest_neuron
  4.  
  5. def initialize(source_neuron, dest_neuron, prng)
  6. self.source_neuron = source_neuron
  7. self.dest_neuron = dest_neuron
  8. self.prev_weight = self.weight = prng.rand(-1.0..1.0)
  9. end
  10. end
  11.  
  12. class Neuron
  13.  
  14. LEARNING_RATE = 1.0
  15. MOMENTUM = 0.3
  16.  
  17. attr_accessor :synapses_in, :synapses_out
  18. attr_accessor :threshold, :prev_threshold, :error
  19. attr_accessor :output
  20.  
  21. def initialize(prng)
  22. self.prev_threshold = self.threshold = prng.rand(-1.0..1.0)
  23. self.synapses_in = []
  24. self.synapses_out = []
  25. end
  26.  
  27. def calculate_output
  28. # calculate output based on the previous layer
  29. # use logistic function
  30.  
  31. activation = synapses_in.inject(0.0) do |sum, synapse|
  32. sum + synapse.weight * synapse.source_neuron.output
  33. end
  34. activation -= threshold
  35.  
  36. self.output = 1.0 / (1.0 + Math.exp(-activation))
  37. end
  38.  
  39. def derivative
  40. output * (1 - output)
  41. end
  42.  
  43. def output_train(rate, target)
  44. self.error = (target - output) * derivative
  45. update_weights(rate)
  46. end
  47.  
  48. def hidden_train(rate)
  49. self.error = synapses_out.inject(0.0) do |sum, synapse|
  50. sum + synapse.prev_weight * synapse.dest_neuron.error
  51. end * derivative
  52. update_weights(rate)
  53. end
  54.  
  55. def update_weights(rate)
  56. synapses_in.each do |synapse|
  57. temp_weight = synapse.weight
  58. synapse.weight += (rate * LEARNING_RATE * error * synapse.source_neuron.output) +
  59. (MOMENTUM * ( synapse.weight - synapse.prev_weight))
  60. synapse.prev_weight = temp_weight
  61. end
  62. temp_threshold = threshold
  63. self.threshold += (rate * LEARNING_RATE * error * -1) +
  64. (MOMENTUM * (threshold - prev_threshold))
  65. self.prev_threshold = temp_threshold
  66. end
  67. end
  68.  
  69. class NeuralNetwork
  70. attr_accessor :prng
  71.  
  72. def initialize(inputs, hidden, outputs)
  73. self.prng = Random.new
  74.  
  75. @input_layer = (1..inputs).map { Neuron.new(prng) }
  76. @hidden_layer = (1..hidden).map { Neuron.new(prng) }
  77. @output_layer = (1..outputs).map { Neuron.new(prng) }
  78.  
  79. @input_layer.product(@hidden_layer).each do |source, dest|
  80. synapse = Synapse.new(source, dest, prng)
  81. source.synapses_out << synapse
  82. dest.synapses_in << synapse
  83. end
  84. @hidden_layer.product(@output_layer).each do |source, dest|
  85. synapse = Synapse.new(source, dest, prng)
  86. source.synapses_out << synapse
  87. dest.synapses_in << synapse
  88. end
  89. end
  90.  
  91. def train(inputs, targets)
  92. feed_forward(inputs)
  93.  
  94. @output_layer.zip(targets).each do |neuron, target|
  95. neuron.output_train(0.3, target)
  96. end
  97. @hidden_layer.each { |neuron| neuron.hidden_train(0.3) }
  98. end
  99.  
  100. def feed_forward(inputs)
  101. @input_layer.zip(inputs).each do |neuron, input|
  102. neuron.output = input
  103. end
  104. @hidden_layer.each { |neuron| neuron.calculate_output }
  105. @output_layer.each { |neuron| neuron.calculate_output }
  106. end
  107.  
  108. def current_outputs
  109. @output_layer.map { |neuron| neuron.output }
  110. end
  111.  
  112. end
  113.  
  114. require 'benchmark'
  115.  
  116. x = Benchmark.measure do |x|
  117. xor = NeuralNetwork.new(2, 10, 1)
  118.  
  119. 10000.times do
  120. xor.train([0, 0], [0])
  121. xor.train([1, 0], [1])
  122. xor.train([0, 1], [1])
  123. xor.train([1, 1], [0])
  124. end
  125.  
  126. xor.feed_forward([0, 0])
  127. puts xor.current_outputs
  128. xor.feed_forward([0, 1])
  129. puts xor.current_outputs
  130. xor.feed_forward([1, 0])
  131. puts xor.current_outputs
  132. xor.feed_forward([1, 1])
  133. puts xor.current_outputs
  134. end
  135. puts x
Add Comment
Please, Sign In to add comment