caffe 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ module Caffe
2
+ TRAIN = Phase::TRAIN
3
+ TEST = Phase::TEST
4
+ CPU = SolverParameter::SolverMode::CPU
5
+ GPU = SolverParameter::SolverMode::GPU
6
+ end
@@ -0,0 +1,3 @@
1
+ module Caffe
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,104 @@
1
+ RSpec.describe Caffe::Blob do
2
+ before :example do
3
+ @blob = Caffe::Blob.new [1, 2, 3, 4]
4
+ end
5
+
6
+ it 'returns its shape as an array' do
7
+ expect(@blob.shape).to eq([1, 2, 3, 4])
8
+ end
9
+
10
+ it 'can only have at most 4 dimensions' do
11
+ expect { Caffe::Blob.new [1, 2, 3, 4, 5] }.to raise_error(ArgumentError)
12
+ end
13
+
14
+ it 'can have shape dimension other than 4' do
15
+ @blob = Caffe::Blob.new [1, 10]
16
+ expect(@blob[0][5]).to eq(0.0)
17
+ end
18
+
19
+ it 'can reshape' do
20
+ @blob.shape = [1, 2, 2, 2]
21
+ expect(@blob.shape).to eq([1, 2, 2, 2])
22
+ end
23
+
24
+ def random_indices
25
+ @blob.shape.map do |x|
26
+ Random.rand x
27
+ end
28
+ end
29
+
30
+ shared_examples :memory do
31
+ it 'can access to next dimension via []' do
32
+ indices = random_indices
33
+ 3.times do |i|
34
+ @data = @data[indices[i]]
35
+ expect(@data).to be_a(Caffe::Blob::Cursor)
36
+ end
37
+ end
38
+
39
+ it 'can be read via []' do
40
+ i, j, k, l = random_indices
41
+ expect(@data[i][j][k][l]).to eq(0.0)
42
+ end
43
+
44
+ it 'can be write via []=' do
45
+ i, j, k, l = random_indices
46
+ @data[i][j][k][l] = 1.0
47
+ expect(@data[i][j][k][l]).to eq(1.0)
48
+ end
49
+
50
+ it 'returns the size of its memory' do
51
+ i, j = random_indices
52
+ expect(@data.size).to eq(1 * 2 * 3 * 4)
53
+ expect(@data[i][j].size).to eq(3 * 4)
54
+ end
55
+
56
+ it 'raise error when the index is out of range' do
57
+ expect { @data[10] }.to raise_error(RangeError)
58
+ expect { @data[0][0][0][10] }.to raise_error(RangeError)
59
+ end
60
+
61
+ it 'can be enumerated' do
62
+ i, j = random_indices
63
+
64
+ @data[i].each do |x|
65
+ expect(x).to be(0.0)
66
+ end
67
+
68
+ arr = Array.new @data[i][j].size, 0.0
69
+ expect(@data[i][j].to_a).to eq(arr)
70
+ end
71
+
72
+ it 'can be copied from Array' do
73
+ arr = Array.new @data.size do
74
+ Random.rand 2
75
+ end
76
+ @data.copy_from! arr
77
+ expect(@data.to_a).to eq(arr)
78
+ end
79
+ end
80
+
81
+ context '#data' do
82
+ before :example do
83
+ @data = @blob.data
84
+ end
85
+
86
+ include_examples :memory
87
+ end
88
+
89
+ context '#diff' do
90
+ before :example do
91
+ @data = @blob.diff
92
+ end
93
+
94
+ include_examples :memory
95
+ end
96
+
97
+ context 'itself' do
98
+ before :example do
99
+ @data = @blob
100
+ end
101
+
102
+ include_examples :memory
103
+ end
104
+ end
@@ -0,0 +1,26 @@
1
+ RSpec.describe Caffe do
2
+ it 'contains constant shortcuts of enum' do
3
+ expect(Caffe::TRAIN).to eq(Caffe::Phase::TRAIN)
4
+ expect(Caffe::TEST).to eq(Caffe::Phase::TEST)
5
+ expect(Caffe::CPU).to eq(Caffe::SolverParameter::SolverMode::CPU)
6
+ expect(Caffe::GPU).to eq(Caffe::SolverParameter::SolverMode::GPU)
7
+ end
8
+
9
+ it 'can change mode' do
10
+ expect(Caffe.mode).to eq(Caffe::CPU)
11
+ Caffe.mode = Caffe::GPU
12
+ expect(Caffe.mode).to eq(Caffe::GPU)
13
+ end
14
+
15
+ it 'can get / set parallel settings' do
16
+ expect(Caffe.solver_count).to eq(1)
17
+ expect(Caffe.solver_rank).to eq(0)
18
+ expect(Caffe.multiprocess).to eq(false)
19
+ Caffe.solver_count = 2
20
+ Caffe.solver_rank = 1
21
+ Caffe.multiprocess = true
22
+ expect(Caffe.solver_count).to eq(2)
23
+ expect(Caffe.solver_rank).to eq(1)
24
+ expect(Caffe.multiprocess).to eq(true)
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH << File.expand_path('../../../lib', __FILE__)
2
+
3
+ require 'lmdb'
4
+ require 'caffe'
5
+
6
+ def gen
7
+ data = Array.new 32 do
8
+ Random.rand 2
9
+ end
10
+
11
+ num = data.inject(0) do |i, x|
12
+ 2 * i + x
13
+ end
14
+
15
+ label = num % 1024 > 1024 / 2 ? 1 : 0
16
+
17
+ datum = Caffe::Datum.new channels: 32, height: 1, width: 1, label: label
18
+ datum.data = data.pack 'C*'
19
+
20
+ datum.serialize_to_string
21
+ end
22
+
23
+ env = LMDB.new File.expand_path('../test_data', __FILE__)
24
+ env.mapsize = 1 * 1024 * 1024 * 1024
25
+ db = env.database
26
+
27
+ 25600.times do |i|
28
+ db[format('%08d', i)] = gen
29
+ end
Binary file
@@ -0,0 +1,71 @@
1
+ name: "test"
2
+
3
+ layer {
4
+ name: "data"
5
+ type: "Input"
6
+ top: "data"
7
+ input_param {
8
+ shape: {
9
+ dim: 1
10
+ dim: 32
11
+ }
12
+ }
13
+ }
14
+
15
+ layer {
16
+ name: "ip1"
17
+ type: "InnerProduct"
18
+ bottom: "data"
19
+ top: "ip1"
20
+ param {
21
+ lr_mult: 1
22
+ }
23
+ param {
24
+ lr_mult: 2
25
+ }
26
+ inner_product_param {
27
+ num_output: 100
28
+ weight_filler {
29
+ type: "gaussian"
30
+ }
31
+ bias_filler {
32
+ type: "constant"
33
+ }
34
+ }
35
+ }
36
+
37
+ layer {
38
+ name: "sigmoid"
39
+ type: "Sigmoid"
40
+ bottom: "ip1"
41
+ top: "ip1"
42
+ }
43
+
44
+ layer {
45
+ name: "ip2"
46
+ type: "InnerProduct"
47
+ bottom: "ip1"
48
+ top: "ip2"
49
+ param {
50
+ lr_mult: 1
51
+ }
52
+ param {
53
+ lr_mult: 2
54
+ }
55
+ inner_product_param {
56
+ num_output: 2
57
+ weight_filler {
58
+ type: "gaussian"
59
+ }
60
+ bias_filler {
61
+ type: "constant"
62
+ }
63
+ }
64
+ }
65
+
66
+ layer {
67
+ name: "prob"
68
+ type: "Softmax"
69
+ bottom: "ip2"
70
+ top: "prob"
71
+ }
@@ -0,0 +1,14 @@
1
+ net: "test_train.prototxt"
2
+ test_iter: 100
3
+ test_interval: 800
4
+ base_lr: 0.1
5
+ momentum: 0.9
6
+ weight_decay: 0.0005
7
+ lr_policy: "inv"
8
+ gamma: 0.0001
9
+ power: 0.75
10
+ display: 800
11
+ max_iter: 25600
12
+ snapshot: 25600
13
+ snapshot_prefix: "test"
14
+ solver_mode: CPU
@@ -0,0 +1,83 @@
1
+ name: "test"
2
+
3
+ layer {
4
+ name: "data"
5
+ type: "Data"
6
+ top: "data"
7
+ top: "label"
8
+ data_param {
9
+ source: "test_data"
10
+ batch_size: 256
11
+ backend: LMDB
12
+ }
13
+ }
14
+
15
+ layer {
16
+ name: "ip1"
17
+ type: "InnerProduct"
18
+ bottom: "data"
19
+ top: "ip1"
20
+ param {
21
+ lr_mult: 1
22
+ }
23
+ param {
24
+ lr_mult: 2
25
+ }
26
+ inner_product_param {
27
+ num_output: 100
28
+ weight_filler {
29
+ type: "gaussian"
30
+ }
31
+ bias_filler {
32
+ type: "constant"
33
+ }
34
+ }
35
+ }
36
+
37
+ layer {
38
+ name: "sigmoid"
39
+ type: "Sigmoid"
40
+ bottom: "ip1"
41
+ top: "ip1"
42
+ }
43
+
44
+ layer {
45
+ name: "ip2"
46
+ type: "InnerProduct"
47
+ bottom: "ip1"
48
+ top: "ip2"
49
+ param {
50
+ lr_mult: 1
51
+ }
52
+ param {
53
+ lr_mult: 2
54
+ }
55
+ inner_product_param {
56
+ num_output: 2
57
+ weight_filler {
58
+ type: "gaussian"
59
+ }
60
+ bias_filler {
61
+ type: "constant"
62
+ }
63
+ }
64
+ }
65
+
66
+ layer {
67
+ name: "accuracy"
68
+ type: "Accuracy"
69
+ bottom: "ip2"
70
+ bottom: "label"
71
+ top: "accuracy"
72
+ include {
73
+ phase: TEST
74
+ }
75
+ }
76
+
77
+ layer {
78
+ name: "loss"
79
+ type: "SoftmaxWithLoss"
80
+ bottom: "ip2"
81
+ bottom: "label"
82
+ top: "loss"
83
+ }
@@ -0,0 +1,71 @@
1
+ RSpec.describe Caffe::Net do
2
+ before :example do
3
+ Caffe.mode = Caffe::CPU
4
+ path = File.expand_path '../net/test.prototxt', __FILE__
5
+ @net = Caffe::Net.new path, Caffe::TEST
6
+ end
7
+
8
+ it 'can get the input' do
9
+ expect(@net.inputs).to be_an(Array)
10
+ expect(@net.inputs.size).to eq(1)
11
+ input = @net.inputs[0]
12
+ expect(input).to be_a(Caffe::Blob)
13
+ expect(input.shape).to eq([1, 32])
14
+ end
15
+
16
+ it 'can get blob by name' do
17
+ blob = @net.blob('ip1')
18
+ expect(blob).to be_a(Caffe::Blob)
19
+ expect(blob.shape).to eq([1, 100])
20
+
21
+ blob = @net.blob('prob')
22
+ expect(blob.shape).to eq([1, 2])
23
+ end
24
+
25
+ it 'can get output' do
26
+ expect(@net.outputs).to be_an(Array)
27
+ expect(@net.outputs.size).to eq(1)
28
+ output = @net.outputs[0]
29
+ expect(output).to be_a(Caffe::Blob)
30
+ expect(output.shape).to eq([1, 2])
31
+ end
32
+
33
+ it 'can reshape according to the input size' do
34
+ input = @net.inputs[0]
35
+ input.shape = [64, 32]
36
+ @net.reshape!
37
+ expect(@net.outputs[0].shape).to eq([64, 2])
38
+ end
39
+
40
+ context 'trained net' do
41
+ before :example do
42
+ path = File.expand_path '../net/test.caffemodel', __FILE__
43
+ @net.load_trained! path
44
+ end
45
+
46
+ it 'can read from trained model' do
47
+ input = @net.inputs[0]
48
+ expect(input.shape).to eq([1, 32])
49
+ end
50
+
51
+ it 'can forward' do
52
+ data = Array.new 32 do
53
+ Random.rand 2
54
+ end
55
+ input = @net.inputs[0]
56
+ input.copy_from! data
57
+
58
+ expect(@net.forward!).to eq(0.0)
59
+ output = @net.outputs[0]
60
+ expect(output[0][0] + output[0][1]).to be_within(1e-6).of(1.0)
61
+
62
+ label = output[0][1] > output[0][0] ? 1 : 0
63
+ num = data.inject(0) do |i, x|
64
+ 2 * i + x
65
+ end
66
+ expected = num % 1024 > 1024 / 2 ? 1 : 0
67
+
68
+ expect(label).to eq(expected)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,16 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |expectations|
3
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
4
+ end
5
+
6
+ config.mock_with :rspec do |mocks|
7
+ mocks.verify_partial_doubles = true
8
+ end
9
+
10
+ config.shared_context_metadata_behavior = :apply_to_host_groups
11
+ end
12
+
13
+ lib = File.expand_path '../../lib', __FILE__
14
+ $LOAD_PATH << lib
15
+
16
+ require 'caffe'
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: caffe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tiny Tiny
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rice
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: protobuf
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: A ruby wrapper of the deep leaning framework
84
+ email:
85
+ - gyf1214@gmail.com
86
+ executables: []
87
+ extensions:
88
+ - ext/caffe/extconf.rb
89
+ extra_rdoc_files:
90
+ - README.md
91
+ - LICENSE
92
+ files:
93
+ - LICENSE
94
+ - README.md
95
+ - ext/caffe/blob.cc
96
+ - ext/caffe/blob.hpp
97
+ - ext/caffe/caffe.cc
98
+ - ext/caffe/common.cc
99
+ - ext/caffe/common.hpp
100
+ - ext/caffe/extconf.rb
101
+ - ext/caffe/mkmf_cxx.rb
102
+ - ext/caffe/net.cc
103
+ - ext/caffe/net.hpp
104
+ - ext/caffe/util.hpp
105
+ - lib/caffe.rb
106
+ - lib/caffe/blob.rb
107
+ - lib/caffe/caffe.pb.rb
108
+ - lib/caffe/common.rb
109
+ - lib/caffe/version.rb
110
+ - spec/blob_spec.rb
111
+ - spec/common_spec.rb
112
+ - spec/net/gen_data.rb
113
+ - spec/net/test.caffemodel
114
+ - spec/net/test.prototxt
115
+ - spec/net/test_solver.prototxt
116
+ - spec/net/test_train.prototxt
117
+ - spec/net_spec.rb
118
+ - spec/spec_helper.rb
119
+ homepage: https://github.com/gyf1214/ruby-caffe
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.5.2
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: A ruby wrapper of the deep leaning framework
143
+ test_files:
144
+ - spec/blob_spec.rb
145
+ - spec/common_spec.rb
146
+ - spec/net/gen_data.rb
147
+ - spec/net/test.caffemodel
148
+ - spec/net/test.prototxt
149
+ - spec/net/test_solver.prototxt
150
+ - spec/net/test_train.prototxt
151
+ - spec/net_spec.rb
152
+ - spec/spec_helper.rb