class CooCoo::FullyConnectedLayer

Attributes

activation_function[R]
bias[R]
weights[R]

Public Class Methods

from_hash(h, network = nil) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 139
def from_hash(h, network = nil)
  self.new(h[:neurons][0][:num_inputs],
           h[:outputs],
           ActivationFunctions.from_name(h[:f] || 'Identity')).
    update_from_hash!(h)
end
new(num_inputs, size, activation_func = ActivationFunctions::Identity.instance, weights = nil, bias = nil) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 15
def initialize(num_inputs, size, activation_func = ActivationFunctions::Identity.instance, weights = nil, bias = nil)
  @num_inputs = num_inputs
  @size = size
  @activation_function = activation_func
  @weights = weights || @activation_function.initial_weights(num_inputs, size)
  @bias = bias || @activation_function.initial_bias(size)
end

Public Instance Methods

==(other) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 130
def ==(other)
  other.kind_of?(self.class) &&
    size == other.size &&
    bias == other.bias &&
    weights == other.weights &&
    activation_function == other.activation_function
end
add_inputs!(new_size) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 98
def add_inputs!(new_size)
  if new_size != num_inputs
    w = CooCoo::Vector.zeros(new_size * size)
    w.set2d!(new_size, @weights, num_inputs, 0, 0)
    w.set2d!(new_size, @activation_function.initial_weights(size, 1), 1, new_size - 1, 0)
    @weights = w
    @num_inputs = new_size
  end
  
  self
end
add_neurons!(new_size) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 82
def add_neurons!(new_size)
  if new_size != @size
    w = CooCoo::Vector.zeros(num_inputs * new_size)
    w[0, @weights.size] = @weights
    w[@weights.size, num_inputs] = @activation_function.initial_weights(num_inputs, 1)
    @weights = w

    @bias = CooCoo::Vector.ones(new_size).set(@bias)
    @bias[-1] = @activation_function.initial_bias(1)[0]
    
    @size = new_size
  end
  
  self
end
adjust_weights!(deltas) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 55
def adjust_weights!(deltas)
  @bias -= deltas.bias_deltas
  @weights -= deltas.weight_deltas
  self
end
backprop(input, output, errors, hidden_state) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 39
def backprop(input, output, errors, hidden_state)
  return errors, hidden_state
end
forward(input, hidden_state) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 35
def forward(input, hidden_state)
  return @weights.dot(num_inputs, size, input, 1, num_inputs) + @bias, hidden_state
end
neuron_hash() click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 73
def neuron_hash
  @weights.each_slice(num_inputs).with_index.collect do |neuron_weights, i|
    { num_inputs: num_inputs,
      weights: neuron_weights.to_a,
      bias: @bias[i]
    }      
  end
end
num_inputs() click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 27
def num_inputs
  @num_inputs
end
size() click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 31
def size
  @size
end
to_hash(network = nil) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 65
def to_hash(network = nil)
  { type: self.class.to_s,
    outputs: size,
    neurons: neuron_hash,
    f: activation_function.name
  }
end
transfer_error(deltas) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 43
def transfer_error(deltas)
  deltas.dot(size, 1, @weights, num_inputs, size)
end
transfer_input_error(expecting) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 47
def transfer_input_error(expecting)
  (output - expecting).to_a
end
update_from_hash!(h) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 119
def update_from_hash!(h)
  add_neurons!(h[:outputs])
  add_inputs!(h[:neurons][0][:num_inputs])
  
  h[:outputs].times do |i|
    update_neuron_from_hash!(i, h[:neurons][i])
  end

  self
end
update_neuron_from_hash!(neuron_index, h) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 110
def update_neuron_from_hash!(neuron_index, h)
  if neuron_index > size
    add_neurons!(neuron_index)
  end

  @weights[neuron_index * num_inputs, num_inputs] = h[:weights]
  @bias[neuron_index] = h[:bias]
end
update_weights!(inputs, deltas) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 51
def update_weights!(inputs, deltas)
  adjust_weights!(weight_deltas(inputs, deltas))
end
weight_deltas(inputs, deltas) click to toggle source
# File lib/coo-coo/fully_connected_layer.rb, line 61
def weight_deltas(inputs, deltas)
  WeightDeltas.new(deltas, deltas.dot(1, size, inputs, num_inputs, 1))
end