CooCoo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/CooCoo.gemspec +47 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +88 -0
  6. data/README.md +123 -0
  7. data/Rakefile +81 -0
  8. data/bin/cuda-dev-info +25 -0
  9. data/bin/cuda-free +28 -0
  10. data/bin/cuda-free-trend +7 -0
  11. data/bin/ffi-gen +267 -0
  12. data/bin/spec_runner_html.sh +42 -0
  13. data/bin/trainer +198 -0
  14. data/bin/trend-cost +13 -0
  15. data/examples/char-rnn.rb +405 -0
  16. data/examples/cifar/cifar.rb +94 -0
  17. data/examples/img-similarity.rb +201 -0
  18. data/examples/math_ops.rb +57 -0
  19. data/examples/mnist.rb +365 -0
  20. data/examples/mnist_classifier.rb +293 -0
  21. data/examples/mnist_dream.rb +214 -0
  22. data/examples/seeds.rb +268 -0
  23. data/examples/seeds_dataset.txt +210 -0
  24. data/examples/t10k-images-idx3-ubyte +0 -0
  25. data/examples/t10k-labels-idx1-ubyte +0 -0
  26. data/examples/train-images-idx3-ubyte +0 -0
  27. data/examples/train-labels-idx1-ubyte +0 -0
  28. data/ext/buffer/Rakefile +50 -0
  29. data/ext/buffer/buffer.pre.cu +727 -0
  30. data/ext/buffer/matrix.pre.cu +49 -0
  31. data/lib/CooCoo.rb +1 -0
  32. data/lib/coo-coo.rb +18 -0
  33. data/lib/coo-coo/activation_functions.rb +344 -0
  34. data/lib/coo-coo/consts.rb +5 -0
  35. data/lib/coo-coo/convolution.rb +298 -0
  36. data/lib/coo-coo/core_ext.rb +75 -0
  37. data/lib/coo-coo/cost_functions.rb +91 -0
  38. data/lib/coo-coo/cuda.rb +116 -0
  39. data/lib/coo-coo/cuda/device_buffer.rb +240 -0
  40. data/lib/coo-coo/cuda/device_buffer/ffi.rb +109 -0
  41. data/lib/coo-coo/cuda/error.rb +51 -0
  42. data/lib/coo-coo/cuda/host_buffer.rb +117 -0
  43. data/lib/coo-coo/cuda/runtime.rb +157 -0
  44. data/lib/coo-coo/cuda/vector.rb +315 -0
  45. data/lib/coo-coo/data_sources.rb +2 -0
  46. data/lib/coo-coo/data_sources/xournal.rb +25 -0
  47. data/lib/coo-coo/data_sources/xournal/bitmap_stream.rb +197 -0
  48. data/lib/coo-coo/data_sources/xournal/document.rb +377 -0
  49. data/lib/coo-coo/data_sources/xournal/loader.rb +144 -0
  50. data/lib/coo-coo/data_sources/xournal/renderer.rb +101 -0
  51. data/lib/coo-coo/data_sources/xournal/saver.rb +99 -0
  52. data/lib/coo-coo/data_sources/xournal/training_document.rb +78 -0
  53. data/lib/coo-coo/data_sources/xournal/training_document/constants.rb +15 -0
  54. data/lib/coo-coo/data_sources/xournal/training_document/document_maker.rb +89 -0
  55. data/lib/coo-coo/data_sources/xournal/training_document/document_reader.rb +105 -0
  56. data/lib/coo-coo/data_sources/xournal/training_document/example.rb +37 -0
  57. data/lib/coo-coo/data_sources/xournal/training_document/sets.rb +76 -0
  58. data/lib/coo-coo/debug.rb +8 -0
  59. data/lib/coo-coo/dot.rb +129 -0
  60. data/lib/coo-coo/drawing.rb +4 -0
  61. data/lib/coo-coo/drawing/cairo_canvas.rb +100 -0
  62. data/lib/coo-coo/drawing/canvas.rb +68 -0
  63. data/lib/coo-coo/drawing/chunky_canvas.rb +101 -0
  64. data/lib/coo-coo/drawing/sixel.rb +214 -0
  65. data/lib/coo-coo/enum.rb +17 -0
  66. data/lib/coo-coo/from_name.rb +58 -0
  67. data/lib/coo-coo/fully_connected_layer.rb +205 -0
  68. data/lib/coo-coo/generation_script.rb +38 -0
  69. data/lib/coo-coo/grapher.rb +140 -0
  70. data/lib/coo-coo/image.rb +286 -0
  71. data/lib/coo-coo/layer.rb +67 -0
  72. data/lib/coo-coo/layer_factory.rb +26 -0
  73. data/lib/coo-coo/linear_layer.rb +59 -0
  74. data/lib/coo-coo/math.rb +607 -0
  75. data/lib/coo-coo/math/abstract_vector.rb +121 -0
  76. data/lib/coo-coo/math/functions.rb +39 -0
  77. data/lib/coo-coo/math/interpolation.rb +7 -0
  78. data/lib/coo-coo/network.rb +264 -0
  79. data/lib/coo-coo/neuron.rb +112 -0
  80. data/lib/coo-coo/neuron_layer.rb +168 -0
  81. data/lib/coo-coo/option_parser.rb +18 -0
  82. data/lib/coo-coo/platform.rb +17 -0
  83. data/lib/coo-coo/progress_bar.rb +11 -0
  84. data/lib/coo-coo/recurrence/backend.rb +99 -0
  85. data/lib/coo-coo/recurrence/frontend.rb +101 -0
  86. data/lib/coo-coo/sequence.rb +187 -0
  87. data/lib/coo-coo/shell.rb +2 -0
  88. data/lib/coo-coo/temporal_network.rb +291 -0
  89. data/lib/coo-coo/trainer.rb +21 -0
  90. data/lib/coo-coo/trainer/base.rb +67 -0
  91. data/lib/coo-coo/trainer/batch.rb +82 -0
  92. data/lib/coo-coo/trainer/batch_stats.rb +27 -0
  93. data/lib/coo-coo/trainer/momentum_stochastic.rb +59 -0
  94. data/lib/coo-coo/trainer/stochastic.rb +47 -0
  95. data/lib/coo-coo/transformer.rb +272 -0
  96. data/lib/coo-coo/vector_layer.rb +194 -0
  97. data/lib/coo-coo/version.rb +3 -0
  98. data/lib/coo-coo/weight_deltas.rb +23 -0
  99. data/prototypes/convolution.rb +116 -0
  100. data/prototypes/linear_drop.rb +51 -0
  101. data/prototypes/recurrent_layers.rb +79 -0
  102. data/www/images/screamer.png +0 -0
  103. data/www/images/screamer.xcf +0 -0
  104. data/www/index.html +82 -0
  105. metadata +373 -0
@@ -0,0 +1,68 @@
1
+ require 'chunky_png'
2
+ require 'coo-coo/math'
3
+
4
+ module CooCoo
5
+ module Drawing
6
+ class Canvas
7
+ attr_accessor :fill_color, :stroke_color
8
+
9
+ def fill_color=(c)
10
+ @fill_color = ChunkyPNG::Color.parse(c)
11
+ end
12
+
13
+ def stroke_color=(c)
14
+ @stroke_color = ChunkyPNG::Color.parse(c)
15
+ end
16
+
17
+ def flush
18
+ self
19
+ end
20
+
21
+ def line(x1, y1, x2, y2)
22
+ self
23
+ end
24
+
25
+ def stroke(points)
26
+ self
27
+ end
28
+
29
+ def rect(x, y, w, h)
30
+ self
31
+ end
32
+
33
+ def circle(x, y, r)
34
+ self
35
+ end
36
+
37
+ def blit(img, x, y)
38
+ self
39
+ end
40
+
41
+ def text(txt, x, y, font, size, style = nil)
42
+ self
43
+ end
44
+
45
+ protected
46
+ def color_components(c)
47
+ [ ChunkyPNG::Color.r(c),
48
+ ChunkyPNG::Color.g(c),
49
+ ChunkyPNG::Color.b(c)
50
+ ]
51
+ end
52
+
53
+ def to_grayscale(c)
54
+ ChunkyPNG::Color.r(ChunkyPNG::Color.to_grayscale(c))
55
+ end
56
+
57
+ def chunky_to_vector(img, grayscale)
58
+ f = if grayscale
59
+ method(:to_grayscale)
60
+ else
61
+ method(:color_components)
62
+ end
63
+
64
+ Vector[img.pixels.collect(&f).flatten]
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,101 @@
1
+ require 'chunky_png'
2
+ require 'coo-coo/math'
3
+
4
+ module CooCoo
5
+ module Drawing
6
+ class ChunkyCanvas < Canvas
7
+ attr_reader :image
8
+
9
+ def initialize(img_or_width, height = nil)
10
+ if height
11
+ img = ChunkyPNG::Image.new(img_or_width, height)
12
+ else
13
+ img = img_or_width
14
+ end
15
+
16
+ @image = img
17
+ end
18
+
19
+ def line(x1, y1, x2, y2)
20
+ @image.line(x1, y1, x2, y2, stroke_color)
21
+ self
22
+ end
23
+
24
+ def stroke(points)
25
+ last_x = points[0][0]
26
+ last_y = points[0][1]
27
+ last_w = points[0][2] || 1.0
28
+ last_color = points[0][3]
29
+
30
+ points.each.drop(1).each do |(x, y, w, color)|
31
+ w ||= 1.0
32
+
33
+ if color
34
+ self.stroke_color = color
35
+ self.fill_color = color
36
+ end
37
+
38
+ if w <= 1.0
39
+ line(last_x.to_i, last_y.to_i, x.to_i, y.to_i)
40
+ else
41
+ step_x = (x / w).abs.round
42
+ step_y = (y / w).abs.round
43
+ steps = Math.max(step_x, step_y)
44
+ steps = 4.0 if steps < 4.0
45
+
46
+ (steps + 1).to_i.times do |n|
47
+ t = n / steps.to_f
48
+ if color
49
+ self.stroke_color = lerp_color(last_color, color, t)
50
+ self.fill_color = lerp_color(last_color, color, t)
51
+ end
52
+
53
+ circle(Math.lerp(last_x, x, t).to_i,
54
+ Math.lerp(last_y, y, t).to_i,
55
+ (Math.lerp(last_w, w, t)/2.0).ceil.to_i)
56
+ end
57
+ end
58
+
59
+ last_x = x
60
+ last_y = y
61
+ last_w = w
62
+ last_color = color
63
+ end
64
+
65
+ self
66
+ end
67
+
68
+ def lerp_color(a, b, t)
69
+ ChunkyPNG::Color.interpolate_quick(a, b, (t * 256).to_i)
70
+ end
71
+
72
+ def rect(x, y, w, h)
73
+ @image.rect(x, y, w, h, stroke_color, fill_color)
74
+ self
75
+ end
76
+
77
+ def circle(x, y, r)
78
+ @image.circle(x, y, r, stroke_color, fill_color)
79
+ self
80
+ end
81
+
82
+ def blit(other, x, y, w, h)
83
+ img = ChunkyPNG::Image.from_blob(other)
84
+ if w != img.width || h != img.height
85
+ img.resample_bilinear!(w.to_i, h.to_i)
86
+ end
87
+ @image.compose!(img, x.to_i, y.to_i)
88
+ self
89
+ end
90
+
91
+ def text(txt, x, y, font, font_size, font_style = nil)
92
+ self
93
+ end
94
+
95
+ def to_vector(grayscale = false)
96
+ chunky_to_vector(@image, grayscale)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,214 @@
1
+ require 'stringio'
2
+
3
+ module CooCoo
4
+ module Drawing
5
+ module Sixel
6
+ def self.from_array(a, width, height = nil)
7
+ s = Stringer.new
8
+ s.begin_sixel + s.from_array(a, width, height) + s.newline + s.finish_sixel
9
+ end
10
+
11
+ def self.with_sixel(io = $stdout, &block)
12
+ Streamer.new(io) do |s|
13
+ block.call(s)
14
+ end
15
+ end
16
+
17
+ def self.to_string(&block)
18
+ stream = StringIO.new
19
+ Streamer.new(stream, &block)
20
+ stream.string
21
+ end
22
+
23
+ class Streamer
24
+ def initialize(io = $stdout, stringer = Stringer.new, &block)
25
+ @io = io
26
+ @stringer = stringer
27
+ with_sixel(&block)
28
+ end
29
+
30
+ def method_missing(mid, *args, &block)
31
+ @io.write(@stringer.send(mid, *args, &block))
32
+ end
33
+
34
+ def with_sixel(&block)
35
+ begin_sixel
36
+ block.call(self)
37
+ ensure
38
+ finish_sixel
39
+ end
40
+ end
41
+
42
+ class Stringer
43
+ RGB = Struct.new(:r, :g, :b)
44
+ HSL = Struct.new(:h, :s, :l)
45
+
46
+ def initialize(options = Hash.new)
47
+ @max_colors = options.fetch(:max_colors, 256)
48
+ @colors = Array.new(@max_colors)
49
+ @background = options.fetch(:background, 0)
50
+ end
51
+
52
+ def from_array(a, width, height = nil)
53
+ height ||= (a.size / width.to_f).ceil
54
+ max_color = a.max.ceil
55
+
56
+ (height / 6.0).ceil.times.collect do |y|
57
+ (max_color + 1).times.collect do |c|
58
+ #next if c == 0
59
+ in_color(c) + width.times.collect do |x|
60
+ sixel_line(c, *6.times.collect { |i|
61
+ a[(y*6+i) * width + x] rescue @background
62
+ })
63
+ end.join
64
+ end.join(cr)
65
+ end.join(newline)
66
+ end
67
+
68
+ def sixel_line(c, *pixels)
69
+ line = 6.times.inject(0) { |acc, i|
70
+ if pixels[i].to_i == c
71
+ (acc | (1 << i))
72
+ else
73
+ acc
74
+ end
75
+ }
76
+ [ 63 + line ].pack('c')
77
+ end
78
+
79
+ def move_to(x, y)
80
+ finish_sixel + "\e[#{y.to_i};#{x.to_i}H" + begin_sixel
81
+ end
82
+
83
+ def set_color(c, r, g, b)
84
+ @colors[c] = RGB.new(r, g, b)
85
+ emit_color(c)
86
+ end
87
+
88
+ def set_color_hsl(c, h, s, l)
89
+ @colors[c] = HSL.new(h, s, l)
90
+ emit_color(c)
91
+ end
92
+
93
+ def emit_color(n, c = nil)
94
+ case c
95
+ when RGB then "\##{n.to_i};2;#{c.r.to_i};#{c.g.to_i};#{c.b.to_i}"
96
+ when HSL then "\##{n.to_i};1;#{c.h.to_i};#{c.s.to_i};#{c.l.to_i}"
97
+ else @colors[n] && emit_color(n, @colors[n])
98
+ end
99
+ end
100
+
101
+ def emit_all_colors
102
+ @colors.each.with_index.collect do |c, i|
103
+ emit_color(i, c) if c
104
+ end.join
105
+ end
106
+
107
+ def in_color(c)
108
+ "\##{c}"
109
+ end
110
+
111
+ def start_sixel
112
+ "\ePq"
113
+ end
114
+
115
+ def begin_sixel
116
+ start_sixel + emit_all_colors
117
+ end
118
+
119
+ def finish_sixel
120
+ "\e\\"
121
+ end
122
+
123
+ def cr
124
+ "$"
125
+ end
126
+
127
+ def lf
128
+ "-\n"
129
+ end
130
+
131
+ def newline
132
+ cr + lf
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ if __FILE__ == $0
140
+ require 'coo-coo/math'
141
+
142
+ HI = <<-EOT
143
+ \ePq
144
+ \#0;2;0;0;0\#1;2;100;0;0\#2;2;0;100;0
145
+ \#1~~@@vv@@~~@@~~$
146
+ \#2??}}GG}}??}}??-
147
+ \#1!14@
148
+ \e\\
149
+ EOT
150
+
151
+ arr = 100.times.collect { |y|
152
+ 100.times.collect { |x|
153
+ 8 + (8 * (Math.cos(y / 100.0 * 6.28) * Math.sin(x / 100.0 * 6.28))).to_i
154
+ }
155
+ }.flatten
156
+ line = 100.times.collect { |y| 40.times.collect { |i| (i < 2 || i > 37) ? 15 : 0 } }.flatten
157
+ stringer = CooCoo::Drawing::Sixel::Stringer.new
158
+
159
+ puts(HI)
160
+
161
+ puts
162
+ puts("In sixel")
163
+ puts(stringer.begin_sixel)
164
+ puts("\#0;2;100;0;0\#1;2;0;100;0\#2;2;0;0;100")
165
+ 16.times {
166
+ $stdout.write(stringer.sixel_line(1, 1, 1, 0, 0, 1, 1))
167
+ }
168
+ puts
169
+ puts(stringer.sixel_line(1, 0, 0, 1, 1, 0, 0))
170
+ puts(stringer.sixel_line(1, 0, 0, 1, 1, 0, 0))
171
+ puts(stringer.sixel_line(2, 1, 1, 2, 2, 1, 1))
172
+ puts(stringer.sixel_line(2, 1, 1, 2, 2, 1, 1))
173
+ puts(stringer.sixel_line(1, 1, 1, 1, 1, 1, 1))
174
+ puts(stringer.sixel_line(1, 1, 1, 1, 1, 1, 1))
175
+ puts(stringer.sixel_line(1, 1, 1, 1, 1, 1, 1))
176
+ puts(stringer.finish_sixel)
177
+
178
+ puts("And the big one:")
179
+ puts
180
+ puts(stringer.begin_sixel)
181
+ #puts("\#0;2;100;0;0\#1;2;0;100;0\#2;2;0;0;100\#3;2;100,100,100")
182
+ 16.times { |i| puts(stringer.set_color(i, i * 100 / 16.0, i * 100 / 16.0, i * 100 / 16.0)) }
183
+ # puts(stringer.set_color(0, 100, 0, 0) +
184
+ # stringer.set_color(1, 0, 100, 0) +
185
+ # stringer.set_color(2, 0, 0, 100) +
186
+ # stringer.set_color(3, 100, 100, 100))
187
+ puts(stringer.from_array(arr, 100, 100))
188
+ puts(stringer.cr)
189
+ puts(stringer.from_array(arr.collect { |a| arr.max - a }, 100, 100))
190
+ puts(stringer.newline)
191
+ puts(stringer.newline)
192
+ puts(stringer.from_array(line, 40, 100))
193
+ puts(stringer.finish_sixel)
194
+
195
+ v = CooCoo::Vector.new(28 * 28, 2)
196
+ CooCoo::Drawing::Sixel.with_sixel do |s|
197
+ s.set_color(0, 0, 0, 0)
198
+ s.set_color(1, 100, 0, 0)
199
+ s.set_color(2, 100, 100, 100)
200
+ s.set_color(3, 100, 0, 100)
201
+ s.set_color(3, 50, 50, 50)
202
+ s.from_array(CooCoo::Vector[64.times] / 16, 64, 1)
203
+ s.from_array(CooCoo::Vector[64.times] / 16, 1, 64)
204
+ s.from_array(CooCoo::Vector[64.times] / 16, 8, 8)
205
+ s.newline
206
+ s.from_array(v, 28)
207
+ s.newline
208
+ s.from_array(CooCoo::Vector.new(28 * 28, 3), 28)
209
+ s.newline
210
+ s.from_array(CooCoo::Vector.rand(28 * 28, 4), 28)
211
+ end
212
+
213
+ puts("Good bye.")
214
+ end
@@ -0,0 +1,17 @@
1
+ require 'coo-coo/core_ext'
2
+
3
+ class Enumerator
4
+ define_once(:zero) do
5
+ Array.new(size, self.first.zero)
6
+ end
7
+
8
+ define_once(:sum) do
9
+ inject(0) do |acc, e|
10
+ acc += e
11
+ end
12
+ end
13
+
14
+ define_once(:average) do
15
+ sum / (size || count)
16
+ end
17
+ end
@@ -0,0 +1,58 @@
1
+ module CooCoo
2
+ # Adds class methods to register classes that can be instantiated
3
+ # using strings.
4
+ #
5
+ # To get an instance, use {#from_name}.
6
+ #
7
+ # To add classes to the registry, call {#register}, preferably
8
+ # inside the class definition.
9
+ module FromName
10
+ # Adds a class to the registry using the given name.
11
+ # @param klass [Class] the class to instantiate
12
+ # @param name [String] name to use when calling #from_name
13
+ # @return [self]
14
+ def register(klass, name = nil)
15
+ @klasses ||= Hash.new
16
+ @klasses[(name || klass.name).split('::').last] = klass
17
+ self
18
+ end
19
+
20
+ # @return [Array] of names of all the registered classes.
21
+ def named_classes
22
+ @klasses.keys.sort
23
+ end
24
+
25
+ # @return [Enumerator] of all the registered classes.
26
+ def each(&block)
27
+ @klasses.each(&block)
28
+ end
29
+
30
+ # Returns an instance of the class registered with the given name.
31
+ # @param name [String] Registered name of the class with optional arguments in parenthesis.
32
+ # @param args Additional arguments to pass to the constructor. Overrides any given in the string.
33
+ # @return An instance of the registered class.
34
+ def from_name(name, *args)
35
+ name, params = parse_name(name)
36
+ klass = @klasses.fetch(name)
37
+ params = args unless args == nil || args.empty?
38
+
39
+ if params && klass.respond_to?(:new)
40
+ klass.new(*params)
41
+ elsif klass.respond_to?(:instance)
42
+ klass.instance
43
+ else
44
+ klass
45
+ end
46
+ end
47
+
48
+ private
49
+ def parse_name(name)
50
+ m = name.match(/(\w+)\((.*)\)/)
51
+ if m
52
+ return m[1], m[2].split(',').collect(&:chomp)
53
+ else
54
+ return name, nil
55
+ end
56
+ end
57
+ end
58
+ end