Class: Cerebrum

Inherits:
Object
  • Object
show all
Includes:
CerebrumHelper, DataScrubber
Defined in:
lib/cerebrum/version.rb,
lib/cerebrum/cerebrum.rb

Constant Summary collapse

VERSION =
"0.1.3"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(learning_rate: 0.3, momentum: 0.1, binary_thresh: 0.5, hidden_layers: nil) ⇒ Cerebrum

Returns a new instance of Cerebrum.



12
13
14
15
16
17
# File 'lib/cerebrum/cerebrum.rb', line 12

def initialize(learning_rate: 0.3, momentum: 0.1, binary_thresh: 0.5, hidden_layers: nil)
  @learning_rate  = learning_rate
  @momentum       = momentum
  @binary_thresh  = binary_thresh
  @hidden_layers  = hidden_layers
end

Instance Attribute Details

#binary_threshObject

Returns the value of attribute binary_thresh.



9
10
11
# File 'lib/cerebrum/cerebrum.rb', line 9

def binary_thresh
  @binary_thresh
end

#hidden_layersObject

Returns the value of attribute hidden_layers.



9
10
11
# File 'lib/cerebrum/cerebrum.rb', line 9

def hidden_layers
  @hidden_layers
end

#input_lookup_tableObject

Returns the value of attribute input_lookup_table.



9
10
11
# File 'lib/cerebrum/cerebrum.rb', line 9

def input_lookup_table
  @input_lookup_table
end

#learning_rateObject

Returns the value of attribute learning_rate.



9
10
11
# File 'lib/cerebrum/cerebrum.rb', line 9

def learning_rate
  @learning_rate
end

#momentumObject

Returns the value of attribute momentum.



9
10
11
# File 'lib/cerebrum/cerebrum.rb', line 9

def momentum
  @momentum
end

#output_lookup_tableObject

Returns the value of attribute output_lookup_table.



9
10
11
# File 'lib/cerebrum/cerebrum.rb', line 9

def output_lookup_table
  @output_lookup_table
end

Instance Method Details

#load_state(saved_state) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/cerebrum/cerebrum.rb', line 85

def load_state(saved_state)
  state = JSON.parse(saved_state, symbolize_names: true)

  @biases               = state[:biases]
  @binary_thresh        = state[:binary_thresh]
  @changes              = state[:changes]
  @deltas               = state[:deltas]
  @errors               = state[:errors]
  @hidden_layers        = state[:hidden_layers]
  @input_lookup_table   = state[:input_lookup_table]
  @layer_sizes          = state[:layer_sizes]
  @layers               = state[:layers]
  @learning_rate        = state[:learning_rate]
  @momentum             = state[:momentum]
  @output_lookup_table  = state[:output_lookup_table]
  @outputs              = state[:outputs]
  @weights              = state[:weights]
end

#run(input) ⇒ Object



60
61
62
63
64
# File 'lib/cerebrum/cerebrum.rb', line 60

def run(input)
  input = to_vector_given_features(input, @input_lookup_table) if @input_lookup_table
  output = run_input(input)
  @output_lookup_table ? to_features_given_vector(output, @output_lookup_table) : output
end

#save_stateObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/cerebrum/cerebrum.rb', line 66

def save_state
  {
    biases: @biases,
    binary_thresh: @binary_thresh,
    changes: @changes,
    deltas: @deltas,
    errors: @errors,
    hidden_layers: @hidden_layers,
    input_lookup_table: @input_lookup_table,
    layer_sizes: @layer_sizes,
    layers: @layers,
    learning_rate: @learning_rate,
    momentum: @momentum,
    output_lookup_table: @output_lookup_table,
    outputs: @outputs,
    weights: @weights
  }.to_json
end

#train(training_set, options = Hash.new) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cerebrum/cerebrum.rb', line 28

def train(training_set, options = Hash.new)
  @input_lookup_table   ||= get_input_lookup_table(training_set)
  @output_lookup_table  ||= get_output_lookup_table(training_set)
  training_set = scrub_dataset(training_set)

  iterations        = options[:iterations] || 20000
  error_threshold   = options[:error_threshold] || 0.005
  log               = options[:log] || false
  log_period        = options[:log_period] || 10
  learning_rate     = options[:learning_rate] || 0.3
  error             = Float::INFINITY
  current_iteration = 0

  input_size = training_set[0][:input].length
  output_size = training_set[0][:output].length

  @hidden_layers ||= [ [3, (input_size/2).floor].max ]
  layer_sizes = [input_size, @hidden_layers, output_size].flatten
  construct_network(layer_sizes)

  iterations.times do |i|
    current_iteration = i
    training_set_errors = training_set.map { |ex| train_pattern(ex[:input], ex[:output], learning_rate) }
    error = training_set_errors.inject(:+) / training_set.length
    puts "(#{i}) training error: #{error}" if (log && (i % log_period) == 0)

    break if error < error_threshold
  end

  { error: error, iterations: current_iteration }
end

#train_pattern(input, target, learning_rate) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/cerebrum/cerebrum.rb', line 19

def train_pattern(input, target, learning_rate)
  learning_rate = learning_rate || @learning_rate

  run_input(input)
  calculate_deltas(target)
  adjust_weights(learning_rate)
  mean_squared_error(@errors[@layers])
end