sabina 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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +16 -0
  5. data/CODE_OF_CONDUCT.md +49 -0
  6. data/Gemfile +13 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +201 -0
  9. data/Rakefile +4 -0
  10. data/examples/example_ae_01/ae_learning_process.gif +0 -0
  11. data/examples/example_ae_01/ae_original_data.png +0 -0
  12. data/examples/example_ae_01/main.rb +123 -0
  13. data/examples/example_ae_01/training_data.csv +821 -0
  14. data/examples/example_mp_01/main.rb +158 -0
  15. data/examples/example_mp_01/mp_learning_process.gif +0 -0
  16. data/examples/example_mp_01/mp_training_data.png +0 -0
  17. data/examples/example_mp_01/training_data.csv +601 -0
  18. data/examples/example_mp_02/main.rb +170 -0
  19. data/examples/example_mp_02/mp_learning_process.gif +0 -0
  20. data/examples/example_mp_02/mp_training_data.png +0 -0
  21. data/examples/example_mp_02/training_data.csv +821 -0
  22. data/lib/sabina/auto_encoder.rb +46 -0
  23. data/lib/sabina/configuration.rb +41 -0
  24. data/lib/sabina/layer/ae_hidden_layer.rb +10 -0
  25. data/lib/sabina/layer/ae_input_layer.rb +4 -0
  26. data/lib/sabina/layer/ae_output_layer.rb +10 -0
  27. data/lib/sabina/layer/base_layer.rb +33 -0
  28. data/lib/sabina/layer/mp_hidden_layer.rb +4 -0
  29. data/lib/sabina/layer/mp_input_layer.rb +4 -0
  30. data/lib/sabina/layer/mp_output_layer.rb +12 -0
  31. data/lib/sabina/layer.rb +11 -0
  32. data/lib/sabina/multilayer_perceptron.rb +135 -0
  33. data/lib/sabina/sparse_auto_encoder.rb +49 -0
  34. data/lib/sabina/util.rb +11 -0
  35. data/lib/sabina/version.rb +3 -0
  36. data/lib/sabina.rb +17 -0
  37. data/sabina.gemspec +37 -0
  38. metadata +124 -0
@@ -0,0 +1,170 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
2
+ require 'open3'
3
+ require 'sabina'
4
+
5
+ DIM = 2
6
+ K = 3
7
+ LOOP_NUM = 100
8
+ xrange = [-2.2, 2.2]
9
+ yrange = [-2.2, 2.2]
10
+
11
+ training_data = Sabina::MultilayerPerceptron.load_csv('training_data.csv')
12
+
13
+ # You can create your own layer class.
14
+ # In this example, a rectified linear function is set
15
+ # as an activation function.
16
+ # @f_ is differentiation of @f.
17
+ class MyHiddenLayer < Sabina::Layer::BaseLayer
18
+ def initialize(size)
19
+ super
20
+ @f = ->(x){ x > 0.0 ? x : 0.0 }
21
+ @f_ = ->(x){ x > 0.0 ? 1.0 : 0.0 }
22
+ end
23
+ end
24
+
25
+ options = {
26
+ :layers => [
27
+ Sabina::Layer::MPInputLayer.new(DIM),
28
+ MyHiddenLayer.new(16),
29
+ MyHiddenLayer.new(8),
30
+ Sabina::Layer::MPOutputLayer.new(K)
31
+ ],
32
+ :mini_batch_size => 10,
33
+ :learning_rate => 0.01,
34
+ :training_data => training_data,
35
+ }
36
+
37
+ mp = Sabina::MultilayerPerceptron.new(options)
38
+
39
+
40
+
41
+ ##################################################
42
+ # Make a chart of trainig data.
43
+ ##################################################
44
+ Open3.popen3('gnuplot') do |gp_in, gp_out, gp_err|
45
+ output_file = "./mp_training_data.png"
46
+ gp_in.puts "set colorsequence classic"
47
+ gp_in.puts "set terminal png size 480, 450"
48
+ gp_in.puts "set output '#{output_file}'"
49
+ gp_in.puts "set label 2 center at screen 0.5,0.9 'Training Data' font 'Helvetica,22'"
50
+ gp_in.puts "set tmargin 3.2"
51
+ gp_in.puts "set xlabel 'x0'"
52
+ gp_in.puts "set ylabel 'x1'"
53
+ gp_in.puts "set size square"
54
+ gp_in.puts xrange.tap { |f, t| break "set xrange [#{f}:#{t}]" }
55
+ gp_in.puts yrange.tap { |f, t| break "set yrange [#{f}:#{t}]" }
56
+ plot = "plot "
57
+
58
+ K.times do |k|
59
+ plot << "'-' notitle pt 1 ps 1 lc #{k+1},\\\n"
60
+ end
61
+ plot.gsub!(/,\\\n\z/, "\n")
62
+
63
+ K.times do |k|
64
+ label = Array.new(K) { |j| j == k ? 1 : 0 }
65
+ training_data.each do |data|
66
+ if label == data[:d]
67
+ data[:x].tap { |x, y| plot << "#{x}, #{y}\n" }
68
+ end
69
+ end
70
+ plot << "e\n"
71
+ end
72
+
73
+ gp_in.puts plot
74
+ puts output_file
75
+ gp_in.puts "set output"
76
+ gp_in.puts "exit"
77
+ gp_in.close
78
+ end
79
+
80
+
81
+ ##################################################
82
+ # Make a GIF of the learning process.
83
+ ##################################################
84
+ Open3.popen3('gnuplot') do |gp_in, gp_out, gp_err|
85
+ output_file = "./mp_learning_process.gif"
86
+ gp_in.puts "set colorsequence classic"
87
+ gp_in.puts "set terminal gif animate delay 10 optimize size 880, 450"
88
+ gp_in.puts "set output '#{output_file}'"
89
+ gp_in.puts "set tmargin 3.2"
90
+ gp_in.puts "set size square"
91
+ log = []
92
+ tmp_data = xrange.map { |v| (20*v).to_i }.tap { |f, t| break [*f..t] }
93
+ .product yrange.map { |v| (20*v).to_i }.tap { |f, t| break [*f..t] }
94
+ tmp_data.map! do |data|
95
+ data.each_with_object(0.05).map(&:*)
96
+ end
97
+ x_mat = Matrix.columns( tmp_data )
98
+
99
+ LOOP_NUM.times do |t|
100
+ mp.learn
101
+ log << mp.error(training_data)
102
+ gp_in.puts "set multiplot layout 1, 2"
103
+
104
+ ##################################################
105
+ # Training Data
106
+ ##################################################
107
+ gp_in.puts "set label 2 center at screen 0.28,0.9 'Training Data' font 'Helvetica,22'"
108
+ gp_in.puts xrange.tap { |f, t| break "set xrange [#{f}:#{t}]" }
109
+ gp_in.puts yrange.tap { |f, t| break "set yrange [#{f}:#{t}]" }
110
+ gp_in.puts "set xlabel 'x0'"
111
+ gp_in.puts "set ylabel 'x1'"
112
+ gp_in.puts "unset grid"
113
+ plot = "plot "
114
+
115
+ K.times do |k|
116
+ plot << "'-' notitle pt 1 ps 1 lc #{k+1},\\\n"
117
+ end
118
+ K.times do |k|
119
+ plot << "'-' notitle pt 7 ps 1 lc #{k+1},\\\n"
120
+ end
121
+ plot.gsub!(/,\\\n\z/, "\n")
122
+
123
+ y_ary = mp.propagate_forward(x_mat).t.to_a
124
+ K.times do |k|
125
+ tmp_data.each_with_index do |(x, y), n|
126
+ label = y_ary[n].index( y_ary[n].max )
127
+ plot << "#{x}, #{y}\n" if label == k
128
+ end
129
+ plot << "e\n"
130
+ end
131
+
132
+ K.times do |k|
133
+ label = Array.new(K) { |j| j == k ? 1 : 0 }
134
+ training_data.each do |data|
135
+ if label == data[:d]
136
+ data[:x].tap { |x, y| plot << "#{x}, #{y}\n" }
137
+ end
138
+ end
139
+ plot << "e\n"
140
+ end
141
+ gp_in.puts plot
142
+
143
+ ##################################################
144
+ # Training Error
145
+ ##################################################
146
+ gp_in.puts "set label 2 center at screen 0.79,0.9 'Training Error' font 'Helvetica,22'"
147
+ gp_in.puts "set xrange [0:#{LOOP_NUM}]"
148
+ gp_in.puts "set yrange [0:#{log.first + 10}]"
149
+ gp_in.puts "set xlabel 'iteration number'"
150
+ gp_in.puts "set ylabel 'training error'"
151
+ gp_in.puts "set grid"
152
+ plot = "plot "
153
+
154
+ plot << "'-' notitle with lines lw 3 lt 1 lc 1,\\\n"
155
+ plot.gsub!(/,\\\n\z/, "\n")
156
+ log.each { |x, y| plot << "#{x}, #{y}\n" }
157
+ plot << "e\n"
158
+ gp_in.puts plot
159
+
160
+ # progress bar
161
+ puts " error : #{log.last}"
162
+ puts " [#{("*"*(t / (LOOP_NUM / 10))).ljust(10, " ")}]"
163
+ print "\e[2A"; STDOUT.flush;
164
+ end
165
+
166
+ gp_in.puts "set output"
167
+ puts output_file
168
+ gp_in.puts "exit"
169
+ gp_in.close
170
+ end