ruby_brain 0.1.0
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 +10 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +48 -0
- data/README.org +237 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/mnist.rb +79 -0
- data/examples/mnist2.rb +82 -0
- data/lib/ruby_brain.rb +19 -0
- data/lib/ruby_brain/dataset/mnist/data.rb +62 -0
- data/lib/ruby_brain/dataset/mnist/test_mnist.rb +28 -0
- data/lib/ruby_brain/exception.rb +17 -0
- data/lib/ruby_brain/layer.rb +37 -0
- data/lib/ruby_brain/network.rb +252 -0
- data/lib/ruby_brain/nodes.rb +58 -0
- data/lib/ruby_brain/trainer.rb +71 -0
- data/lib/ruby_brain/training_data_manipulator.rb +35 -0
- data/lib/ruby_brain/version.rb +3 -0
- data/lib/ruby_brain/weights.rb +82 -0
- data/ruby_brain.gemspec +34 -0
- metadata +125 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module RubyBrain::Nodes
|
2
|
+
class Neuron
|
3
|
+
attr_accessor :order_index, :left_side_weights, :right_side_weights
|
4
|
+
attr_reader :this_output, :this_backward_output
|
5
|
+
|
6
|
+
def initialize(gain=1.0)
|
7
|
+
@gain = gain
|
8
|
+
@this_output = nil
|
9
|
+
@this_backward_output = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_sigmoid_output(sigmoid_input)
|
13
|
+
1.0 / (1 + Math.exp(-1 * @gain * sigmoid_input))
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_backward_sigmoid_output(backward_sigmoid_input)
|
17
|
+
@gain * (1 - @this_output) * @this_output * backward_sigmoid_input
|
18
|
+
end
|
19
|
+
|
20
|
+
def output_of_forward_calc(inputs)
|
21
|
+
sigmoid_input = 0.0
|
22
|
+
@left_side_weights.transpose[@order_index].zip(inputs).each do |weight, input|
|
23
|
+
sigmoid_input += input * weight
|
24
|
+
end
|
25
|
+
@this_output = get_sigmoid_output(sigmoid_input)
|
26
|
+
end
|
27
|
+
|
28
|
+
def output_of_backward_calc(backward_inputs)
|
29
|
+
sigmoid_backward_input = 0.0
|
30
|
+
if @right_side_weights.nil?
|
31
|
+
sigmoid_backward_input = backward_inputs[@order_index]
|
32
|
+
else
|
33
|
+
@right_side_weights[@order_index].zip(backward_inputs).each do |weight, input|
|
34
|
+
sigmoid_backward_input += input * weight
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@this_backward_output = get_backward_sigmoid_output(sigmoid_backward_input)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ConstNode
|
42
|
+
attr_accessor :order_index, :value, :left_side_weights, :right_side_weights
|
43
|
+
attr_reader :this_output, :this_backward_output
|
44
|
+
|
45
|
+
def initialize(value=1.0)
|
46
|
+
@value = value
|
47
|
+
@this_output = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def output_of_forward_calc(inputs=[])
|
51
|
+
@this_output = @value
|
52
|
+
end
|
53
|
+
|
54
|
+
def output_of_backward_calc(backward_inputs=[])
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module RubyBrain::Trainer
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def normal_learning(network_structure, input_training_set, output_training_set, options={})
|
7
|
+
default_options = {learning_rate: 0.05, max_training_count: 5000, tolerance: 0.045, initial_weights_file: nil}
|
8
|
+
training_options = default_options.merge(options)
|
9
|
+
puts "===== normal learnng ====="
|
10
|
+
pp training_options
|
11
|
+
network = RubyBrain::Network.new(network_structure)
|
12
|
+
network.learning_rate = training_options[:learning_rate]
|
13
|
+
network.init_network
|
14
|
+
if training_options[:initial_weights_file]
|
15
|
+
puts "loading weights from #{training_options[:initial_weights_file]}"
|
16
|
+
network.load_weights_from_yaml_file(training_options[:initial_weights_file])
|
17
|
+
end
|
18
|
+
network.learn(input_training_set, output_training_set, max_training_count=training_options[:max_training_count], tolerance=training_options[:tolerance])
|
19
|
+
|
20
|
+
network.dump_weights_to_yaml("weights_#{network_structure.join('_')}_#{Time.now.to_i}.yml")
|
21
|
+
|
22
|
+
# input_training_set.each do |inputs|
|
23
|
+
# puts network.get_forward_outputs(inputs).join(',')
|
24
|
+
# end
|
25
|
+
end
|
26
|
+
|
27
|
+
def learn2(network_structure, input_training_set, output_training_set)
|
28
|
+
network = RubyBrain::Network.new(network_structure)
|
29
|
+
network.learning_rate = 0.05
|
30
|
+
network.init_network
|
31
|
+
network.learn2(input_training_set, output_training_set, max_training_count=5000, tolerance=0.045)
|
32
|
+
|
33
|
+
puts network.dump_weights_to_yaml
|
34
|
+
|
35
|
+
input_training_set.each do |inputs|
|
36
|
+
pp network.get_forward_outputs(inputs)[0]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def stack_learning(network_structure, input_training_set, output_training_set)
|
41
|
+
ws = Array.new(network_structure.size-1, nil)
|
42
|
+
(1..(network_structure.size-2)).each do |i|
|
43
|
+
next_network_form = network_structure[0..i] + [network_structure[-1]]
|
44
|
+
neuralnet = RubyBrain::Network.new(next_network_form)
|
45
|
+
neuralnet.learning_rate = 0.05
|
46
|
+
neuralnet.init_network
|
47
|
+
neuralnet.overwrite_weights(ws)
|
48
|
+
# neuralnet.learn_only_specified_layer(-1, input_training_set, output_training_set, max_training_count=1000, tolerance=0.06)
|
49
|
+
neuralnet.learn2(input_training_set, output_training_set, max_training_count=500, tolerance=0.006)
|
50
|
+
ws = neuralnet.get_weights_as_array
|
51
|
+
ws[-1] = nil
|
52
|
+
end
|
53
|
+
neuralnet = RubyBrain::Network.new(network_structure)
|
54
|
+
neuralnet.learning_rate = 0.05
|
55
|
+
neuralnet.init_network
|
56
|
+
neuralnet.overwrite_weights(ws)
|
57
|
+
neuralnet.learn(input_training_set, output_training_set, max_training_count=2000, tolerance=0.0036)
|
58
|
+
# neuralnet.learn2(input_training_set, output_training_set, max_training_count=1000, tolerance=0.036)
|
59
|
+
|
60
|
+
puts neuralnet.dump_weights_to_yaml
|
61
|
+
|
62
|
+
input_training_set.each do |inputs|
|
63
|
+
pp neuralnet.get_forward_outputs(inputs)[0]
|
64
|
+
end
|
65
|
+
puts "==================================================================================================="
|
66
|
+
input_training_set.each do |inputs|
|
67
|
+
pp neuralnet.get_forward_outputs(inputs)[1]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module RubyBrain
|
4
|
+
class TrainingDataManipulator
|
5
|
+
attr_accessor :columns
|
6
|
+
def initialize(data_file, has_header)
|
7
|
+
puts data_file
|
8
|
+
@columns = []
|
9
|
+
@raw_data = parse_data(data_file, has_header)
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_data(data_file, has_header)
|
13
|
+
array_of_data_set = []
|
14
|
+
File.open(data_file) do |f|
|
15
|
+
@columns = f.readline.chomp.split(',') if has_header
|
16
|
+
f.each_line do |line|
|
17
|
+
next if /\A\s+\z/ =~ line
|
18
|
+
array_of_data_set << line.chomp.split(',')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
array_of_data_set
|
22
|
+
end
|
23
|
+
|
24
|
+
def ix(*col_index)
|
25
|
+
@raw_data.map do |a_set|
|
26
|
+
a_set.values_at(*col_index).map(&:to_f)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def num_data_sets
|
31
|
+
@raw_data.length
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module RubyBrain
|
2
|
+
class WeightContainer
|
3
|
+
def initialize(num_units_list)
|
4
|
+
@w_3d = []
|
5
|
+
|
6
|
+
num_units_list.each_cons(2) do |num_units_on_left_layer, num_units_on_right_layer|
|
7
|
+
@w = []
|
8
|
+
(num_units_on_left_layer + 1).times do |i|
|
9
|
+
@w[i] = []
|
10
|
+
num_units_on_right_layer.times do |j|
|
11
|
+
@w[i][j] = Random.rand(2.0) - 1.0
|
12
|
+
end
|
13
|
+
end
|
14
|
+
@w_3d << @w
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_from(weights_set_source)
|
19
|
+
@w_3d = weights_set_source
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_weights_as_array
|
23
|
+
@w_3d.dup
|
24
|
+
end
|
25
|
+
|
26
|
+
def overwrite_weights(weights_set_source)
|
27
|
+
# weights_set_source.each_with_index do |weights, i|
|
28
|
+
# next if i >= @w_3d.size
|
29
|
+
# weights.each_with_index do |w, j|
|
30
|
+
# next if j >= @w_3d[i].size
|
31
|
+
# w.size.times do |k|
|
32
|
+
# @w_3d[i][j][k] = w[k] unless w[k].nil?
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
|
37
|
+
@w_3d.zip(weights_set_source).each_with_index do |wl, i|
|
38
|
+
next if wl[1].nil?
|
39
|
+
wl[0].zip(wl[1]).each_with_index do |ww, j|
|
40
|
+
next if ww[1].nil?
|
41
|
+
ww[0].zip(ww[1]).each_with_index do |w, k|
|
42
|
+
@w_3d[i][j][k] = w[1] || w[0]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def num_sets
|
50
|
+
@w_3d.size
|
51
|
+
end
|
52
|
+
|
53
|
+
def weights_of_order(order_number)
|
54
|
+
@w_3d[order_number]
|
55
|
+
end
|
56
|
+
|
57
|
+
def dump_to_yaml(file_name=nil)
|
58
|
+
if file_name
|
59
|
+
File.open file_name, 'w+' do |f|
|
60
|
+
YAML.dump(@w_3d, f)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
# @w_3d.to_yaml
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_from_yaml_file(yaml_file)
|
67
|
+
overwrite_weights(YAML.load_file(yaml_file))
|
68
|
+
end
|
69
|
+
|
70
|
+
def each_weights
|
71
|
+
@w_3d.each do |weights|
|
72
|
+
yield weights
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def each_weights_with_index
|
77
|
+
@w_3d.each_with_index do |weights, i|
|
78
|
+
yield weights, i
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/ruby_brain.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 'ruby_brain/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ruby_brain"
|
8
|
+
spec.version = RubyBrain::VERSION
|
9
|
+
spec.authors = ["elgoog"]
|
10
|
+
spec.email = ["elgoog.development@gmail.com"]
|
11
|
+
spec.summary = %q{NeuralNet/DeepLearning implement for Ruby}
|
12
|
+
spec.description = %q{NeuralNet/DeepLearning implement for Ruby}
|
13
|
+
spec.homepage = "https://github.com/elgoog/ruby_brain/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
# if spec.respond_to?(:metadata)
|
19
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
20
|
+
# else
|
21
|
+
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
22
|
+
# end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
32
|
+
|
33
|
+
spec.add_runtime_dependency "mnist"
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_brain
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- elgoog
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
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
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
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
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mnist
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: NeuralNet/DeepLearning implement for Ruby
|
70
|
+
email:
|
71
|
+
- elgoog.development@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- README.org
|
83
|
+
- Rakefile
|
84
|
+
- bin/console
|
85
|
+
- bin/setup
|
86
|
+
- examples/mnist.rb
|
87
|
+
- examples/mnist2.rb
|
88
|
+
- lib/ruby_brain.rb
|
89
|
+
- lib/ruby_brain/dataset/mnist/data.rb
|
90
|
+
- lib/ruby_brain/dataset/mnist/test_mnist.rb
|
91
|
+
- lib/ruby_brain/exception.rb
|
92
|
+
- lib/ruby_brain/layer.rb
|
93
|
+
- lib/ruby_brain/network.rb
|
94
|
+
- lib/ruby_brain/nodes.rb
|
95
|
+
- lib/ruby_brain/trainer.rb
|
96
|
+
- lib/ruby_brain/training_data_manipulator.rb
|
97
|
+
- lib/ruby_brain/version.rb
|
98
|
+
- lib/ruby_brain/weights.rb
|
99
|
+
- ruby_brain.gemspec
|
100
|
+
homepage: https://github.com/elgoog/ruby_brain/
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.5.1
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: NeuralNet/DeepLearning implement for Ruby
|
124
|
+
test_files: []
|
125
|
+
has_rdoc:
|