brains 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []