diff --git a/.github/workflows/linux_aarch64.yml b/.github/workflows/linux_aarch64.yml new file mode 100644 index 00000000..a505d1e4 --- /dev/null +++ b/.github/workflows/linux_aarch64.yml @@ -0,0 +1,37 @@ +name: Crystal CI + +on: + push: + branches: [ master ] + # pull_request: + # branches: [ master ] + +jobs: + build: + + runs-on: [linux, ARM64] + + container: + image: crystallang/crystal:nightly-alpine + + steps: + - uses: actions/checkout@v2 + + - name: Show Crystal version + run: crystal -v + + - name: Install dependencies + # run: shards install && shards update + run: shards install --ignore-crystal-version && shards update --ignore-crystal-version + + - name: Show repo version + run: scripts/version_info + + - name: Run static code analysis + run: bin/ameba --no-color + - name: Run tests + run: scripts/test_always + + # run: crystal spec + - name: Run tests (w/ junit format) + run: scripts/test_always_junit_format diff --git a/.github/workflows/crystal.yml b/.github/workflows/linux_amd64.yml similarity index 94% rename from .github/workflows/crystal.yml rename to .github/workflows/linux_amd64.yml index 2615a289..ddc95472 100644 --- a/.github/workflows/crystal.yml +++ b/.github/workflows/linux_amd64.yml @@ -3,8 +3,8 @@ name: Crystal CI on: push: branches: [ master ] - pull_request: - branches: [ master ] + # pull_request: + # branches: [ master ] jobs: build: diff --git a/spec/ai4cr/breed/manager_spec.cr b/spec/ai4cr/breed/manager_spec.cr index ea882386..da31cbc4 100644 --- a/spec/ai4cr/breed/manager_spec.cr +++ b/spec/ai4cr/breed/manager_spec.cr @@ -1,4 +1,3 @@ -require "./../../spec_helper" require "./../../spectator_helper" class MyBreed diff --git a/spec/ai4cr/error_stats_spec.cr b/spec/ai4cr/error_stats_spec.cr index d0fdbdc6..bcdbdc5c 100644 --- a/spec/ai4cr/error_stats_spec.cr +++ b/spec/ai4cr/error_stats_spec.cr @@ -1,4 +1,3 @@ -require "./../spec_helper" require "./../spectator_helper" Spectator.describe Ai4cr::ErrorStats do diff --git a/spec/ai4cr/neural_network/cmn/mini_net_manager_spec.cr b/spec/ai4cr/neural_network/cmn/mini_net_manager_spec.cr index 42dbe009..629a7ab8 100644 --- a/spec/ai4cr/neural_network/cmn/mini_net_manager_spec.cr +++ b/spec/ai4cr/neural_network/cmn/mini_net_manager_spec.cr @@ -1,4 +1,3 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Cmn::MiniNetManager do diff --git a/spec/ai4cr/neural_network/from_json/learning_styles_spec.cr b/spec/ai4cr/neural_network/from_json/learning_styles_spec.cr index aa66d431..a6dc1347 100644 --- a/spec/ai4cr/neural_network/from_json/learning_styles_spec.cr +++ b/spec/ai4cr/neural_network/from_json/learning_styles_spec.cr @@ -1,4 +1,3 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe "from_json" do diff --git a/spec/ai4cr/neural_network/from_json/mini_net_manager_spec.cr b/spec/ai4cr/neural_network/from_json/mini_net_manager_spec.cr index c715263b..794f825e 100644 --- a/spec/ai4cr/neural_network/from_json/mini_net_manager_spec.cr +++ b/spec/ai4cr/neural_network/from_json/mini_net_manager_spec.cr @@ -1,4 +1,3 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Cmn::MiniNetManager do diff --git a/spec/ai4cr/neural_network/from_json/mini_net_spec.cr b/spec/ai4cr/neural_network/from_json/mini_net_spec.cr index cbcfc1a5..d66edca5 100644 --- a/spec/ai4cr/neural_network/from_json/mini_net_spec.cr +++ b/spec/ai4cr/neural_network/from_json/mini_net_spec.cr @@ -1,4 +1,3 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe "from_json" do diff --git a/spec/ai4cr/neural_network/from_json/rnn_simple_manager_spec.cr b/spec/ai4cr/neural_network/from_json/rnn_simple_manager_spec.cr index 237716c1..112586c6 100644 --- a/spec/ai4cr/neural_network/from_json/rnn_simple_manager_spec.cr +++ b/spec/ai4cr/neural_network/from_json/rnn_simple_manager_spec.cr @@ -1,4 +1,3 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do diff --git a/spec/ai4cr/neural_network/from_json/rnn_simple_spec.cr b/spec/ai4cr/neural_network/from_json/rnn_simple_spec.cr index bfa42b37..51df1047 100644 --- a/spec/ai4cr/neural_network/from_json/rnn_simple_spec.cr +++ b/spec/ai4cr/neural_network/from_json/rnn_simple_spec.cr @@ -1,4 +1,3 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Cmn::RnnSimpleConcerns::TrainAndAdjust do diff --git a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/calc_guess_spec.cr b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/calc_guess_spec.cr index 335c2e19..93255595 100644 --- a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/calc_guess_spec.cr +++ b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/calc_guess_spec.cr @@ -1,4 +1,3 @@ -require "./../../../../spec_helper" require "./../../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleConcerns::CalcGuess do diff --git a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/data_utils_spec.cr b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/data_utils_spec.cr index 2fa509c3..89434c1b 100644 --- a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/data_utils_spec.cr +++ b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/data_utils_spec.cr @@ -1,4 +1,3 @@ -require "./../../../../spec_helper" require "./../../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleConcerns::DataUtils do diff --git a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/props_and_inits_spec.cr b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/props_and_inits_spec.cr index 3153850e..9a0c1809 100644 --- a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/props_and_inits_spec.cr +++ b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/props_and_inits_spec.cr @@ -1,4 +1,3 @@ -require "./../../../../spec_helper" require "./../../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleConcerns::PropsAndInits do diff --git a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/train_and_adjust_spec.cr b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/train_and_adjust_spec.cr index ff5d5906..6cb62649 100644 --- a/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/train_and_adjust_spec.cr +++ b/spec/ai4cr/neural_network/rnn/rnn_simple_concerns/train_and_adjust_spec.cr @@ -1,4 +1,3 @@ -require "./../../../../spec_helper" require "./../../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleConcerns::TrainAndAdjust do diff --git a/spec/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr b/spec/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr index 6ddf9a28..040f6745 100644 --- a/spec/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr +++ b/spec/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr @@ -1,17 +1,17 @@ -require "./../../../spec_helper" require "./../../../spectator_helper" Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do let(my_breed_manager) { Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager.new } let(delta_child_1) { Ai4cr::Data::Utils.rand_neg_half_to_pos_one_and_half_no_zero_no_one } - let(delta_child_2) { Ai4cr::Data::Utils.rand_neg_half_to_pos_one_and_half_no_zero_no_one } let(ancestor_adam_value) { 0.1 } let(ancestor_eve_value) { 0.9 } let(expected_child_1_value) { ancestor_adam_value + delta_child_1 * (ancestor_eve_value - ancestor_adam_value) } + let(params) { my_breed_manager.gen_params } let(config_default_randomized) { - Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + # Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + params } let(config_adam) { @@ -192,13 +192,6 @@ Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do end context "children have expected values for" do - # let(child_1) { - # # cain - # child = my_breed_manager.breed(ancestor_adam, ancestor_eve, delta: delta_child_1) - # child.name = "Cain, child of #{ancestor_adam.name} and #{ancestor_eve.name}" - # child - # } - let(ancestor_adam_json) { JSON.parse(ancestor_adam.to_json) } let(ancestor_eve_json) { JSON.parse(ancestor_eve.to_json) } let(child_1_json) { JSON.parse(child_1.to_json) } @@ -334,92 +327,131 @@ Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do end end - describe "#build_team" do - context "when using all defaults" do - it "creates specified quantity of members" do - qty_new_members = 4 - params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config - next_gen_members = my_breed_manager.build_team(qty_new_members, **params) - expect(next_gen_members.size).to eq(qty_new_members) - end + describe "#gen_params" do + let(param_keys) { params.keys.to_a } + let(expected_keys) { + [ + :name, :history_size, :io_offset, :time_col_qty, + :input_size, :output_size, :hidden_layer_qty, :hidden_size_given, + :learning_style, :bias_disabled, :bias_default, :learning_rate, + :momentum, :deriv_scale, + ] + } + it "which include expected keys" do + expect(param_keys).to eq(expected_keys) end end - describe "#train_team" do - pending "successive generations score better (i.e.: lower errors)" do - # TODO: (a) move to 'spec_bench' and (b) replace here with more 'always' tests - max_members = 10 - qty_new_members = max_members + describe "#build_team" do + context "with defaults" do + let(team_members) { my_breed_manager.build_team } - params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + it "builds a team of expected size" do + expect(team_members.size).to eq(10) + end - first_gen_members = my_breed_manager.build_team(qty_new_members, **params) - second_gen_members = my_breed_manager.train_team(inputs, outputs, first_gen_members, max_members) - third_gen_members = my_breed_manager.train_team(inputs, outputs, second_gen_members, max_members) + it "builds a team of expected class" do + expect(team_members.class).to eq(Array(Ai4cr::NeuralNetwork::Rnn::RnnSimple)) + end - first_gen_members_scored = first_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members - first_gen_members_stats = first_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + context "creates members with expected values for" do + it ":name" do + key = :name + key_string = key.to_s + team_members.each do |member| + member_json = JSON.parse(member.to_json) + expect(member_json[key_string]).to eq(params[key_string]) + end + # member = team_members.first + # member_json = JSON.parse(member.to_json) + # expect(member_json[key_string]).to eq(params[key_string]) + end + end - second_gen_members_scored = second_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members - second_gen_members_stats = second_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + # context "creates members of specified params for key" do + # let(next_gen_members) { my_breed_manager.build_team } + # it "creates members of specified params" do + # qty_new_members = 4 + # params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + # next_gen_members = my_breed_manager.build_team(qty_new_members, **params) + + # puts + # puts "params.class: #{params.class}" + # puts + # puts "params.keys: #{params.keys}" + # puts + # puts "JSON.parse(next_gen_members.first.to_json)[:name.to_s]: #{JSON.parse(next_gen_members.first.to_json)[:name.to_s]}" + # puts + + # next_gen_members.each do |member| + # member_json = JSON.parse(next_gen_members.first.to_json) + # (params.keys.to_a - [:history_size, :learning_style]).each do |key| + # key_string = key.to_s + # params_value = params[key] + + # # expect([key_string, member_json[key_string]]).to eq([key_string, params_value]) + # # assert_approximate_equality_of_nested_list([key_string, member_json[key_string]], [key_string, params_value]) + # end + # end + + # end + # end + end - third_gen_members_scored = third_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members - third_gen_members_stats = third_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + context "when given qty_new_members' and using defaults params" do + it "creates specified quantity of members" do + qty_new_members = 4 + next_gen_members = my_breed_manager.build_team(qty_new_members) + expect(next_gen_members.size).to eq(qty_new_members) + end - puts - puts "#train_team:" - puts - puts "first_gen_members_scored: #{first_gen_members_scored}" - first_gen_members_stats.each { |m| puts m } + it "creates members of specified class" do + qty_new_members = 4 + next_gen_members = my_breed_manager.build_team(qty_new_members) + member_classes = next_gen_members.map { |member| member.class.name }.sort.uniq + expect(member_classes.size).to eq(1) + expect(member_classes.first).to eq(Ai4cr::NeuralNetwork::Rnn::RnnSimple.name) + end + end - puts - puts "second_gen_members_scored: #{second_gen_members_scored}" - second_gen_members_stats.each { |m| puts m } - expect(second_gen_members_scored).to be < first_gen_members_scored + context "when given qty_new_members' and params" do + it "creates specified quantity of members" do + qty_new_members = 4 + params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + next_gen_members = my_breed_manager.build_team(qty_new_members, **params) + expect(next_gen_members.size).to eq(qty_new_members) + end - puts - puts "third_gen_members_scored: #{third_gen_members_scored}" - third_gen_members_stats.each { |m| puts m } - expect(third_gen_members_scored).to be < second_gen_members_scored + it "creates members of specified class" do + qty_new_members = 4 + params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + next_gen_members = my_breed_manager.build_team(qty_new_members, **params) + member_classes = next_gen_members.map { |member| member.class.name }.sort.uniq + expect(member_classes.size).to eq(1) + expect(member_classes.first).to eq(Ai4cr::NeuralNetwork::Rnn::RnnSimple.name) + end end end - describe "#train_team_using_sequence" do - pending "successive generations score better (i.e.: lower errors)" do - # TODO: (a) move to 'spec_bench' and (b) replace here with more 'always' tests - max_members = 10 - qty_new_members = max_members - - params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config - - first_gen_members = my_breed_manager.build_team(qty_new_members, **params) - second_gen_members = my_breed_manager.train_team_using_sequence(inputs_sequence, outputs_sequence, first_gen_members, max_members) - third_gen_members = my_breed_manager.train_team_using_sequence(inputs_sequence, outputs_sequence, second_gen_members, max_members) - - first_gen_members_scored = first_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members - first_gen_members_stats = first_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } - - second_gen_members_scored = second_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members - second_gen_members_stats = second_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } - - third_gen_members_scored = third_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members - third_gen_members_stats = third_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } - - puts - puts "#train_team_using_sequence:" - puts - puts "first_gen_members_scored: #{first_gen_members_scored}" - first_gen_members_stats.each { |m| puts m } + describe "#train_team" do + context "with defaults" do + # let(qty_new_members) { 3 } + let(team_members) { my_breed_manager.build_team } # (qty_new_members) } + + # let(inputs) { 3 } + # let(outputs) { 3 } + # let(max_members) { 3 } + + # it "" do + # expect(team_members.size). + # next_gen_members = my_breed_manager.train_team(inputs, outputs, team_members) #, max_members) + # end + end + end - puts - puts "second_gen_members_scored: #{second_gen_members_scored}" - second_gen_members_stats.each { |m| puts m } - expect(second_gen_members_scored).to be < first_gen_members_scored + describe "#train_team_using_sequence" do + end - puts - puts "third_gen_members_scored: #{third_gen_members_scored}" - third_gen_members_stats.each { |m| puts m } - expect(third_gen_members_scored).to be < second_gen_members_scored - end + describe "#cross_breed" do end end diff --git a/spec/ai4cr/team_spec.cr b/spec/ai4cr/team_spec.cr index d351badb..6f0340e3 100644 --- a/spec/ai4cr/team_spec.cr +++ b/spec/ai4cr/team_spec.cr @@ -1,4 +1,3 @@ -require "./../spec_helper" require "./../spectator_helper" Spectator.describe Ai4cr::Team do diff --git a/spec_bench/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr b/spec_bench/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr new file mode 100644 index 00000000..18d57556 --- /dev/null +++ b/spec_bench/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr @@ -0,0 +1,200 @@ +require "../../../../spec/spectator_helper" +require "../../../spec_bench_helper" +# require "../../../support/neural_network/data/*" + +Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do + let(my_breed_manager) { Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager.new } + + let(ancestor_adam_value) { 0.1 } + let(ancestor_eve_value) { 0.9 } + + let(config_default_randomized) { + Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + } + + let(config_adam) { + config_default_randomized.merge( + name: "Adam", + + bias_disabled: false, + bias_default: (ancestor_adam_value / 2.0).round(1), + + learning_rate: ancestor_adam_value, + # momentum: (1.0 - ancestor_adam_value).round(1), + momentum: ancestor_adam_value, + deriv_scale: (ancestor_adam_value / 4.0).round(1), + + history_size: 3 + ) + } + + let(config_eve) { + config_default_randomized.merge( + name: "Eve", + + bias_disabled: false, + bias_default: (ancestor_eve_value / 2.0).round(1), + + learning_rate: ancestor_eve_value, + # momentum: (1.0 - ancestor_eve_value).round(1), + momentum: ancestor_eve_value, + deriv_scale: (ancestor_eve_value / 4.0).round(1), + + history_size: 3 + ) + } + let(ancestor_adam) { + ancestor = my_breed_manager.create(**config_adam) + ancestor.mini_net_set.each do |mini_net_li| + mini_net_li.each do |mini_net_ti| + mini_net_ti.weights.map_with_index! do |row, i| + row.map_with_index! do |_col, j| + (i + j / 10.0).round(1) + end + end + end + end + ancestor.train(inputs, outputs) + # ancestor.train(inputs, outputs) + ancestor + } + let(ancestor_eve) { + ancestor = my_breed_manager.create(**config_eve) + ancestor.mini_net_set.each do |mini_net_li| + mini_net_li.each do |mini_net_ti| + mini_net_ti.weights.map_with_index! do |row, i| + row.map_with_index! do |_col, j| + -(i + j / 10.0).round(1) + end + end + end + end + ancestor.train(inputs, outputs) + # ancestor.train(inputs, outputs) + ancestor + } + + let(inputs) { + [ + [0.1, 0.2], + [0.3, 0.4], + ] + } + let(outputs) { + [ + [0.1], + [0.9], + ] + } + + let(inputs_sequence) { + [ + [ + [0.1, 0.2], + [0.3, 0.4], + ], + [ + [0.3, 0.4], + [0.5, 0.6], + ], + [ + [0.5, 0.6], + [0.7, 0.8], + ], + ] + } + let(outputs_sequence) { + [ + [ + [0.1], + [0.9], + ], + [ + [0.9], + [0.5], + ], + [ + [0.5], + [0.3], + ], + ] + } + + describe "#train_team" do + it "successive generations score better (i.e.: lower errors)" do + # TODO: (a) move to 'spec_bench' and (b) replace here with more 'always' tests + max_members = 10 + qty_new_members = max_members + + params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + + first_gen_members = my_breed_manager.build_team(qty_new_members, **params) + second_gen_members = my_breed_manager.train_team(inputs, outputs, first_gen_members, max_members) + third_gen_members = my_breed_manager.train_team(inputs, outputs, second_gen_members, max_members) + + first_gen_members_scored = first_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members + first_gen_members_stats = first_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + + second_gen_members_scored = second_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members + second_gen_members_stats = second_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + + third_gen_members_scored = third_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members + third_gen_members_stats = third_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + + puts + puts "#train_team:" + puts + puts "first_gen_members_scored: #{first_gen_members_scored}" + first_gen_members_stats.each { |m| puts m } + + puts + puts "second_gen_members_scored: #{second_gen_members_scored}" + second_gen_members_stats.each { |m| puts m } + expect(second_gen_members_scored).to be < first_gen_members_scored + + puts + puts "third_gen_members_scored: #{third_gen_members_scored}" + third_gen_members_stats.each { |m| puts m } + expect(third_gen_members_scored).to be < second_gen_members_scored + end + end + + describe "#train_team_using_sequence" do + it "successive generations score better (i.e.: lower errors)" do + # TODO: (a) move to 'spec_bench' and (b) replace here with more 'always' tests + max_members = 10 + qty_new_members = max_members + + params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config + + first_gen_members = my_breed_manager.build_team(qty_new_members, **params) + second_gen_members = my_breed_manager.train_team_using_sequence(inputs_sequence, outputs_sequence, first_gen_members, max_members) + third_gen_members = my_breed_manager.train_team_using_sequence(inputs_sequence, outputs_sequence, second_gen_members, max_members) + + first_gen_members_scored = first_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members + first_gen_members_stats = first_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + + second_gen_members_scored = second_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members + second_gen_members_stats = second_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + + third_gen_members_scored = third_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members + third_gen_members_stats = third_gen_members.map { |member| "#{member.birth_id} => #{member.error_stats.plot_error_distance_history} @ #{member.error_stats.score}" } + + puts + puts "#train_team_using_sequence:" + puts + puts "first_gen_members_scored: #{first_gen_members_scored}" + first_gen_members_stats.each { |m| puts m } + + puts + puts "second_gen_members_scored: #{second_gen_members_scored}" + second_gen_members_stats.each { |m| puts m } + expect(second_gen_members_scored).to be < first_gen_members_scored + + puts + puts "third_gen_members_scored: #{third_gen_members_scored}" + third_gen_members_stats.each { |m| puts m } + expect(third_gen_members_scored).to be < second_gen_members_scored + end + end +end diff --git a/src/ai4cr/breed/manager.cr b/src/ai4cr/breed/manager.cr index 9226553e..58d77d9b 100644 --- a/src/ai4cr/breed/manager.cr +++ b/src/ai4cr/breed/manager.cr @@ -46,7 +46,8 @@ module Ai4cr # end # ``` - MAX_MEMBERS_DEFAULT = 10 + QTY_NEW_MEMBERS_DEFAULT = 10 + MAX_MEMBERS_DEFAULT = QTY_NEW_MEMBERS_DEFAULT ############################################################################ # TODO: WHY is this required? @@ -89,6 +90,10 @@ module Ai4cr @@counter.reset(T.name, value) end + def gen_params + T.new.config + end + def create(**params) # i.e.: via NO parents channel = Channel(Int32).new @@ -232,6 +237,21 @@ module Ai4cr qty_new_members.times.to_a.map { channel.receive } end + def build_team(qty_new_members : Int32 = QTY_NEW_MEMBERS_DEFAULT) : Array(T) + params = gen_params + build_team(qty_new_members, **params) + end + + def train_team(inputs, outputs, team_members : Array(T), max_members = MAX_MEMBERS_DEFAULT, train_qty = 1) + team_members = train_team_in_parallel(inputs, outputs, team_members, train_qty) + + team_members = cross_breed(team_members) + + team_members = train_team_in_parallel(inputs, outputs, team_members, train_qty) + + (team_members.sort_by { |contestant| contestant.error_stats.score })[0..max_members - 1] + end + def train_team_using_sequence(inputs_sequence, outputs_sequence, team_members : Array(T), max_members = MAX_MEMBERS_DEFAULT, train_qty = 1) inputs_sequence.each_with_index do |inputs, i| outputs = outputs_sequence[i] @@ -248,16 +268,6 @@ module Ai4cr (team_members.sort_by { |contestant| contestant.error_stats.score })[0..max_members - 1] end - def train_team(inputs, outputs, team_members : Array(T), max_members = MAX_MEMBERS_DEFAULT, train_qty = 1) - team_members = train_team_in_parallel(inputs, outputs, team_members, train_qty) - - team_members = cross_breed(team_members) - - team_members = train_team_in_parallel(inputs, outputs, team_members, train_qty) - - (team_members.sort_by { |contestant| contestant.error_stats.score })[0..max_members - 1] - end - def train_team_in_parallel(inputs, outputs, team_members, train_qty) channel = Channel(T).new qty = team_members.size