mlpnn 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rubocop.yml +63 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +52 -0
- data/LICENSE +20 -0
- data/README.rdoc +44 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/examples/backpropagation_example.rb +72 -0
- data/examples/patterns_with_base_noise.rb +67 -0
- data/examples/patterns_with_noise.rb +67 -0
- data/examples/training_patterns.rb +67 -0
- data/examples/xor.rb +27 -0
- data/lib/mlp.rb +8 -0
- data/lib/mlp/network.rb +124 -0
- data/lib/mlp/neuron.rb +53 -0
- data/lib/mlp/version.rb +4 -0
- data/mlpnn.gemspec +31 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 55e005b2fa8211ce8deb2b6b0c72e1658c38e10e
|
4
|
+
data.tar.gz: 2521f3894e6125581af1715f9a49858a3b8277ab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68736aceb98084f6f2d4122756264377ae83f4cce5db5de5ade2ef98ecc9bc117b5de46c0fb173d77bee7d50551e89584f5e19f05b095bffac722d37e16e376c
|
7
|
+
data.tar.gz: 23b20e30307018cf3ded7a381c9c9e82004b275cc5a549eac80479c1caca6a4c16a151947ad40b8b378f5670d226f432d415a0ac4987b81b801d894c0459accc
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# This is the configuration used to check the rubocop source code.
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
Exclude:
|
5
|
+
- 'vendor/**/*'
|
6
|
+
- 'spec/fixtures/**/*'
|
7
|
+
- 'tmp/**/*'
|
8
|
+
TargetRubyVersion: 2.4
|
9
|
+
|
10
|
+
Style/Encoding:
|
11
|
+
EnforcedStyle: when_needed
|
12
|
+
Enabled: true
|
13
|
+
|
14
|
+
Style/FrozenStringLiteralComment:
|
15
|
+
EnforcedStyle: always
|
16
|
+
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Exclude:
|
19
|
+
- 'Rakefile'
|
20
|
+
- '**/*.rake'
|
21
|
+
- 'spec/**/*.rb'
|
22
|
+
|
23
|
+
# Offense count: 86
|
24
|
+
Metrics/AbcSize:
|
25
|
+
Max: 19
|
26
|
+
|
27
|
+
# Offense count: 32
|
28
|
+
# Configuration parameters: CountComments.
|
29
|
+
Metrics/ClassLength:
|
30
|
+
Max: 178
|
31
|
+
|
32
|
+
# Offense count: 28
|
33
|
+
Metrics/CyclomaticComplexity:
|
34
|
+
Max: 7
|
35
|
+
|
36
|
+
# Offense count: 139
|
37
|
+
# Configuration parameters: CountComments.
|
38
|
+
Metrics/MethodLength:
|
39
|
+
Max: 14
|
40
|
+
|
41
|
+
# Offense count: 12
|
42
|
+
# Configuration parameters: CountComments.
|
43
|
+
Metrics/ModuleLength:
|
44
|
+
Max: 156
|
45
|
+
|
46
|
+
Style/BarePercentLiterals:
|
47
|
+
EnforcedStyle: bare_percent
|
48
|
+
Heredoc:
|
49
|
+
Exclude: true
|
50
|
+
|
51
|
+
Style/TrailingCommaInLiteral:
|
52
|
+
EnforcedStyleForMultiline: comma
|
53
|
+
Heredoc:
|
54
|
+
IncludeKeys:
|
55
|
+
- RUBY
|
56
|
+
|
57
|
+
Metrics/LineLength:
|
58
|
+
Max: 90
|
59
|
+
Heredoc:
|
60
|
+
ExcludeKeys:
|
61
|
+
- YAML
|
62
|
+
- XML
|
63
|
+
- TEXT
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
mlpnn (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
activesupport (5.0.1)
|
10
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
11
|
+
i18n (~> 0.7)
|
12
|
+
minitest (~> 5.1)
|
13
|
+
tzinfo (~> 1.1)
|
14
|
+
ast (2.3.0)
|
15
|
+
concurrent-ruby (1.0.4)
|
16
|
+
i18n (0.7.0)
|
17
|
+
minitest (5.10.1)
|
18
|
+
parser (2.3.3.1)
|
19
|
+
ast (~> 2.2)
|
20
|
+
powerpack (0.1.1)
|
21
|
+
rainbow (2.2.1)
|
22
|
+
rake (10.5.0)
|
23
|
+
rubocop (0.47.1)
|
24
|
+
parser (>= 2.3.3.1, < 3.0)
|
25
|
+
powerpack (~> 0.1)
|
26
|
+
rainbow (>= 1.99.1, < 3.0)
|
27
|
+
ruby-progressbar (~> 1.7)
|
28
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
29
|
+
ruby-progressbar (1.8.1)
|
30
|
+
shoulda (3.5.0)
|
31
|
+
shoulda-context (~> 1.0, >= 1.0.1)
|
32
|
+
shoulda-matchers (>= 1.4.1, < 3.0)
|
33
|
+
shoulda-context (1.2.2)
|
34
|
+
shoulda-matchers (2.8.0)
|
35
|
+
activesupport (>= 3.0.0)
|
36
|
+
thread_safe (0.3.5)
|
37
|
+
tzinfo (1.2.2)
|
38
|
+
thread_safe (~> 0.1)
|
39
|
+
unicode-display_width (1.1.3)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
bundler (~> 1.13)
|
46
|
+
mlpnn!
|
47
|
+
rake (~> 10.0)
|
48
|
+
rubocop (~> 0.47)
|
49
|
+
shoulda (~> 3.5)
|
50
|
+
|
51
|
+
BUNDLED WITH
|
52
|
+
1.13.7
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 reddavis / 2017 BEaStia
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
= Multi-Layer Perceptron Neural Network
|
2
|
+
|
3
|
+
I built this to not only learn about the MLP but to also make a very simple, well laid out MLP so other can easily see what's happening.
|
4
|
+
|
5
|
+
I also suggest checking out http://bit.ly/XEWOc for a great tutorial.
|
6
|
+
|
7
|
+
== Install
|
8
|
+
|
9
|
+
gem install mlp
|
10
|
+
|
11
|
+
== How To Use
|
12
|
+
require 'mlp'
|
13
|
+
|
14
|
+
a = MLP::Network.new(hidden_layers: [2], output_nodes: 1, inputs: 2)
|
15
|
+
|
16
|
+
3001.times do |i|
|
17
|
+
a.train([0,0], [0])
|
18
|
+
a.train([0,1], [1])
|
19
|
+
a.train([1,0], [1])
|
20
|
+
error = a.train([1,1], [0])
|
21
|
+
puts "Error after iteration #{i}:\t#{error}" if i%200 == 0
|
22
|
+
end
|
23
|
+
|
24
|
+
puts "Test data"
|
25
|
+
puts "[0,0] = > #{a.feed_forward([0,0]).inspect}"
|
26
|
+
puts "[0,1] = > #{a.feed_forward([0,1]).inspect}"
|
27
|
+
puts "[1,0] = > #{a.feed_forward([1,0]).inspect}"
|
28
|
+
puts "[1,1] = > #{a.feed_forward([1,1]).inspect}"
|
29
|
+
|
30
|
+
== Benchmarks
|
31
|
+
|
32
|
+
The above example produces these times
|
33
|
+
|
34
|
+
user system total real
|
35
|
+
MLP 0.820000 0.000000 0.820000 ( 0.837693)
|
36
|
+
Ai4R 1.180000 0.010000 1.190000 ( 1.232388)
|
37
|
+
|
38
|
+
== Thanks
|
39
|
+
|
40
|
+
* David Richards - For his code reviews and all round helpfulness. - http://github.com/davidrichards
|
41
|
+
|
42
|
+
== Copyright
|
43
|
+
|
44
|
+
Copyright (c) 2009 Red Davis, 2017 Igor Pavlov See LICENSE for details.
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# This test was taken from ai4r gem
|
3
|
+
|
4
|
+
# Author:: Sergio Fierens
|
5
|
+
# License:: MPL 1.1
|
6
|
+
# Project:: ai4r
|
7
|
+
# Url:: http://ai4r.rubyforge.org/
|
8
|
+
#
|
9
|
+
# You can redistribute it and/or modify it under the terms of
|
10
|
+
# the Mozilla Public License version 1.1 as published by the
|
11
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
12
|
+
|
13
|
+
require File.dirname(__FILE__) + '/training_patterns'
|
14
|
+
require File.dirname(__FILE__) + '/patterns_with_noise'
|
15
|
+
require File.dirname(__FILE__) + '/patterns_with_base_noise'
|
16
|
+
require File.dirname(__FILE__) + '/../lib/mlp'
|
17
|
+
require 'benchmark'
|
18
|
+
|
19
|
+
times = Benchmark.measure do
|
20
|
+
srand 1
|
21
|
+
|
22
|
+
net = MLP::Network.new(hidden_layers: [2], output_nodes: 3, inputs: 256)
|
23
|
+
|
24
|
+
tr_with_noise = TRIANGLE_WITH_NOISE.flatten.collect { |input| input.to_f / 5.0 }
|
25
|
+
sq_with_noise = SQUARE_WITH_NOISE.flatten.collect { |input| input.to_f / 5.0 }
|
26
|
+
cr_with_noise = CROSS_WITH_NOISE.flatten.collect { |input| input.to_f / 5.0 }
|
27
|
+
|
28
|
+
tr_with_base_noise = TRIANGLE_WITH_BASE_NOISE.flatten.collect { |input| input.to_f / 5.0 }
|
29
|
+
sq_with_base_noise = SQUARE_WITH_BASE_NOISE.flatten.collect { |input| input.to_f / 5.0 }
|
30
|
+
cr_with_base_noise = CROSS_WITH_BASE_NOISE.flatten.collect { |input| input.to_f / 5.0 }
|
31
|
+
|
32
|
+
puts 'Training the network, please wait.'
|
33
|
+
101.times do |i|
|
34
|
+
tr_input = TRIANGLE.flatten.collect { |input| input.to_f / 5.0 }
|
35
|
+
sq_input = SQUARE.flatten.collect { |input| input.to_f / 5.0 }
|
36
|
+
cr_input = CROSS.flatten.collect { |input| input.to_f / 5.0 }
|
37
|
+
|
38
|
+
error1 = net.train(tr_input, [1, 0, 0])
|
39
|
+
error2 = net.train(sq_input, [0, 1, 0])
|
40
|
+
error3 = net.train(cr_input, [0, 0, 1])
|
41
|
+
puts "Error after iteration #{i}:\t#{error1} - #{error2} - #{error3}" if i % 20 == 0
|
42
|
+
end
|
43
|
+
|
44
|
+
def result_label(result)
|
45
|
+
if result[0] > result[1] && result[0] > result[2]
|
46
|
+
'TRIANGLE'
|
47
|
+
elsif result[1] > result[2]
|
48
|
+
'SQUARE'
|
49
|
+
else
|
50
|
+
'CROSS'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
tr_input = TRIANGLE.flatten.collect { |input| input.to_f / 5.0 }
|
55
|
+
sq_input = SQUARE.flatten.collect { |input| input.to_f / 5.0 }
|
56
|
+
cr_input = CROSS.flatten.collect { |input| input.to_f / 5.0 }
|
57
|
+
|
58
|
+
puts 'Training Examples'
|
59
|
+
puts "#{net.feed_forward(tr_input).inspect} => #{result_label(net.feed_forward(tr_input))}"
|
60
|
+
puts "#{net.feed_forward(sq_input).inspect} => #{result_label(net.feed_forward(sq_input))}"
|
61
|
+
puts "#{net.feed_forward(cr_input).inspect} => #{result_label(net.feed_forward(cr_input))}"
|
62
|
+
puts 'Examples with noise'
|
63
|
+
puts "#{net.feed_forward(tr_with_noise).inspect} => #{result_label(net.feed_forward(tr_with_noise))}"
|
64
|
+
puts "#{net.feed_forward(sq_with_noise).inspect} => #{result_label(net.feed_forward(sq_with_noise))}"
|
65
|
+
puts "#{net.feed_forward(cr_with_noise).inspect} => #{result_label(net.feed_forward(cr_with_noise))}"
|
66
|
+
puts 'Examples with base noise'
|
67
|
+
puts "#{net.feed_forward(tr_with_base_noise).inspect} => #{result_label(net.feed_forward(tr_with_base_noise))}"
|
68
|
+
puts "#{net.feed_forward(sq_with_base_noise).inspect} => #{result_label(net.feed_forward(sq_with_base_noise))}"
|
69
|
+
puts "#{net.feed_forward(cr_with_base_noise).inspect} => #{result_label(net.feed_forward(cr_with_base_noise))}"
|
70
|
+
end
|
71
|
+
|
72
|
+
puts "Elapsed time: #{times}"
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Author:: Sergio Fierens
|
3
|
+
# License:: MPL 1.1
|
4
|
+
# Project:: ai4r
|
5
|
+
# Url:: http://ai4r.rubyforge.org/
|
6
|
+
#
|
7
|
+
# You can redistribute it and/or modify it under the terms of
|
8
|
+
# the Mozilla Public License version 1.1 as published by the
|
9
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
10
|
+
|
11
|
+
TRIANGLE_WITH_BASE_NOISE = [
|
12
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
13
|
+
[3, 3, 3, 3, 3, 3, 4, 10, 10, 4, 3, 3, 3, 3, 3, 3],
|
14
|
+
[3, 3, 3, 3, 3, 3, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3],
|
15
|
+
[3, 3, 3, 3, 3, 4, 10, 4, 4, 10, 4, 3, 3, 3, 3, 3],
|
16
|
+
[3, 3, 3, 3, 3, 8, 8, 3, 3, 8, 8, 3, 3, 3, 3, 3],
|
17
|
+
[3, 3, 3, 3, 4, 10, 4, 3, 3, 4, 10, 4, 3, 3, 3, 3],
|
18
|
+
[3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3],
|
19
|
+
[3, 3, 3, 4, 10, 4, 3, 3, 3, 3, 4, 10, 4, 3, 3, 3],
|
20
|
+
[3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3],
|
21
|
+
[3, 3, 4, 10, 4, 3, 3, 3, 3, 3, 3, 4, 10, 4, 3, 3],
|
22
|
+
[3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3],
|
23
|
+
[3, 4, 10, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 10, 4, 3],
|
24
|
+
[3, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3],
|
25
|
+
[4, 10, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 10, 4],
|
26
|
+
[8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8],
|
27
|
+
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
28
|
+
].freeze
|
29
|
+
|
30
|
+
SQUARE_WITH_BASE_NOISE = [
|
31
|
+
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
32
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
33
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
34
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
35
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
36
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
37
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
38
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
39
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
40
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
41
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
42
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
43
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
44
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
45
|
+
[10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10],
|
46
|
+
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
47
|
+
|
48
|
+
].freeze
|
49
|
+
|
50
|
+
CROSS_WITH_BASE_NOISE = [
|
51
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
52
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
53
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
54
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
55
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
56
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
57
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
58
|
+
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
|
59
|
+
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
|
60
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
61
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
62
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
63
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
64
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
65
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
66
|
+
[3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3],
|
67
|
+
].freeze
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Author:: Sergio Fierens
|
3
|
+
# License:: MPL 1.1
|
4
|
+
# Project:: ai4r
|
5
|
+
# Url:: http://ai4r.rubyforge.org/
|
6
|
+
#
|
7
|
+
# You can redistribute it and/or modify it under the terms of
|
8
|
+
# the Mozilla Public License version 1.1 as published by the
|
9
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
10
|
+
|
11
|
+
TRIANGLE_WITH_NOISE = [
|
12
|
+
[1, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0],
|
13
|
+
[0, 0, 0, 0, 3, 0, 1, 9, 9, 1, 0, 0, 0, 0, 3, 0],
|
14
|
+
[0, 3, 0, 0, 0, 0, 5, 1, 5, 3, 0, 0, 0, 0, 0, 7],
|
15
|
+
[0, 0, 0, 7, 0, 1, 9, 1, 1, 9, 1, 0, 0, 0, 3, 0],
|
16
|
+
[0, 0, 0, 0, 0, 3, 5, 0, 3, 5, 5, 0, 0, 0, 0, 0],
|
17
|
+
[0, 1, 0, 0, 1, 9, 1, 0, 1, 1, 9, 1, 0, 0, 0, 0],
|
18
|
+
[1, 0, 0, 0, 5, 5, 0, 0, 0, 0, 5, 5, 7, 0, 0, 3],
|
19
|
+
[0, 0, 3, 3, 9, 1, 0, 0, 1, 0, 1, 9, 1, 0, 0, 0],
|
20
|
+
[0, 0, 0, 5, 5, 0, 3, 7, 0, 0, 0, 5, 5, 0, 0, 0],
|
21
|
+
[0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0],
|
22
|
+
[0, 0, 5, 5, 0, 0, 0, 0, 3, 0, 0, 0, 5, 5, 0, 0],
|
23
|
+
[0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0],
|
24
|
+
[0, 5, 5, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 5, 5, 0],
|
25
|
+
[1, 9, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 9, 1],
|
26
|
+
[5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5],
|
27
|
+
[10, 10, 10, 10, 1, 10, 10, 10, 10, 10, 1, 10, 10, 10, 10, 10],
|
28
|
+
].freeze
|
29
|
+
|
30
|
+
SQUARE_WITH_NOISE = [
|
31
|
+
[10, 3, 10, 10, 10, 6, 10, 10, 10, 10, 10, 4, 10, 10, 10, 10],
|
32
|
+
[10, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
33
|
+
[10, 0, 3, 0, 0, 0, 0, 7, 0, 6, 1, 0, 0, 0, 0, 0],
|
34
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
35
|
+
[10, 0, 4, 0, 4, 0, 0, 0, 1, 0, 3, 0, 0, 4, 0, 10],
|
36
|
+
[10, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
|
37
|
+
[10, 0, 0, 0, 3, 6, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10],
|
38
|
+
[10, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 7, 0, 0, 10],
|
39
|
+
[10, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
40
|
+
[10, 0, 7, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
41
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 7, 10],
|
42
|
+
[10, 0, 3, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 10],
|
43
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10],
|
44
|
+
[10, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 10],
|
45
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
46
|
+
[10, 10, 10, 10, 3, 10, 10, 10, 10, 0, 10, 10, 1, 10, 1, 10],
|
47
|
+
|
48
|
+
].freeze
|
49
|
+
|
50
|
+
CROSS_WITH_NOISE = [
|
51
|
+
[0, 0, 0, 0, 0, 0, 3, 3, 5, 0, 3, 0, 0, 0, 1, 0],
|
52
|
+
[0, 1, 0, 0, 0, 1, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
53
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 3, 0, 0, 0],
|
54
|
+
[0, 0, 1, 8, 0, 0, 0, 5, 5, 0, 4, 0, 0, 0, 1, 0],
|
55
|
+
[0, 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0],
|
56
|
+
[0, 0, 0, 8, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 1],
|
57
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 3, 0, 0, 0, 0, 0],
|
58
|
+
[5, 5, 5, 8, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5],
|
59
|
+
[5, 5, 5, 5, 5, 5, 5, 5, 1, 5, 5, 5, 5, 1, 0, 0],
|
60
|
+
[0, 0, 0, 8, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0],
|
61
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 4, 0, 0, 0, 0, 0, 0],
|
62
|
+
[0, 0, 0, 0, 0, 4, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
63
|
+
[4, 0, 0, 4, 0, 0, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0],
|
64
|
+
[0, 0, 0, 0, 0, 1, 0, 5, 4, 4, 3, 0, 0, 0, 0, 0],
|
65
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 10, 0, 0, 0],
|
66
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
67
|
+
].freeze
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Author:: Sergio Fierens
|
3
|
+
# License:: MPL 1.1
|
4
|
+
# Project:: ai4r
|
5
|
+
# Url:: http://ai4r.rubyforge.org/
|
6
|
+
#
|
7
|
+
# You can redistribute it and/or modify it under the terms of
|
8
|
+
# the Mozilla Public License version 1.1 as published by the
|
9
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
10
|
+
|
11
|
+
TRIANGLE = [
|
12
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
13
|
+
[0, 0, 0, 0, 0, 0, 1, 9, 9, 1, 0, 0, 0, 0, 0, 0],
|
14
|
+
[0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0],
|
15
|
+
[0, 0, 0, 0, 0, 1, 9, 1, 1, 9, 1, 0, 0, 0, 0, 0],
|
16
|
+
[0, 0, 0, 0, 0, 5, 5, 0, 0, 5, 5, 0, 0, 0, 0, 0],
|
17
|
+
[0, 0, 0, 0, 1, 9, 1, 0, 0, 1, 9, 1, 0, 0, 0, 0],
|
18
|
+
[0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0],
|
19
|
+
[0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0],
|
20
|
+
[0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0],
|
21
|
+
[0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0],
|
22
|
+
[0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0],
|
23
|
+
[0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0],
|
24
|
+
[0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0],
|
25
|
+
[1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1],
|
26
|
+
[5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5],
|
27
|
+
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
28
|
+
].freeze
|
29
|
+
|
30
|
+
SQUARE = [
|
31
|
+
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
32
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
33
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
34
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
35
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
36
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
37
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
38
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
39
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
40
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
41
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
42
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
43
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
44
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
45
|
+
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
46
|
+
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
47
|
+
|
48
|
+
].freeze
|
49
|
+
|
50
|
+
CROSS = [
|
51
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
52
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
53
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
54
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
55
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
56
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
57
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
58
|
+
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
|
59
|
+
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
|
60
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
61
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
62
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
63
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
64
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
65
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
66
|
+
[0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0],
|
67
|
+
].freeze
|
data/examples/xor.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# This test was taken from ai4r gem
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/../lib/mlp'
|
5
|
+
require 'benchmark'
|
6
|
+
|
7
|
+
times = Benchmark.measure do
|
8
|
+
srand 1
|
9
|
+
|
10
|
+
a = MLP::Network.new(hidden_layers: [2], output_nodes: 1, inputs: 2)
|
11
|
+
|
12
|
+
3001.times do |i|
|
13
|
+
a.train([0, 0], [0])
|
14
|
+
a.train([0, 1], [1])
|
15
|
+
a.train([1, 0], [1])
|
16
|
+
error = a.train([1, 1], [0])
|
17
|
+
puts "Error after iteration #{i}:\t#{error}" if i % 200 == 0
|
18
|
+
end
|
19
|
+
|
20
|
+
puts 'Test data'
|
21
|
+
puts "[0,0] = > #{a.feed_forward([0, 0]).inspect}"
|
22
|
+
puts "[0,1] = > #{a.feed_forward([0, 1]).inspect}"
|
23
|
+
puts "[1,0] = > #{a.feed_forward([1, 0]).inspect}"
|
24
|
+
puts "[1,1] = > #{a.feed_forward([1, 1]).inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "Elapsed time: #{times}"
|
data/lib/mlp.rb
ADDED
data/lib/mlp/network.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MLP
|
4
|
+
class Network
|
5
|
+
|
6
|
+
UPDATE_WEIGHT_VALUE = 0.25
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@input_size = options[:inputs]
|
10
|
+
@hidden_layers = options[:hidden_layers]
|
11
|
+
@number_of_output_nodes = options[:output_nodes]
|
12
|
+
setup_network
|
13
|
+
end
|
14
|
+
|
15
|
+
def feed_forward(input)
|
16
|
+
@network.each_with_index do |layer, layer_index|
|
17
|
+
layer.each do |neuron|
|
18
|
+
if layer_index == 0
|
19
|
+
neuron.fire(input)
|
20
|
+
else
|
21
|
+
input = @network[layer_index - 1].map(&:last_output)
|
22
|
+
neuron.fire(input)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@network.last.map(&:last_output)
|
27
|
+
end
|
28
|
+
|
29
|
+
def train(input, targets)
|
30
|
+
# To go back we must go forward
|
31
|
+
feed_forward(input)
|
32
|
+
compute_deltas(targets)
|
33
|
+
update_weights(input)
|
34
|
+
calculate_error(targets)
|
35
|
+
end
|
36
|
+
|
37
|
+
def inspect
|
38
|
+
@network
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def update_weights(input)
|
44
|
+
reversed_network = @network.reverse
|
45
|
+
reversed_network.each_with_index do |layer, layer_index|
|
46
|
+
if layer_index == 0
|
47
|
+
update_output_weights(layer, layer_index, input)
|
48
|
+
else
|
49
|
+
update_hidden_weights(layer, layer_index, input)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_output_weights(layer, _layer_index, input)
|
55
|
+
inputs = @hidden_layers.empty? ? input : @network[-2].map(&:last_output)
|
56
|
+
layer.each do |neuron|
|
57
|
+
neuron.update_weight(inputs, UPDATE_WEIGHT_VALUE)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def update_hidden_weights(layer, layer_index, original_input)
|
62
|
+
inputs = if layer_index == (@network.size - 1)
|
63
|
+
original_input
|
64
|
+
else
|
65
|
+
@network.reverse[layer_index + 1].map(&:last_output)
|
66
|
+
end
|
67
|
+
layer.each do |neuron|
|
68
|
+
neuron.update_weight(inputs, UPDATE_WEIGHT_VALUE)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def compute_deltas(targets)
|
73
|
+
reversed_network = @network.reverse
|
74
|
+
reversed_network.each_with_index do |layer, layer_index|
|
75
|
+
if layer_index == 0
|
76
|
+
compute_output_deltas(layer, targets)
|
77
|
+
else
|
78
|
+
compute_hidden_deltas(layer, targets)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def compute_output_deltas(layer, targets)
|
84
|
+
layer.each_with_index do |neuron, i|
|
85
|
+
output = neuron.last_output
|
86
|
+
neuron.delta = output * (1 - output) * (targets[i] - output)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def compute_hidden_deltas(layer, _targets)
|
91
|
+
layer.each_with_index do |neuron, neuron_index|
|
92
|
+
error = 0
|
93
|
+
@network.last.each do |output_neuron|
|
94
|
+
error += output_neuron.delta * output_neuron.weights[neuron_index]
|
95
|
+
end
|
96
|
+
output = neuron.last_output
|
97
|
+
neuron.delta = output * (1 - output) * error
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def calculate_error(targets)
|
102
|
+
outputs = @network.last.map(&:last_output)
|
103
|
+
sum = 0
|
104
|
+
targets.each_with_index do |t, index|
|
105
|
+
sum += (t - outputs[index])**2
|
106
|
+
end
|
107
|
+
0.5 * sum
|
108
|
+
end
|
109
|
+
|
110
|
+
def setup_network
|
111
|
+
@network = []
|
112
|
+
|
113
|
+
# Hidden Layers
|
114
|
+
@hidden_layers.each_with_index do |number_of_neurons, index|
|
115
|
+
inputs = index == 0 ? @input_size : @hidden_layers[index - 1].size
|
116
|
+
@network << Array.new(number_of_neurons) { Neuron.new(inputs) }
|
117
|
+
end
|
118
|
+
|
119
|
+
# Output layer
|
120
|
+
inputs = @hidden_layers.empty? ? @input_size : @hidden_layers.last
|
121
|
+
@network << Array.new(@number_of_output_nodes) { Neuron.new(inputs) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/mlp/neuron.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module MLP
|
5
|
+
class Neuron
|
6
|
+
attr_reader :last_output, :weights
|
7
|
+
attr_accessor :delta
|
8
|
+
|
9
|
+
def initialize(number_of_inputs)
|
10
|
+
create_weights(number_of_inputs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def fire(input)
|
14
|
+
@last_output = activation_function(input)
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_weight(inputs, training_rate)
|
18
|
+
inputs << -1 # Add the bias
|
19
|
+
@weights.each_index do |i|
|
20
|
+
@weights[i] += training_rate * delta * inputs[i]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
@weights
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def activation_function(input)
|
31
|
+
sum = 0
|
32
|
+
input.each_with_index do |n, index|
|
33
|
+
sum += @weights[index] * n
|
34
|
+
end
|
35
|
+
sum += @weights.last * -1 # bias node
|
36
|
+
sigmoid_function(sum)
|
37
|
+
end
|
38
|
+
|
39
|
+
# g(h) = 1 / (1+exp(-B*h(j)))
|
40
|
+
def sigmoid_function(x)
|
41
|
+
1 / (1 + Math.exp(-1 * x))
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_weights(number_of_inputs)
|
45
|
+
# Create random weights between 0 & 1
|
46
|
+
# Plus another one for the bias node
|
47
|
+
@weights = []
|
48
|
+
(number_of_inputs + 1).times do
|
49
|
+
@weights << (rand > 0.5 ? -rand : rand)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/mlp/version.rb
ADDED
data/mlpnn.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'mlp/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'mlpnn'
|
9
|
+
s.version = MLP::VERSION
|
10
|
+
|
11
|
+
s.authors = %w(reddavis beastia)
|
12
|
+
s.date = '2017-01-19'
|
13
|
+
s.description = <<~TEXT
|
14
|
+
Multi-Layer Perceptron Neural Network in Ruby(remake of reddavis' project by BEaStia)"
|
15
|
+
TEXT
|
16
|
+
s.email = 'gophan1992@gmail.com'
|
17
|
+
s.extra_rdoc_files = %w(LICENSE README.rdoc)
|
18
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test|spec|features)/})
|
20
|
+
end
|
21
|
+
|
22
|
+
s.homepage = 'http://github.com/BEaStia/mlp'
|
23
|
+
s.require_paths = ['lib']
|
24
|
+
s.summary = 'Multi-Layer Perceptron Neural Network in Ruby'
|
25
|
+
s.required_ruby_version = '~> 2.3'
|
26
|
+
|
27
|
+
s.add_development_dependency 'bundler', '~> 1.13'
|
28
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
s.add_development_dependency 'rubocop', '~> 0.47'
|
30
|
+
s.add_development_dependency 'shoulda', '~> 3.5'
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mlpnn
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- reddavis
|
8
|
+
- beastia
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2017-01-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.13'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.13'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rubocop
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.47'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.47'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: shoulda
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.5'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.5'
|
70
|
+
description: 'Multi-Layer Perceptron Neural Network in Ruby(remake of reddavis'' project
|
71
|
+
by BEaStia)"
|
72
|
+
|
73
|
+
'
|
74
|
+
email: gophan1992@gmail.com
|
75
|
+
executables: []
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files:
|
78
|
+
- LICENSE
|
79
|
+
- README.rdoc
|
80
|
+
files:
|
81
|
+
- ".gitignore"
|
82
|
+
- ".rubocop.yml"
|
83
|
+
- Gemfile
|
84
|
+
- Gemfile.lock
|
85
|
+
- LICENSE
|
86
|
+
- README.rdoc
|
87
|
+
- Rakefile
|
88
|
+
- VERSION
|
89
|
+
- examples/backpropagation_example.rb
|
90
|
+
- examples/patterns_with_base_noise.rb
|
91
|
+
- examples/patterns_with_noise.rb
|
92
|
+
- examples/training_patterns.rb
|
93
|
+
- examples/xor.rb
|
94
|
+
- lib/mlp.rb
|
95
|
+
- lib/mlp/network.rb
|
96
|
+
- lib/mlp/neuron.rb
|
97
|
+
- lib/mlp/version.rb
|
98
|
+
- mlpnn.gemspec
|
99
|
+
homepage: http://github.com/BEaStia/mlp
|
100
|
+
licenses: []
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.3'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.6.8
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Multi-Layer Perceptron Neural Network in Ruby
|
122
|
+
test_files: []
|