Class: RubyBrain::Network
- Inherits:
-
Object
- Object
- RubyBrain::Network
- Extended by:
- Forwardable
- Defined in:
- lib/ruby_brain/network.rb
Instance Attribute Summary collapse
-
#learning_rate ⇒ Object
Returns the value of attribute learning_rate.
Instance Method Summary collapse
- #dump_weights ⇒ Object
-
#dump_weights_to_yaml(file_name = nil) ⇒ Object
Dumps weights of the network into a file whose format is YAML.
-
#get_forward_outputs(inputs) ⇒ Object
Calculate the network output of forward propagation.
-
#init_network ⇒ Object
Initialize the network.
-
#initialize(num_units_list) ⇒ Network
constructor
Constructor of Network class.
-
#learn(inputs_set, outputs_set, max_training_count = 50, tolerance = 0.0, monitoring_channels = []) ⇒ Object
Starts training with training dataset.
- #learn2(inputs_set, outputs_set, max_training_count = 50, tolerance = 0.0, monitoring_channels = []) ⇒ Object
- #learn_only_specified_layer(layer_index, inputs_set, outputs_set, max_training_count = 50, tolerance = 0.0) ⇒ Object
- #load_weights_from(weights_set_source) ⇒ Object
-
#load_weights_from_yaml_file(yaml_file) ⇒ Object
Loads weights of the network from existing weights file whose format is YAML.
-
#run_backpropagate(backward_inputs) ⇒ Object
Calculate the networkoutput of backward propagation.
-
#update_weights ⇒ Object
Updates weights actually based on the result of backward propagation.
- #update_weights_of_layer(layer_index) ⇒ Object
Constructor Details
#initialize(num_units_list) ⇒ Network
Constructor of Network class
15 16 17 18 19 |
# File 'lib/ruby_brain/network.rb', line 15 def initialize(num_units_list) @layers = [] @num_units_list = num_units_list @weights_set = WeightContainer.new(@num_units_list) end |
Instance Attribute Details
#learning_rate ⇒ Object
Returns the value of attribute learning_rate.
6 7 8 |
# File 'lib/ruby_brain/network.rb', line 6 def learning_rate @learning_rate end |
Instance Method Details
#dump_weights ⇒ Object
259 260 261 262 263 |
# File 'lib/ruby_brain/network.rb', line 259 def dump_weights @weights_set.each_weights do |weights| pp weights end end |
#dump_weights_to_yaml(file_name = nil) ⇒ Object
Dumps weights of the network into a file whose format is YAML.
268 269 270 |
# File 'lib/ruby_brain/network.rb', line 268 def dump_weights_to_yaml(file_name=nil) @weights_set.dump_to_yaml(file_name) end |
#get_forward_outputs(inputs) ⇒ Object
Calculate the network output of forward propagation.
66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/ruby_brain/network.rb', line 66 def get_forward_outputs(inputs) inputs.each_with_index do |input, i| @layers.first.nodes[i].value = input end a_layer_outputs = nil a_layer_inputs = @layers.first.forward_outputs @layers.each do |layer| a_layer_outputs = layer.forward_outputs(a_layer_inputs) a_layer_inputs = a_layer_outputs end a_layer_outputs end |
#init_network ⇒ Object
Initialize the network. This method creates network actually based on the network structure Array which specified with Constructor.
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 |
# File 'lib/ruby_brain/network.rb', line 31 def init_network @layers = [] layer = Layer.new (@num_units_list[0] + 1).times do layer.append Nodes::ConstNode.new layer.output_weights = @weights_set.weights_of_order(0) end @layers << layer @num_units_list[1..-2].each_with_index do |num_units, i| layer = Layer.new layer.input_weights = @weights_set.weights_of_order(i) layer.output_weights = @weights_set.weights_of_order(i+1) (num_units).times do layer.append Nodes::Neuron.new end layer.append Nodes::ConstNode.new @layers << layer end layer = Layer.new layer.input_weights = @weights_set.weights_of_order(@num_units_list.size - 2) @num_units_list[-1].times do layer.append Nodes::Neuron.new end @layers << layer end |
#learn(inputs_set, outputs_set, max_training_count = 50, tolerance = 0.0, monitoring_channels = []) ⇒ Object
Starts training with training dataset
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/ruby_brain/network.rb', line 137 def learn(inputs_set, outputs_set, max_training_count=50, tolerance=0.0, monitoring_channels=[]) raise RubyBrain::Exception::TrainingDataError if inputs_set.size != outputs_set.size # raise "inputs_set and outputs_set has different size!!!!" if inputs_set.size != outputs_set.size best_error = 9999999999999 best_weights_array = [] max_training_count.times do |i_training| accumulated_errors = 0.0 # for rms inputs_set.zip(outputs_set).each do |t_input, t_output| forward_outputs = get_forward_outputs(t_input) # for rms start total_error_of_output_nodes = forward_outputs.zip(t_output).reduce(0.0) do |a, output_pair| a + ((output_pair[0] - output_pair[1])**2 / 2.0) end # end accumulated_errors += total_error_of_output_nodes / forward_outputs.size # accumulated_errors += forward_outputs.zip(t_output).reduce(0.0) { |a, output_pair| a + ((output_pair[0] - output_pair[1])**2 / 2.0) } / forward_outputs.size # for rms end backward_inputs = forward_outputs.zip(t_output).map { |o, t| o - t } run_backpropagate(backward_inputs) update_weights end rms_error = Math.sqrt(2.0 * accumulated_errors / inputs_set.size) # for rms # rms_error = calculate_rms_error(inputs_set, outputs_set) puts "--> #{rms_error} (#{i_training}/#{max_training_count})" if rms_error < best_error puts "update best!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" best_error = rms_error best_weights_array = @weights_set.get_weights_as_array end puts "best: #{best_error}" break if rms_error <= tolerance end if monitoring_channels.include? :best_params_training File.open "best_weights_#{Time.now.to_i}.yml", 'w+' do |f| YAML.dump(best_weights_array, f) end end end |
#learn2(inputs_set, outputs_set, max_training_count = 50, tolerance = 0.0, monitoring_channels = []) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/ruby_brain/network.rb', line 182 def learn2(inputs_set, outputs_set, max_training_count=50, tolerance=0.0, monitoring_channels=[]) # looks like works well for networks which has many layers... [1, 10, 10, 10, 1], [1, 100, 100, 100, 1] # looks like NOT works well for networks which has many units in a layer... [1, 100, 1] raise RubyBrain::Exception::TrainingDataError if inputs_set.size != outputs_set.size # raise "inputs_set and outputs_set has different size!!!!" if inputs_set.size != outputs_set.size initial_learning_rate = @learning_rate rms_error = Float::INFINITY max_training_count.times do |i_training| accumulated_errors = 0.0 # for rms inputs_set.zip(outputs_set).each do |t_input, t_output| forward_outputs = get_forward_outputs(t_input) # for rms start total_error_of_output_nodes = forward_outputs.zip(t_output).reduce(0.0) do |a, output_pair| a + ((output_pair[0] - output_pair[1])**2 / 2.0) end # end error_of_this_training_data = total_error_of_output_nodes / forward_outputs.size accumulated_errors += error_of_this_training_data # accumulated_errors += forward_outputs.zip(t_output).reduce(0.0) { |a, output_pair| a + ((output_pair[0] - output_pair[1])**2 / 2.0) } / forward_outputs.size # for rms end # if error_of_this_training_data > rms_error**2/2.0 # @learning_rate *= 10.0 # end backward_inputs = forward_outputs.zip(t_output).map { |o, t| o - t } run_backpropagate(backward_inputs) update_weights # @learning_rate = initial_learning_rate end rms_error = Math.sqrt(2.0 * accumulated_errors / inputs_set.size) # for rms # rms_error = calculate_rms_error(inputs_set, outputs_set) puts "--> #{rms_error} (#{i_training}/#{max_training_count})" break if rms_error <= tolerance end end |
#learn_only_specified_layer(layer_index, inputs_set, outputs_set, max_training_count = 50, tolerance = 0.0) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/ruby_brain/network.rb', line 221 def learn_only_specified_layer(layer_index, inputs_set, outputs_set, max_training_count=50, tolerance=0.0) # looks like works well for networks which has many layers... [1, 10, 10, 10, 1], [1, 100, 100, 100, 1] # looks like NOT works well for networks which has many units in a layer... [1, 100, 1] raise "inputs_set and outputs_set has different size!!!!" if inputs_set.size != outputs_set.size initial_learning_rate = @learning_rate rms_error = Float::INFINITY max_training_count.times do |i_training| accumulated_errors = 0.0 # for rms inputs_set.zip(outputs_set).each do |t_input, t_output| forward_outputs = get_forward_outputs(t_input) # for rms start total_error_of_output_nodes = forward_outputs.zip(t_output).reduce(0.0) do |a, output_pair| a + ((output_pair[0] - output_pair[1])**2 / 2.0) end # end error_of_this_training_data = total_error_of_output_nodes / forward_outputs.size accumulated_errors += error_of_this_training_data # accumulated_errors += forward_outputs.zip(t_output).reduce(0.0) { |a, output_pair| a + ((output_pair[0] - output_pair[1])**2 / 2.0) } / forward_outputs.size # for rms end if error_of_this_training_data > rms_error**2/2.0 @learning_rate *= 10.0 end backward_inputs = forward_outputs.zip(t_output).map { |o, t| o - t } run_backpropagate(backward_inputs) update_weights_of_layer(layer_index) @learning_rate = initial_learning_rate end rms_error = Math.sqrt(2.0 * accumulated_errors / inputs_set.size) # for rms # rms_error = calculate_rms_error(inputs_set, outputs_set) puts "--> #{rms_error} (#{i_training}/#{max_training_count})" break if rms_error <= tolerance end end |
#load_weights_from(weights_set_source) ⇒ Object
21 22 23 24 |
# File 'lib/ruby_brain/network.rb', line 21 def load_weights_from(weights_set_source) @weights_set.load_from(weights_set_source) init_network end |
#load_weights_from_yaml_file(yaml_file) ⇒ Object
Loads weights of the network from existing weights file whose format is YAML.
275 276 277 |
# File 'lib/ruby_brain/network.rb', line 275 def load_weights_from_yaml_file(yaml_file) @weights_set.load_from_yaml_file(yaml_file) end |
#run_backpropagate(backward_inputs) ⇒ Object
Calculate the networkoutput of backward propagation.
83 84 85 86 87 88 89 90 91 |
# File 'lib/ruby_brain/network.rb', line 83 def run_backpropagate(backward_inputs) a_layer_outputs = nil a_layer_inputs = backward_inputs @layers.reverse[0..-2].each do |layer| a_layer_outputs = layer.backward_outputs(a_layer_inputs) a_layer_inputs = a_layer_outputs end a_layer_outputs end |
#update_weights ⇒ Object
Updates weights actually based on the result of backward propagation
95 96 97 98 99 100 101 102 103 |
# File 'lib/ruby_brain/network.rb', line 95 def update_weights @weights_set.each_weights_with_index do |weights, i| weights.each_with_index do |wl, j| wl.each_with_index do |w, k| wl[k] = w - (@learning_rate * @layers[i].nodes[j].this_output * @layers[i+1].nodes[k].this_backward_output) end end end end |
#update_weights_of_layer(layer_index) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ruby_brain/network.rb', line 105 def update_weights_of_layer(layer_index) layer_index = @weights_set.num_sets + layer_index if layer_index < 0 @weights_set.each_weights_with_index do |weights, i| next if i != layer_index weights.each_with_index do |wl, j| wl.each_with_index do |w, k| wl[k] = w - (@learning_rate * @layers[i].nodes[j].this_output * @layers[i+1].nodes[k].this_backward_output) end end end end |