class CooCoo::Network
Attributes
activation_function[R]
age[R]
command[RW]
comments[RW]
Public Class Methods
from_a(layers)
click to toggle source
# File lib/coo-coo/network.rb, line 212 def from_a(layers) self.new().update_from_a!(layers) end
from_hash(h)
click to toggle source
# File lib/coo-coo/network.rb, line 216 def from_hash(h) self.new.update_from_hash!(h) end
load(path)
click to toggle source
# File lib/coo-coo/network.rb, line 220 def load(path) self.new().load!(path) end
new() { |self| ... }
click to toggle source
# File lib/coo-coo/network.rb, line 15 def initialize @layers = Array.new @age = 0 @command = [ $0 ] + ARGV yield(self) if block_given? end
Public Instance Methods
adjust_weights!(deltas)
click to toggle source
# File lib/coo-coo/network.rb, line 140 def adjust_weights!(deltas) @layers.each_with_index do |layer, i| layer.adjust_weights!(deltas[i]) end @age += 1 self end
backprop(inputs, outputs, errors, hidden_state = nil)
click to toggle source
# File lib/coo-coo/network.rb, line 109 def backprop(inputs, outputs, errors, hidden_state = nil) hidden_state ||= Hash.new d = @layers.reverse_each.each_with_index.inject([]) do |acc, (layer, i)| input = if i < (@layers.size - 1) outputs[@layers.size - i - 2] else prep_input(inputs) # TODO condition prep_input end #CooCoo.debug("#{self.class.name}.#{__method__}\t#{i} #{@layers.size - i - 1}\t#{input.size}\t#{outputs.size}") deltas, hidden_state = layer.backprop(input, outputs[@layers.size - i - 1], errors, hidden_state) errors = layer.transfer_error(deltas) acc.unshift(deltas) end return Sequence[d], hidden_state end
final_output(outputs)
click to toggle source
# File lib/coo-coo/network.rb, line 73 def final_output(outputs) outputs.last end
forward(input, hidden_state = nil, flattened = false, processed = false)
click to toggle source
# File lib/coo-coo/network.rb, line 77 def forward(input, hidden_state = nil, flattened = false, processed = false) unless flattened || input.kind_of?(CooCoo::Vector) input = CooCoo::Vector[input.to_a.flatten, num_inputs] end hidden_state ||= Hash.new output = if processed input else prep_input(input) end outputs = @layers.each_with_index.inject([]) do |acc, (layer, i)| #debug("Layer: #{i} #{layer.num_inputs} #{layer.size}") #debug("Input: #{input}") #debug("Weights: #{layer.neurons[0].weights}") output, hidden_state = layer.forward(output, hidden_state) acc << output #debug("Output: #{input}") end return outputs, hidden_state end
layer(new_layer)
click to toggle source
# File lib/coo-coo/network.rb, line 42 def layer(new_layer) @layers << new_layer self end
layer_index(layer)
click to toggle source
# File lib/coo-coo/network.rb, line 38 def layer_index(layer) @layers.find_index { |l| l.eql?(layer) } end
layers()
click to toggle source
# File lib/coo-coo/network.rb, line 34 def layers @layers end
learn(input, expecting, rate, cost_function = CostFunctions::MeanSquare, hidden_state = nil)
click to toggle source
# File lib/coo-coo/network.rb, line 162 def learn(input, expecting, rate, cost_function = CostFunctions::MeanSquare, hidden_state = nil) hidden_state ||= Hash.new output, hidden_state = forward(input, hidden_state) cost = cost_function.derivative(prep_input(expecting), output.last) deltas, hidden_state = backprop(input, output, cost, hidden_state) update_weights!(input, output, deltas * rate) return self, hidden_state rescue CooCoo.debug("Network#learn caught #{$!}", input, expecting) raise end
load!(path)
click to toggle source
# File lib/coo-coo/network.rb, line 180 def load!(path) yaml = YAML.load(File.read(path)) raise RuntimeError.new("Invalid YAML definition in #{path}") if yaml.nil? update_from_hash!(yaml) self end
num_inputs()
click to toggle source
# File lib/coo-coo/network.rb, line 22 def num_inputs @layers.first.num_inputs end
num_layers()
click to toggle source
# File lib/coo-coo/network.rb, line 30 def num_layers @layers.size end
num_outputs()
click to toggle source
# File lib/coo-coo/network.rb, line 26 def num_outputs @layers.last.size end
output_activation_function()
click to toggle source
# File lib/coo-coo/network.rb, line 56 def output_activation_function unless @output_activation_function layer = @layers.reverse.find { |l| l.activation_function } @output_activation_function = layer.activation_function end @output_activation_function end
predict(input, hidden_state = nil, flattened = false, processed = false)
click to toggle source
# File lib/coo-coo/network.rb, line 102 def predict(input, hidden_state = nil, flattened = false, processed = false) hidden_state ||= Hash.new outputs, hidden_state = forward(input, hidden_state, flattened, processed) out = final_output(outputs) return out, hidden_state end
prep_input(input)
click to toggle source
# File lib/coo-coo/network.rb, line 65 def prep_input(input) activation_function.prep_input(input) end
prep_output_target(target)
click to toggle source
# File lib/coo-coo/network.rb, line 69 def prep_output_target(target) output_activation_function.prep_output_target(target) end
save(path)
click to toggle source
# File lib/coo-coo/network.rb, line 174 def save(path) File.write_to(path) do |f| f.write(to_hash.to_yaml) end end
to_hash()
click to toggle source
# File lib/coo-coo/network.rb, line 203 def to_hash { age: @age, command: @command, comments: @comments, layers: @layers.collect { |l| l.to_hash(self) } } end
transfer_errors(deltas)
click to toggle source
# File lib/coo-coo/network.rb, line 129 def transfer_errors(deltas) @layers.zip(deltas).collect do |layer, delta| layer.transfer_error(delta) end end
update_from_hash!(h)
click to toggle source
# File lib/coo-coo/network.rb, line 189 def update_from_hash!(h) @layers = Array.new h[:layers].each do |layer_hash| @layers << CooCoo::LayerFactory.from_hash(layer_hash, self) end @age = h.fetch(:age, 0) @command = h.fetch(:command, nil) @comments = h.fetch(:comments) { Array.new } self end
update_weights!(input, outputs, deltas)
click to toggle source
# File lib/coo-coo/network.rb, line 135 def update_weights!(input, outputs, deltas) adjust_weights!(weight_deltas(input, outputs, deltas)) self end
weight_deltas(input, outputs, deltas)
click to toggle source
# File lib/coo-coo/network.rb, line 149 def weight_deltas(input, outputs, deltas) d = @layers.each_with_index.collect do |layer, i| inputs = if i != 0 outputs[i - 1] else prep_input(input) end layer.weight_deltas(inputs, deltas[i]) end d end