brains 0.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +159 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/brains.gemspec +34 -0
- data/example/iris.rb +100 -0
- data/example/xor.rb +64 -0
- data/iris.data +150 -0
- data/lib/brains.rb +13 -0
- data/lib/brains/brains.jar +0 -0
- data/lib/brains/commons-cli.jar +0 -0
- data/lib/brains/commons-lang3.jar +0 -0
- data/lib/brains/gson.jar +0 -0
- data/lib/brains/net.rb +105 -0
- data/lib/brains/version.rb +3 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -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
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -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
|
data/bin/setup
ADDED
data/brains.gemspec
ADDED
@@ -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
|
data/example/iris.rb
ADDED
@@ -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)}%)"
|
data/example/xor.rb
ADDED
@@ -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
|
data/iris.data
ADDED
@@ -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
|
data/lib/brains.rb
ADDED
@@ -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
|
Binary file
|
data/lib/brains/gson.jar
ADDED
Binary file
|
data/lib/brains/net.rb
ADDED
@@ -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
|
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: []
|