Skip to content

Commit 9f41353

Browse files
authored
Drhuffman12/add team utils part 7 redo (#63)
* update command line for example re 'spec_bench/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr' * drhuffman12/add_team_utils_part_7_redo 'src' changes re clone vs to/from json * drhuffman12/add_team_utils_part_7_redo 'spec' and 'spec_bench' changes re clone vs to/from json, etc * drhuffman12/add_team_utils_part_7_redo formatting * drhuffman12/add_team_utils_part_7_redo log less often * drhuffman12/add_team_utils_part_7_redo log more often * drhuffman12/add_team_utils_part_7_redo add name suffix re breed type * drhuffman12/add_team_utils_part_7_redo formatting * drhuffman12/add_team_utils_part_7_redo round the comparative 'when_delta' times * drhuffman12/add_team_utils_part_7_redo pend a 'chain' spec (for now) * drhuffman12/add_team_utils_part_7_redo TODO: Refactor and enable breeding (similar to RnnSimple)! (and adjust specs) * drhuffman12/add_team_utils_part_7_redo enable tests re w/ more time col's and additional io files combo's * drhuffman12/add_team_utils_part_7_redo adjust propagation_function to handle NAN and Infinity; TODO: review andlikewise for other prop func cases * drhuffman12/add_team_utils_part_7_redo formatting * drhuffman12/add_team_utils_part_7_redo more NAN handling for 'Cmn::MiniNetConcerns::CalcGuess#propagation_function'; ameba-ize * drhuffman12/add_team_utils_part_7_redo misc tweeks * drhuffman12/add_team_utils_part_7_redo add 'purge_replace' helper * drhuffman12/add_team_utils_part_7_redo formatting * drhuffman12/add_team_utils_part_7_redo only show purge comment if members were purged * drhuffman12/add_team_utils_part_7_redo update test data file path * drhuffman12/add_team_utils_part_7_redo bench tests: revert from tiny hidden size to auto-calc'd, skip team sizes of 1 and 2 members for more complex RNN nets/data; re-org 'train_team_using_sequence'; start RELU net weights tiny; step_update_weights as serial instead of parallel; comment out 'purge_error_limit' code; formatting * drhuffman12/add_team_utils_part_7_redo re-enable purging/replacing members; re-enable 'traing_qty' * drhuffman12/add_team_utils_part_7_redo formatting * drhuffman12/add_team_utils_part_7_redo re-enable 'purge_error_limit' params for 'train_team_using_sequence(..)' * drhuffman12/add_team_utils_part_7_redo rename to 'infinite?' * drhuffman12/add_team_utils_part_7_redo members added during purge get named 'P' * drhuffman12/add_team_utils_part_7_redo use 'score' in the purge * move 'train_qty' so as to affect all tests under "when using a text file as io data" * drhuffman12/add_team_utils_part_7_redo move 'train_qty' so as to affect all tests under "when using a text file as io data" * drhuffman12/add_team_utils_part_7_redo adjust the purge process * drhuffman12/add_team_utils_part_7_redo switch back to using 'score' instead of 'distance' for purging * drhuffman12/add_team_utils_part_7_redo re-enable team of 8 in benches * drhuffman12/add_team_utils_part_7_redo add a hidden layer for the rnn text spec * drhuffman12/add_team_utils_part_7_redo bump up to 16 tc's and 4 hl's * drhuffman12/add_team_utils_part_7_redo bump down to 8 tc's and 4 hl's * drhuffman12/add_team_utils_part_7_redo in 'purge_replace', breed purged member with rand_excluding new membere so we retain some of the training * drhuffman12/add_team_utils_part_7_redo move expect's next to each other * drhuffman12/add_team_utils_part_7_redo note 'inputs_sequence' index 'i' in purge output * drhuffman12/add_team_utils_part_7_redo add 'weight_init_scale*' and auto-scale it; convert some 'TextFile' methods to class methods; add example unicode text file; large vs small RNN size test params; add text output of expected vs actual guesses * drhuffman12/add_team_utils_part_7_redo output formatting * drhuffman12/add_team_utils_part_7_redo adjust outputs and for a 'mid-sized rnn' * drhuffman12/add_team_utils_part_7_redo output should handle less than 32 bits * drhuffman12/add_team_utils_part_7_redo misc tweeks; bump 1st textfile team size up to 10 * drhuffman12/add_team_utils_part_7_redo adjust rnn params; add and revert auto_shrink_weights * drhuffman12/add_team_utils_part_7_redo add timestamp * drhuffman12/add_team_utils_part_7_redo update shards * drhuffman12/add_team_utils_part_7_redo update shards, ameba formatting * drhuffman12/add_team_utils_part_7_redo ameba formatting * drhuffman12 misc cleanup re Crystal v1.0 and other updated shards * drhuffman12 add 'default_to_bit_size' e.g.: to allow forcing from 32bit utf down to 8bit ascii (ignoring higher bits) * drhuffman12 adjust bench params and update README.md * drhuffman12 try 4 hidden layers * drhuffman12 spec_bench w/ 3 hidden layers; TODO: Replace(?)/Supplement(?) below with actual UTF-to-ASCII conversion! (And ASCII-to-UTF reversion) * drhuffman12 tweek bench params * drhuffman12 attempts to get better and quicker RNN results and improved visuals of result progress * drhuffman12/add_team_utils_part_7_redo add system monitoring data to the 'tmp/log.txt' file; formatting * drhuffman12 adjust mem logging; formatting * drhuffman12 add histogram of correct chars * drhuffman12 formatting * drhuffman12 trim logging * drhuffman12 round percentages * drhuffman12 adjust histograms * drhuffman12 adjust histograms * drhuffman12 adjust histograms * drhuffman12 adjust histograms * drhuffman12 reset histograms * drhuffman12 rename 'all_hists' to 'recent_hists' * drhuffman12 set default_to_bit_size to 8 for 'examples/rnn_simple_manager_example.cr * drhuffman12 add second round of training (hopefully will all be 6/6 correct) for whole set of io's in 'examples/rnn_simple_manager_example.cr * drhuffman12 add current time to logging * drhuffman12 add auto-save option to manager * drhuffman12 code cleanup * drhuffman12 formatting * drhuffman12 formatting * drhuffman12 fix 'validate! re hidden_size_given; note re 'implement bi-directional RNN in the next phase' * drhuffman12 Drop 'PURGE_ERROR_LIMIT_SCALE' from 1e12 to 1e4 (to keep weights and guesses from going extreme). * drhuffman12 revert 'INPUT_SIZE_MIN' to '2' with TODO comment * drhuffman12 better error handling for auto-saving the trained nets * drhuffman12 adjust naming for auto-save of nets to show which guesses are correct
1 parent 54cf06e commit 9f41353

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2022
-917
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ e.g.: `time crystal spec --release`
5656

5757
Use the `-Dpreview_mt` (for `crystal build` or `-D preview_mt` for `crystal spec`) flag for multithreading.
5858

59-
e.g.: `CRYSTAL_WORKERS=14 crystal spec spec/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr --release -D preview_mt`
59+
e.g.: `time CRYSTAL_WORKERS=14 crystal spec spec_bench/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr --release -D preview_mt`
60+
e.g.: `time CRYSTAL_WORKERS=24 crystal spec spec_bench/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr --release -D preview_mt > tmp/log.txt 2>&1`
61+
62+
(Personally, as for how many `CRYSTAL_WORKERS`, I'd recommend keep it to less than the number of cores in your CPU, so that you leave at least one or two cores for the OS and apps.)
6063

6164
See also:
6265
* https://crystal-lang.org/2019/09/23/crystal-0.31.0-released.html
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Run via: `time CRYSTAL_WORKERS=24 crystal run examples/rnn_simple_manager_example.cr -Dpreview_mt --release > tmp/log.txt`
2+
# (Adjust the 'CRYSTAL_WORKERS=24' as desired.)
3+
# Follow `tmp/log.txt' in your IDE or in console (i.e.: `tail -f tmp/log.txt`)
4+
# Be on the look out for high `percent_correct: x of x` in the 'tmp/log.txt file'
5+
# Monitor your Ram and CPU usage!
6+
# (This seems to stablize at around about 4 Gb and 1/3 of my system's AMD Ryzen 7 1700X CPU.)
7+
# NOTE: Training results look promising, but tend to be more successful towards the 'more future' side of the outputs.
8+
# So, implement bi-directional RNN in the next phase, in hopes of balancing out the successfulness of the
9+
# 'less future' vs 'more future' guesses.
10+
11+
require "./../src/ai4cr"
12+
13+
class Runner
14+
getter file_path : String
15+
16+
def initialize(@file_path)
17+
end
18+
19+
def compare_successive_training_rounds(
20+
io_offset, time_col_qty,
21+
inputs_sequence, outputs_sequence,
22+
hidden_layer_qty, hidden_size_given,
23+
qty_new_members,
24+
my_breed_manager, max_members,
25+
train_qty,
26+
io_set_text_file
27+
)
28+
puts
29+
puts "v"*40
30+
puts "successive generations (should) score better (?) .. max_members: #{max_members} .. start"
31+
when_before = Time.local
32+
puts "when_before: #{when_before}"
33+
puts "file_path: #{file_path}"
34+
puts
35+
36+
params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new(
37+
io_offset: io_offset,
38+
time_col_qty: time_col_qty,
39+
input_size: inputs_sequence.first.first.size,
40+
output_size: outputs_sequence.first.first.size,
41+
hidden_layer_qty: hidden_layer_qty,
42+
hidden_size_given: hidden_size_given
43+
).config
44+
45+
puts "inputs_sequence.size: #{inputs_sequence.size}"
46+
puts "inputs_sequence.first.size: #{inputs_sequence.first.size}"
47+
puts "inputs_sequence.first.first.size: #{inputs_sequence.first.first.size}"
48+
puts "inputs_sequence.class: #{inputs_sequence.class}"
49+
puts "outputs_sequence.class: #{outputs_sequence.class}"
50+
puts "params: #{params}"
51+
52+
puts "* build/train teams"
53+
puts "\n * first_gen_members (building)..."
54+
first_gen_members = my_breed_manager.build_team(qty_new_members, **params)
55+
puts "\n * second_gen_members (breeding and training; after training first_gen_members)..."
56+
second_gen_members = my_breed_manager.train_team_using_sequence(inputs_sequence, outputs_sequence, first_gen_members, io_set_text_file, max_members, train_qty) # , block_logger: train_team_using_sequence_logger)
57+
puts "\n * third_gen_members (breeding and training; after training second_gen_members) ..."
58+
third_gen_members = my_breed_manager.train_team_using_sequence(inputs_sequence, outputs_sequence, second_gen_members, io_set_text_file, max_members, train_qty) # , block_logger: train_team_using_sequence_logger)
59+
60+
puts "* score and stats ..."
61+
p "."
62+
first_gen_members_scored = first_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members
63+
first_gen_members_stats = first_gen_members.map { |member| member.error_hist_stats }
64+
65+
p "."
66+
second_gen_members_scored = second_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members
67+
second_gen_members_stats = second_gen_members.map { |member| member.error_hist_stats }
68+
69+
p "."
70+
third_gen_members_scored = third_gen_members.map { |member| member.error_stats.score }.sum / qty_new_members
71+
third_gen_members_stats = third_gen_members.map { |member| member.error_hist_stats }
72+
73+
puts
74+
puts "#train_team_using_sequence (text from Bible):"
75+
puts
76+
puts "first_gen_members_scored: #{first_gen_members_scored}"
77+
first_gen_members_stats.each { |m| puts m }
78+
79+
puts
80+
puts "second_gen_members_scored: #{second_gen_members_scored}"
81+
second_gen_members_stats.each { |m| puts m }
82+
83+
puts
84+
puts "third_gen_members_scored: #{third_gen_members_scored}"
85+
third_gen_members_stats.each { |m| puts m }
86+
87+
when_after = Time.local
88+
puts "when_after: #{when_after}"
89+
when_delta = when_after - when_before
90+
puts "when_delta: #{(when_delta.total_seconds / 60.0).round(1)} minutes
91+
"
92+
puts
93+
puts "successive generations score better (?) .. max_members: #{max_members} .. end"
94+
puts "-"*40
95+
puts
96+
end
97+
end
98+
99+
####
100+
101+
my_breed_manager = Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager.new
102+
103+
file_path = "./spec_bench/support/neural_network/data/bible_utf/eng-web_002_GEN_01_read.txt"
104+
file_type_raw = Ai4cr::Utils::IoData::FileType::Raw
105+
prefix_raw_qty = 0
106+
prefix_raw_char = " "
107+
default_to_bit_size = 8
108+
109+
io_set_text_file = Ai4cr::Utils::IoData::TextFileIodBits.new(
110+
file_path, file_type_raw,
111+
prefix_raw_qty, prefix_raw_char,
112+
default_to_bit_size
113+
)
114+
115+
# re 'compare_successive_training_rounds'
116+
time_col_qty = 6 # 25
117+
io_offset = time_col_qty
118+
ios = io_set_text_file.iod_to_io_set_with_offset_time_cols(time_col_qty, io_offset)
119+
120+
inputs_sequence = ios[:input_set]
121+
outputs_sequence = ios[:output_set]
122+
123+
hidden_layer_qty = 3
124+
hidden_size_given = 100 # 100 # 200
125+
126+
max_members = 10
127+
qty_new_members = max_members
128+
129+
train_qty = 2
130+
131+
puts
132+
puts "*"*40
133+
puts "my_breed_manager: #{my_breed_manager}"
134+
puts "io_set_text_file: #{io_set_text_file}"
135+
puts "v"*40
136+
puts "io_set_text_file.raw: #{io_set_text_file.raw}"
137+
puts "^"*40
138+
puts
139+
puts "io_set_text_file.raw.size: #{io_set_text_file.raw.size}"
140+
puts "io_set_text_file.raw.size: #{io_set_text_file.raw.class}"
141+
puts
142+
puts "io_set_text_file.iod.size: #{io_set_text_file.iod.size}"
143+
puts "io_set_text_file.iod.class: #{io_set_text_file.iod.class}"
144+
puts "io_set_text_file.iod.first.size: #{io_set_text_file.iod.first.size}"
145+
puts "io_set_text_file.iod.first.class: #{io_set_text_file.iod.first.class}"
146+
puts "io_set_text_file.iod.first.first.class: #{io_set_text_file.iod.first.first.class}"
147+
148+
puts "-"*40
149+
puts
150+
151+
r = Runner.new(file_path)
152+
153+
r.compare_successive_training_rounds(
154+
io_offset, time_col_qty,
155+
inputs_sequence, outputs_sequence,
156+
hidden_layer_qty, hidden_size_given,
157+
qty_new_members,
158+
my_breed_manager, max_members,
159+
train_qty,
160+
io_set_text_file
161+
)
162+
163+
r.compare_successive_training_rounds(
164+
io_offset, time_col_qty,
165+
inputs_sequence, outputs_sequence,
166+
hidden_layer_qty, hidden_size_given,
167+
qty_new_members,
168+
my_breed_manager, max_members,
169+
train_qty,
170+
io_set_text_file
171+
)

shard.yml

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
name: ai4cr
2-
version: 0.1.23
2+
version: 0.1.24
33

44
authors:
55
- Daniel Huffman <drhuffman12@yahoo.com>
66

7-
crystal: ">= 0.36.0"
8-
# crystal: 1.0
7+
# crystal: ">= 1.0.0"
98

109
license: MIT
1110

@@ -20,32 +19,19 @@ dependencies:
2019

2120
development_dependencies:
2221

23-
## Un-comment/edit after Crystal 0.36.0 or 1.0 compatible:
2422
ameba:
2523
github: crystal-ameba/ameba
26-
version: ~> 0.13.4
27-
# branch: master
28-
# # version: ~> 0.13.3
29-
# ## REVERT to crystal-ameba/ameba after it is Crystal 1.0 compatible.
30-
# ## See also: https://github.com/crystal-ameba/ameba/pull/173
31-
# github: drhuffman12/ameba
32-
# # branch: drhuffman12/bump_crystal_version_to_1
24+
version: ~> 0.14.1
3325

3426
## Un-comment/edit after Crystal 0.36.0 or 1.0 compatible:
3527
# icr:
3628
# github: crystal-community/icr
3729
# branch: master
3830

39-
## Un-comment/edit after Crystal 0.36.0 or 1.0 compatible:
4031
spectator:
41-
# gitlab: arctic-fox/spectator
42-
# branch: master
43-
# version: ">= 0.9.31"
44-
45-
github: drhuffman12/spectator
46-
# branch: drhuffman12/bump_crystal_version_to_1
47-
# branch: drhuffman12/master
48-
branch: drhuffman12/bump_crystal_version_to_0_36_0b
32+
gitlab: arctic-fox/spectator
33+
branch: master
34+
version: ">= 0.9.33"
4935

5036
## Un-comment after Crystal 1.0 compatible:
5137
# aasm:
@@ -59,18 +45,23 @@ development_dependencies:
5945

6046
faker:
6147
github: askn/faker
48+
# github: osacar/faker
49+
# version: "0.6.0"
6250

6351
# # TODO: Fix ameba dependencies or wait for newer version of crystal-coverage (aka https://github.com/anykeyh/crystal-coverage)
6452
# # Error is:
6553
# # ```
6654
# # 12 | new(YAML::ParseContext.new, parse_yaml(string_or_io))
6755
# # ^--
6856
# # Error: wrong number of arguments for 'Ameba::Rule::Lint::Syntax.new' (given 2, expected 0..1)
69-
57+
# # ...
7058
# # Overloads are:
7159
# # - Ameba::Rule::Lint::Syntax.new(config = nil)
72-
60+
# # ...
7361
# # make[1]: *** [Makefile:8: bin/ameba] Error 1
7462
# # ```
7563
# coverage:
7664
# github: anykeyh/crystal-coverage
65+
66+
hardware:
67+
github: crystal-community/hardware

spec/ai4cr/breed/manager_spec.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class MyBreed
2525
def initialize(@name, @some_value, @history_size = 2)
2626
@error_stats = Ai4cr::ErrorStats.new(history_size)
2727
end
28+
29+
def clone
30+
MyBreed.new(self.name, self.some_value, self.history_size)
31+
end
2832
end
2933

3034
class MyBreedManager < Ai4cr::Breed::Manager(MyBreed)

spec/ai4cr/neural_network/cmn/chain_spec.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ describe Ai4cr::NeuralNetwork::Cmn::Chain do
156156
(cns.errors.empty?).should be_true
157157
end
158158

159-
it "updates last net's outputs when guessing" do
159+
pending "updates last net's outputs when guessing" do
160160
last_net_output_before = cns.net_set.last.outputs_guessed.clone
161161
(cns.guesses_best).should eq(expected_inital_outputs)
162162
(cns.guesses_best.size).should eq(expected_inital_outputs.size)

spec/ai4cr/neural_network/rnn/rnn_simple_manager_spec.cr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do
334334
:name, :history_size, :io_offset, :time_col_qty,
335335
:input_size, :output_size, :hidden_layer_qty, :hidden_size_given,
336336
:learning_style, :bias_disabled, :bias_default, :learning_rate,
337-
:momentum, :deriv_scale,
337+
:momentum, :deriv_scale, :weight_init_scale_given,
338338
]
339339
}
340340
it "which include expected keys" do
@@ -355,7 +355,7 @@ Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do
355355
end
356356

357357
context "creates members with expected values for" do
358-
it ":name" do
358+
pending ":name" do
359359
key = :name
360360
key_string = key.to_s
361361
team_members.each do |member|
@@ -408,7 +408,7 @@ Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do
408408
it "creates members of specified class" do
409409
qty_new_members = 4
410410
next_gen_members = my_breed_manager.build_team(qty_new_members)
411-
member_classes = next_gen_members.map { |member| member.class.name }.sort.uniq
411+
member_classes = next_gen_members.map(&.class.name).sort!.uniq!
412412
expect(member_classes.size).to eq(1)
413413
expect(member_classes.first).to eq(Ai4cr::NeuralNetwork::Rnn::RnnSimple.name)
414414
end
@@ -426,7 +426,7 @@ Spectator.describe Ai4cr::NeuralNetwork::Rnn::RnnSimpleManager do
426426
qty_new_members = 4
427427
params = Ai4cr::NeuralNetwork::Rnn::RnnSimple.new.config
428428
next_gen_members = my_breed_manager.build_team(qty_new_members, **params)
429-
member_classes = next_gen_members.map { |member| member.class.name }.sort.uniq
429+
member_classes = next_gen_members.map(&.class.name).sort!.uniq!
430430
expect(member_classes.size).to eq(1)
431431
expect(member_classes.first).to eq(Ai4cr::NeuralNetwork::Rnn::RnnSimple.name)
432432
end

spec/ai4cr/team_spec.cr

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)