brains 0.1.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0d640546a10c8984b876f7f95feeab5cddc10f39
4
+ data.tar.gz: ed2c32d65a0cd4cda1ca00667f821b95e5cc70c7
5
+ SHA512:
6
+ metadata.gz: 95bb48840ee28b6d10f527b0b2efc876db9da382669e5e66027305bd92651846ec9343a217dba1fef4a9d95366cb240d1aeb08a8c73aa98062e58785b81291ec
7
+ data.tar.gz: 77f3df827145cd2314238a5eb0c09f9f52bbf016dd3a6cc9786c472fe5298f7d2e014edd3642bdc1155f15c0bf630176b6317ac45779d16e5cbf52a07c03b222
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.3
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at joseph.dayo@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in brains.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Joseph Emmanuel Dayo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,159 @@
1
+ # Brains
2
+
3
+ A Feedforward neural network toolkit for JRuby. Easily add machine learning features
4
+ to your ruby application using this Gem. Though there are faster native C implementations
5
+ this java backend provides a balance of performance and ease of use.
6
+
7
+ ## Installation
8
+
9
+ Do note that this gem requires JRuby as it uses a java backend to run the neural network
10
+ computations.
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'brains'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install brains
25
+
26
+ ## Usage
27
+
28
+ The brains gem contains facilities for training and using the feedforward neural network
29
+
30
+ Training (XOR example)
31
+ --------
32
+
33
+ Initialize the neural net backend
34
+
35
+ ```ruby
36
+ require 'brains'
37
+
38
+
39
+ # Build a 3 layer network: 4 input neurons, 4 hidden neurons, 3 output neurons
40
+ # Bias neurons are automatically added to input + hidden layers; no need to specify these
41
+ # 5 = 4 in one hidden layer + 1 output neuron (input neurons not counted)
42
+
43
+ nn = Brains::Net.create(2, 1, 5, { neurons_per_layer: 4 })
44
+ nn.randomize_weights
45
+ ```
46
+
47
+ Consider that we want to train the neural network to handle XOR computations
48
+
49
+ ```
50
+ A B A XOR B
51
+ 1 1 0
52
+ 1 0 1
53
+ 0 1 1
54
+ 0 0 0
55
+ ```
56
+
57
+ First we build the training data. This is an array of arrays with each item
58
+ in the following format:
59
+
60
+ ```
61
+ [
62
+ [[input1, input2, input3....], [expected1, expected2, expected3 ...]]
63
+ [[input1, input2, input3....], [expected1, expected2, expected3 ...]]
64
+ ]
65
+ ```
66
+
67
+ ```ruby
68
+ training_data = [
69
+ [[0.9, 0.9], [0.1]],
70
+ [[0.9, 0.1], [0.9]],
71
+ [[0.1, 0.9], [0.9]],
72
+ [[0.1, 0.1], [0.1]],
73
+ ]
74
+ ```
75
+ Note that we map 1 = 0.9 and 0 = 0.1 since using absolute 1 and 0s might cause
76
+ issues with certain neural networks. There are other techniques to "normalize"
77
+ input, but this is beyond the scope of this example.
78
+
79
+ Start training on the data by calling optimize. Here we use 0.01 as the expected
80
+ MSE error before terminating and 1000 as the max epochs.
81
+
82
+ ```ruby
83
+ result = nn.optimize(training_data, 0.01, 1_000 ) { |i, error|
84
+ puts "#{i} #{error}"
85
+ }
86
+ ```
87
+
88
+ To test the neural network you can call the feed method.
89
+
90
+ nn.feed( [test_input1, test_input2, .....]) => [output1, output2, ...]
91
+
92
+ Check if the network is trained. There are more advanced and proper techniques to check if
93
+ a network is sufficiently trained, but this is beyond the scope of this example.
94
+
95
+ ```ruby
96
+ # test on untrained data
97
+ test_data = [
98
+ [0.9, 0.9],
99
+ [0.9, 0.1],
100
+ [0.1, 0.9],
101
+ [0.1, 0.1]
102
+ ]
103
+
104
+ results = test_data.collect { |item|
105
+ nn.feed(item)
106
+ }
107
+
108
+ p results
109
+
110
+ [[0.19717958808009528], [0.7983320405281495], [0.8386219299757574], [0.16609147896733775]]
111
+ ```
112
+
113
+ Using the test data we can see the correlation and the neural network function now approximates
114
+ the xor function with the desired error:
115
+
116
+ ```
117
+ [0.9, 0.9] => [0.19717958808009528]
118
+ [0.9, 0.1] => [0.7983320405281495]
119
+ [0.1, 0.9] => [0.8386219299757574]
120
+ [0.1, 0.1] => [0.16609147896733775]
121
+ ```
122
+
123
+ Saving brain state
124
+ ==================
125
+
126
+ Save the neuron state at any time to a string using to_json
127
+
128
+ ```ruby
129
+ saved_state = nn.to_json
130
+ ```
131
+
132
+ You can then save it to a file. You can then load it back using load()
133
+
134
+ ```ruby
135
+ nn = Brains::Net.load(saved_state)
136
+ ```
137
+
138
+ For other samples please take a look at the example folder.
139
+
140
+ Java Neural Network backend is based on:
141
+
142
+ https://github.com/jedld/brains
143
+
144
+ You can compile the java source code as brains.jar and use it directly with this gem.
145
+
146
+ ## Development
147
+
148
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
149
+
150
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
151
+
152
+ ## Contributing
153
+
154
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/brains. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
155
+
156
+
157
+ ## License
158
+
159
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "brains"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'brains/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "brains"
8
+ spec.version = Brains::VERSION
9
+ spec.authors = ["Joseph Emmanuel Dayo"]
10
+ spec.email = ["joseph.dayo@gmail.com"]
11
+
12
+ spec.summary = %q{A feedforward neural network library for JRuby}
13
+ spec.description = %q{A feedforward neural network library for JRuby}
14
+ spec.homepage = "https://github.com/jedld/brains-jruby"
15
+ spec.license = "MIT"
16
+ spec.platform = "java"
17
+
18
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
20
+ if spec.respond_to?(:metadata)
21
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
22
+ else
23
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.12"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ end
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'brains'
4
+
5
+ # This neural network will predict the species of an iris based on sepal and petal size
6
+ # Dataset: http://en.wikipedia.org/wiki/Iris_flower_data_set
7
+
8
+ rows = File.readlines("iris.data").map {|l| l.chomp.split(',') }
9
+
10
+ rows.shuffle!
11
+
12
+ label_encodings = {
13
+ "Iris-setosa" => [1, 0, 0],
14
+ "Iris-versicolor" => [0, 1, 0],
15
+ "Iris-virginica" => [0, 0 ,1]
16
+ }
17
+
18
+ x_data = rows.map {|row| row[0,4].map(&:to_f) }
19
+ y_data = rows.map {|row| label_encodings[row[4]] }
20
+
21
+ # Normalize data values before feeding into network
22
+ normalize = -> (val, high, low) { (val - low) / (high - low) } # maps input to float between 0 and 1
23
+
24
+ columns = (0..3).map do |i|
25
+ x_data.map {|row| row[i] }
26
+ end
27
+
28
+ x_data.map! do |row|
29
+ row.map.with_index do |val, j|
30
+ max, min = columns[j].max, columns[j].min
31
+ normalize.(val, max, min)
32
+ end
33
+ end
34
+
35
+ x_train = x_data.slice(0, 100)
36
+ y_train = y_data.slice(0, 100)
37
+
38
+ x_test = x_data.slice(100, 50)
39
+ y_test = y_data.slice(100, 50)
40
+
41
+ test_cases = []
42
+ x_train.each_with_index do |x, index|
43
+ test_cases << [x, y_train[index] ]
44
+ end
45
+
46
+ validation_cases = []
47
+ x_test.each_with_index do |x, index|
48
+ test_cases << [x, y_test[index] ]
49
+ end
50
+
51
+ # Build a 3 layer network: 4 input neurons, 4 hidden neurons, 3 output neurons
52
+ # Bias neurons are automatically added to input + hidden layers; no need to specify these
53
+ nn = Brains::Net.create(4, 3, 7, { neurons_per_layer: 4 })
54
+ nn.randomize_weights
55
+
56
+ prediction_success = -> (actual, ideal) {
57
+ predicted = (0..2).max_by {|i| actual[i] }
58
+ ideal[predicted] == 1
59
+ }
60
+
61
+ mse = -> (actual, ideal) {
62
+ errors = actual.zip(ideal).map {|a, i| a - i }
63
+ (errors.inject(0) {|sum, err| sum += err**2}) / errors.length.to_f
64
+ }
65
+
66
+ error_rate = -> (errors, total) { ((errors / total.to_f) * 100).round }
67
+
68
+ run_test = -> (nn, inputs, expected_outputs) {
69
+ success, failure, errsum = 0,0,0
70
+ inputs.each.with_index do |input, i|
71
+ output = nn.feed input
72
+ prediction_success.(output, expected_outputs[i]) ? success += 1 : failure += 1
73
+ errsum += mse.(output, expected_outputs[i])
74
+ end
75
+ [success, failure, errsum / inputs.length.to_f]
76
+ }
77
+
78
+ puts "Testing the untrained network..."
79
+
80
+ success, failure, avg_mse = run_test.(nn, x_test, y_test)
81
+
82
+ puts "Untrained classification success: #{success}, failure: #{failure} (classification error: #{error_rate.(failure, x_test.length)}%, mse: #{(avg_mse * 100).round(2)}%)"
83
+
84
+
85
+ puts "\nTraining the network...\n\n"
86
+
87
+ t1 = Time.now
88
+ result = nn.optimize(test_cases, 0.01, 1_000 ) { |i, error|
89
+ puts "#{i} #{error}"
90
+ }
91
+
92
+ # puts result
93
+ puts "\nDone training the network: #{result[:iterations]} iterations, #{(result[:error] * 100).round(2)}% mse, #{(Time.now - t1).round(1)}s"
94
+
95
+
96
+ puts "\nTesting the trained network..."
97
+
98
+ success, failure, avg_mse = run_test.(nn, x_test, y_test)
99
+
100
+ puts "Trained classification success: #{success}, failure: #{failure} (classification error: #{error_rate.(failure, x_test.length)}%, mse: #{(avg_mse * 100).round(2)}%)"
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'brains'
4
+
5
+
6
+ # Build a 3 layer network: 4 input neurons, 4 hidden neurons, 3 output neurons
7
+ # Bias neurons are automatically added to input + hidden layers; no need to specify these
8
+ # 5 = 4 in one hidden layer + 1 output neuron (input neurons not counted)
9
+
10
+ nn = Brains::Net.create(2, 1, 5, { neurons_per_layer: 4 })
11
+ nn.randomize_weights
12
+
13
+ # A B A XOR B
14
+ # 1 1 0
15
+ # 1 0 1
16
+ # 0 1 1
17
+ # 0 0 0
18
+
19
+ training_data = [
20
+ [[0.9, 0.9], [0.1]],
21
+ [[0.9, 0.1], [0.9]],
22
+ [[0.1, 0.9], [0.9]],
23
+ [[0.1, 0.1], [0.1]],
24
+ ]
25
+
26
+ # test on untrained data
27
+ test_data = [
28
+ [0.9, 0.9],
29
+ [0.9, 0.1],
30
+ [0.1, 0.9],
31
+ [0.1, 0.1]
32
+ ]
33
+
34
+ results = test_data.collect { |item|
35
+ nn.feed(item)
36
+ }
37
+
38
+ p results
39
+
40
+ result = nn.optimize(training_data, 0.01, 1_000 ) { |i, error|
41
+ puts "#{i} #{error}"
42
+ }
43
+
44
+ puts "after training"
45
+
46
+ results = test_data.collect { |item|
47
+ nn.feed(item)
48
+ }
49
+
50
+
51
+ p results
52
+
53
+ state = nn.to_json
54
+ puts state
55
+
56
+ nn2 = Brains::Net.load(state)
57
+
58
+ results2 = test_data.collect { |item|
59
+ nn2.feed(item)
60
+ }
61
+
62
+ puts "use saved state"
63
+
64
+ p results2
@@ -0,0 +1,150 @@
1
+ 5.1,3.5,1.4,0.2,Iris-setosa
2
+ 4.9,3.0,1.4,0.2,Iris-setosa
3
+ 4.7,3.2,1.3,0.2,Iris-setosa
4
+ 4.6,3.1,1.5,0.2,Iris-setosa
5
+ 5.0,3.6,1.4,0.2,Iris-setosa
6
+ 5.4,3.9,1.7,0.4,Iris-setosa
7
+ 4.6,3.4,1.4,0.3,Iris-setosa
8
+ 5.0,3.4,1.5,0.2,Iris-setosa
9
+ 4.4,2.9,1.4,0.2,Iris-setosa
10
+ 4.9,3.1,1.5,0.1,Iris-setosa
11
+ 5.4,3.7,1.5,0.2,Iris-setosa
12
+ 4.8,3.4,1.6,0.2,Iris-setosa
13
+ 4.8,3.0,1.4,0.1,Iris-setosa
14
+ 4.3,3.0,1.1,0.1,Iris-setosa
15
+ 5.8,4.0,1.2,0.2,Iris-setosa
16
+ 5.7,4.4,1.5,0.4,Iris-setosa
17
+ 5.4,3.9,1.3,0.4,Iris-setosa
18
+ 5.1,3.5,1.4,0.3,Iris-setosa
19
+ 5.7,3.8,1.7,0.3,Iris-setosa
20
+ 5.1,3.8,1.5,0.3,Iris-setosa
21
+ 5.4,3.4,1.7,0.2,Iris-setosa
22
+ 5.1,3.7,1.5,0.4,Iris-setosa
23
+ 4.6,3.6,1.0,0.2,Iris-setosa
24
+ 5.1,3.3,1.7,0.5,Iris-setosa
25
+ 4.8,3.4,1.9,0.2,Iris-setosa
26
+ 5.0,3.0,1.6,0.2,Iris-setosa
27
+ 5.0,3.4,1.6,0.4,Iris-setosa
28
+ 5.2,3.5,1.5,0.2,Iris-setosa
29
+ 5.2,3.4,1.4,0.2,Iris-setosa
30
+ 4.7,3.2,1.6,0.2,Iris-setosa
31
+ 4.8,3.1,1.6,0.2,Iris-setosa
32
+ 5.4,3.4,1.5,0.4,Iris-setosa
33
+ 5.2,4.1,1.5,0.1,Iris-setosa
34
+ 5.5,4.2,1.4,0.2,Iris-setosa
35
+ 4.9,3.1,1.5,0.1,Iris-setosa
36
+ 5.0,3.2,1.2,0.2,Iris-setosa
37
+ 5.5,3.5,1.3,0.2,Iris-setosa
38
+ 4.9,3.1,1.5,0.1,Iris-setosa
39
+ 4.4,3.0,1.3,0.2,Iris-setosa
40
+ 5.1,3.4,1.5,0.2,Iris-setosa
41
+ 5.0,3.5,1.3,0.3,Iris-setosa
42
+ 4.5,2.3,1.3,0.3,Iris-setosa
43
+ 4.4,3.2,1.3,0.2,Iris-setosa
44
+ 5.0,3.5,1.6,0.6,Iris-setosa
45
+ 5.1,3.8,1.9,0.4,Iris-setosa
46
+ 4.8,3.0,1.4,0.3,Iris-setosa
47
+ 5.1,3.8,1.6,0.2,Iris-setosa
48
+ 4.6,3.2,1.4,0.2,Iris-setosa
49
+ 5.3,3.7,1.5,0.2,Iris-setosa
50
+ 5.0,3.3,1.4,0.2,Iris-setosa
51
+ 7.0,3.2,4.7,1.4,Iris-versicolor
52
+ 6.4,3.2,4.5,1.5,Iris-versicolor
53
+ 6.9,3.1,4.9,1.5,Iris-versicolor
54
+ 5.5,2.3,4.0,1.3,Iris-versicolor
55
+ 6.5,2.8,4.6,1.5,Iris-versicolor
56
+ 5.7,2.8,4.5,1.3,Iris-versicolor
57
+ 6.3,3.3,4.7,1.6,Iris-versicolor
58
+ 4.9,2.4,3.3,1.0,Iris-versicolor
59
+ 6.6,2.9,4.6,1.3,Iris-versicolor
60
+ 5.2,2.7,3.9,1.4,Iris-versicolor
61
+ 5.0,2.0,3.5,1.0,Iris-versicolor
62
+ 5.9,3.0,4.2,1.5,Iris-versicolor
63
+ 6.0,2.2,4.0,1.0,Iris-versicolor
64
+ 6.1,2.9,4.7,1.4,Iris-versicolor
65
+ 5.6,2.9,3.6,1.3,Iris-versicolor
66
+ 6.7,3.1,4.4,1.4,Iris-versicolor
67
+ 5.6,3.0,4.5,1.5,Iris-versicolor
68
+ 5.8,2.7,4.1,1.0,Iris-versicolor
69
+ 6.2,2.2,4.5,1.5,Iris-versicolor
70
+ 5.6,2.5,3.9,1.1,Iris-versicolor
71
+ 5.9,3.2,4.8,1.8,Iris-versicolor
72
+ 6.1,2.8,4.0,1.3,Iris-versicolor
73
+ 6.3,2.5,4.9,1.5,Iris-versicolor
74
+ 6.1,2.8,4.7,1.2,Iris-versicolor
75
+ 6.4,2.9,4.3,1.3,Iris-versicolor
76
+ 6.6,3.0,4.4,1.4,Iris-versicolor
77
+ 6.8,2.8,4.8,1.4,Iris-versicolor
78
+ 6.7,3.0,5.0,1.7,Iris-versicolor
79
+ 6.0,2.9,4.5,1.5,Iris-versicolor
80
+ 5.7,2.6,3.5,1.0,Iris-versicolor
81
+ 5.5,2.4,3.8,1.1,Iris-versicolor
82
+ 5.5,2.4,3.7,1.0,Iris-versicolor
83
+ 5.8,2.7,3.9,1.2,Iris-versicolor
84
+ 6.0,2.7,5.1,1.6,Iris-versicolor
85
+ 5.4,3.0,4.5,1.5,Iris-versicolor
86
+ 6.0,3.4,4.5,1.6,Iris-versicolor
87
+ 6.7,3.1,4.7,1.5,Iris-versicolor
88
+ 6.3,2.3,4.4,1.3,Iris-versicolor
89
+ 5.6,3.0,4.1,1.3,Iris-versicolor
90
+ 5.5,2.5,4.0,1.3,Iris-versicolor
91
+ 5.5,2.6,4.4,1.2,Iris-versicolor
92
+ 6.1,3.0,4.6,1.4,Iris-versicolor
93
+ 5.8,2.6,4.0,1.2,Iris-versicolor
94
+ 5.0,2.3,3.3,1.0,Iris-versicolor
95
+ 5.6,2.7,4.2,1.3,Iris-versicolor
96
+ 5.7,3.0,4.2,1.2,Iris-versicolor
97
+ 5.7,2.9,4.2,1.3,Iris-versicolor
98
+ 6.2,2.9,4.3,1.3,Iris-versicolor
99
+ 5.1,2.5,3.0,1.1,Iris-versicolor
100
+ 5.7,2.8,4.1,1.3,Iris-versicolor
101
+ 6.3,3.3,6.0,2.5,Iris-virginica
102
+ 5.8,2.7,5.1,1.9,Iris-virginica
103
+ 7.1,3.0,5.9,2.1,Iris-virginica
104
+ 6.3,2.9,5.6,1.8,Iris-virginica
105
+ 6.5,3.0,5.8,2.2,Iris-virginica
106
+ 7.6,3.0,6.6,2.1,Iris-virginica
107
+ 4.9,2.5,4.5,1.7,Iris-virginica
108
+ 7.3,2.9,6.3,1.8,Iris-virginica
109
+ 6.7,2.5,5.8,1.8,Iris-virginica
110
+ 7.2,3.6,6.1,2.5,Iris-virginica
111
+ 6.5,3.2,5.1,2.0,Iris-virginica
112
+ 6.4,2.7,5.3,1.9,Iris-virginica
113
+ 6.8,3.0,5.5,2.1,Iris-virginica
114
+ 5.7,2.5,5.0,2.0,Iris-virginica
115
+ 5.8,2.8,5.1,2.4,Iris-virginica
116
+ 6.4,3.2,5.3,2.3,Iris-virginica
117
+ 6.5,3.0,5.5,1.8,Iris-virginica
118
+ 7.7,3.8,6.7,2.2,Iris-virginica
119
+ 7.7,2.6,6.9,2.3,Iris-virginica
120
+ 6.0,2.2,5.0,1.5,Iris-virginica
121
+ 6.9,3.2,5.7,2.3,Iris-virginica
122
+ 5.6,2.8,4.9,2.0,Iris-virginica
123
+ 7.7,2.8,6.7,2.0,Iris-virginica
124
+ 6.3,2.7,4.9,1.8,Iris-virginica
125
+ 6.7,3.3,5.7,2.1,Iris-virginica
126
+ 7.2,3.2,6.0,1.8,Iris-virginica
127
+ 6.2,2.8,4.8,1.8,Iris-virginica
128
+ 6.1,3.0,4.9,1.8,Iris-virginica
129
+ 6.4,2.8,5.6,2.1,Iris-virginica
130
+ 7.2,3.0,5.8,1.6,Iris-virginica
131
+ 7.4,2.8,6.1,1.9,Iris-virginica
132
+ 7.9,3.8,6.4,2.0,Iris-virginica
133
+ 6.4,2.8,5.6,2.2,Iris-virginica
134
+ 6.3,2.8,5.1,1.5,Iris-virginica
135
+ 6.1,2.6,5.6,1.4,Iris-virginica
136
+ 7.7,3.0,6.1,2.3,Iris-virginica
137
+ 6.3,3.4,5.6,2.4,Iris-virginica
138
+ 6.4,3.1,5.5,1.8,Iris-virginica
139
+ 6.0,3.0,4.8,1.8,Iris-virginica
140
+ 6.9,3.1,5.4,2.1,Iris-virginica
141
+ 6.7,3.1,5.6,2.4,Iris-virginica
142
+ 6.9,3.1,5.1,2.3,Iris-virginica
143
+ 5.8,2.7,5.1,1.9,Iris-virginica
144
+ 6.8,3.2,5.9,2.3,Iris-virginica
145
+ 6.7,3.3,5.7,2.5,Iris-virginica
146
+ 6.7,3.0,5.2,2.3,Iris-virginica
147
+ 6.3,2.5,5.0,1.9,Iris-virginica
148
+ 6.5,3.0,5.2,2.0,Iris-virginica
149
+ 6.2,3.4,5.4,2.3,Iris-virginica
150
+ 5.9,3.0,5.1,1.8,Iris-virginica
@@ -0,0 +1,13 @@
1
+ require "brains/version"
2
+ require "brains/brains.jar"
3
+ require "brains/gson.jar"
4
+ require "brains/commons-lang3.jar"
5
+ require "brains/commons-cli.jar"
6
+ require "brains/net"
7
+ require "json"
8
+
9
+ module Brains
10
+ class Config
11
+ attr_accessor :neurons_per_layer, :input_neurons, :output_neurons
12
+ end
13
+ end
Binary file
Binary file
@@ -0,0 +1,105 @@
1
+ require 'java'
2
+
3
+ module Brains
4
+ class Net
5
+ attr_accessor :nn, :config
6
+
7
+ def self.create(input, output, total, opts = {})
8
+ config = com.dayosoft.nn.NeuralNet::Config.new(input, output, total)
9
+ config.bias = opts[:bias] || 1.0
10
+ config.outputBias = opts[:output_bias] || 1.0
11
+ config.learningRate = opts[:learning_rate] || 0.1
12
+ config.neuronsPerLayer = opts[:neurons_per_layer] || 5
13
+ config.momentumFactor = opts[:momentum_factor] || 0.5
14
+ config.activationFunctionType = opt_to_func(opts[:activation_function] || :htan)
15
+ config.outputActivationFunctionType = opt_to_func(opts[:activation_function] || :sigmoid)
16
+ config.errorFormula = opt_to_error_func(opts[:activation_function] || :mean_squared)
17
+ nn = com.dayosoft.nn.NeuralNet.new(config);
18
+
19
+ Brains::Net.new.set_nn(nn).set_config(config)
20
+ end
21
+
22
+ def self.load(json_string)
23
+ nn = com.dayosoft.nn.NeuralNet::loadStateFromJsonString(nil, json_string)
24
+ config = nn.getConfig
25
+
26
+ Brains::Net.new.set_nn(nn).set_config(config)
27
+ end
28
+
29
+ def randomize_weights(min = -1, max = 1)
30
+ @nn.randomizeWeights(min, max)
31
+ end
32
+
33
+ def dump_weights
34
+ @nn.dumpWeights.to_a.map(&:to_a)
35
+ end
36
+
37
+ def dump_biases
38
+ @nn.dumpWeights.to_a.map(&:to_a)
39
+ end
40
+
41
+ def optimize(test_cases, target_error = 0.01, max_epoch = 1_000_000_000, is_batch = false, &callback)
42
+ inputs = []
43
+ outputs = []
44
+
45
+ test_cases.each do |item|
46
+ inputs << item[0].to_java(Java::double)
47
+ outputs << item[1].to_java(Java::double)
48
+ end
49
+
50
+ result = @nn.optimize(java.util.ArrayList.new(inputs), java.util.ArrayList.new(outputs), target_error, max_epoch, is_batch, callback)
51
+ { iterations: result.first, error: result.second }
52
+ end
53
+
54
+ def feed(input)
55
+ output = @nn.feed(input.to_java(Java::double)).to_a
56
+ end
57
+
58
+ def to_json
59
+ @nn.saveStateToJson
60
+ end
61
+
62
+ def set_nn(nn)
63
+ @nn = nn
64
+ self
65
+ end
66
+
67
+ def set_config(config)
68
+ @config = config
69
+ self
70
+ end
71
+
72
+ protected
73
+
74
+ def initialize
75
+ end
76
+
77
+ private
78
+
79
+ def self.opt_to_func(func)
80
+ case func
81
+ when :htan
82
+ com.dayosoft.nn.Neuron::HTAN
83
+ when :sigmoid
84
+ com.dayosoft.nn.Neuron::SIGMOID
85
+ when :softmax
86
+ com.dayosoft.nn.Neuron::SOFTMAX
87
+ when :rectifier
88
+ com.dayosoft.nn.Neuron::RECTIFIER
89
+ else
90
+ raise "invalid activation function #{func}"
91
+ end
92
+ end
93
+
94
+ def self.opt_to_error_func(func)
95
+ case func
96
+ when :mean_squared
97
+ com.dayosoft.nn.NeuralNet::Config::MEAN_SQUARED
98
+ when :cross_entropy
99
+ com.dayosoft.nn.NeuralNet::Config::CROSS_ENTROPY
100
+ else
101
+ raise "Invalid Error Function #{func}"
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,3 @@
1
+ module Brains
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brains
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: java
6
+ authors:
7
+ - Joseph Emmanuel Dayo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-02-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.12'
19
+ name: bundler
20
+ prerelease: false
21
+ type: :development
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '10.0'
33
+ name: rake
34
+ prerelease: false
35
+ type: :development
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ name: rspec
48
+ prerelease: false
49
+ type: :development
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: A feedforward neural network library for JRuby
56
+ email:
57
+ - joseph.dayo@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - CODE_OF_CONDUCT.md
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - brains.gemspec
73
+ - example/iris.rb
74
+ - example/xor.rb
75
+ - iris.data
76
+ - lib/brains.rb
77
+ - lib/brains/brains.jar
78
+ - lib/brains/commons-cli.jar
79
+ - lib/brains/commons-lang3.jar
80
+ - lib/brains/gson.jar
81
+ - lib/brains/net.rb
82
+ - lib/brains/version.rb
83
+ homepage: https://github.com/jedld/brains-jruby
84
+ licenses:
85
+ - MIT
86
+ metadata:
87
+ allowed_push_host: https://rubygems.org
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.4.8
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: A feedforward neural network library for JRuby
108
+ test_files: []