Class: Brainy::Network

Inherits:
Object
  • Object
show all
Defined in:
lib/brainy/network.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input_count, hidden_count, output_count, learning_rate) ⇒ Network

Returns a new instance of Network.



5
6
7
8
9
10
11
12
13
# File 'lib/brainy/network.rb', line 5

def initialize(input_count, hidden_count, output_count, learning_rate)
  @layers = [
      Array.new(hidden_count, Vector.elements(Array.new(input_count + 1, rand(-1.0..1.0)))),
      Array.new(output_count, Vector.elements(Array.new(hidden_count + 1, rand(-1.0..1.0))))
  ]
  @learning_rate = learning_rate
  @activate = lambda { |x| 1 / (1 + Math.exp(-1 * x)) }
  @activate_prime = lambda { |x| x * (1 - x) }
end

Instance Attribute Details

#hidden_layerObject

Returns the value of attribute hidden_layer.



3
4
5
# File 'lib/brainy/network.rb', line 3

def hidden_layer
  @hidden_layer
end

#output_layerObject

Returns the value of attribute output_layer.



3
4
5
# File 'lib/brainy/network.rb', line 3

def output_layer
  @output_layer
end

Class Method Details

.from_serialized(dump) ⇒ Object



59
60
61
62
63
64
# File 'lib/brainy/network.rb', line 59

def self.from_serialized(dump)
  net = YAML.load(dump)
  net.instance_variable_set(:@activate, lambda { |x| 1 / (1 + Math.exp(-1 * x)) })
  net.instance_variable_set(:@activate_prime, lambda { |x| x * (1 - x) })
  net
end

Instance Method Details

#evaluate(inputs) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/brainy/network.rb', line 15

def evaluate(inputs)
  @layers.reduce(Vector.elements(inputs)) do |input, layer|
    input = Vector.elements(input.to_a + [1])
    output = layer.map { |node| @activate.call(node.inner_product(input)) }
    Vector.elements(output)
  end
end

#get_hidden_deltas(hidden_outs, output_nodes, output_deltas) ⇒ Object



39
40
41
42
43
44
# File 'lib/brainy/network.rb', line 39

def get_hidden_deltas(hidden_outs, output_nodes, output_deltas)
  hidden_outs.each_with_index.map do |out, index|
    error = output_nodes.zip(output_deltas).map { |weights, delta| weights[index] * delta }.reduce(:+)
    error * @activate_prime.call(out)
  end
end

#get_output_deltas(expected, output) ⇒ Object



33
34
35
36
37
# File 'lib/brainy/network.rb', line 33

def get_output_deltas(expected, output)
  expected.zip(output.to_a).map do |expect, out|
    (out - expect) * @activate_prime.call(out)
  end
end

#get_updated_weights(layer, inputs, deltas) ⇒ Object



46
47
48
49
50
51
52
53
# File 'lib/brainy/network.rb', line 46

def get_updated_weights(layer, inputs, deltas)
  layer.each_with_index.map do |weights, node_index|
    weights = weights.each_with_index.map do |weight, weight_index|
      weight - (@learning_rate * inputs[weight_index] * deltas[node_index])
    end
    Vector.elements(weights)
  end
end

#serializeObject



55
56
57
# File 'lib/brainy/network.rb', line 55

def serialize
  YAML.dump(self)
end

#train!(inputs, expected) ⇒ Object



23
24
25
26
27
28
29
30
31
# File 'lib/brainy/network.rb', line 23

def train!(inputs, expected)
  inputs = Vector.elements(inputs + [1])
  hidden_outs = Vector.elements(@layers.first.map { |node| @activate.call(node.inner_product(inputs)) } + [1])
  output_outs = Vector.elements(@layers.last.map { |node| @activate.call(node.inner_product(hidden_outs)) })
  output_deltas = get_output_deltas(expected, output_outs)
  hidden_deltas = get_hidden_deltas(hidden_outs, @layers.last, output_deltas)
  @layers[1] = get_updated_weights(@layers.last, hidden_outs, output_deltas)
  @layers[0] = get_updated_weights(@layers.first, inputs, hidden_deltas)
end