tensor_stream-opencl 0.1.3 → 0.2.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 +4 -4
- data/Gemfile.lock +11 -4
- data/benchmark/benchmark.rb +91 -0
- data/benchmark_intel.txt +36 -0
- data/lib/tensor_stream/opencl/array_ops.rb +395 -0
- data/lib/tensor_stream/opencl/images_ops.rb +62 -0
- data/lib/tensor_stream/opencl/kernels/abs.cl +6 -8
- data/lib/tensor_stream/opencl/kernels/acos.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/apply_adadelta.cl +2 -4
- data/lib/tensor_stream/opencl/kernels/apply_adagrad.cl +12 -0
- data/lib/tensor_stream/opencl/kernels/apply_adam.cl +2 -5
- data/lib/tensor_stream/opencl/kernels/apply_centered_rms_prop.cl +19 -0
- data/lib/tensor_stream/opencl/kernels/apply_gradient.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/apply_momentum.cl +2 -4
- data/lib/tensor_stream/opencl/kernels/apply_rms_prop.cl +16 -0
- data/lib/tensor_stream/opencl/kernels/asin.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/ceil.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/concat.cl +21 -0
- data/lib/tensor_stream/opencl/kernels/cos.cl +3 -5
- data/lib/tensor_stream/opencl/kernels/exp.cl +3 -5
- data/lib/tensor_stream/opencl/kernels/floor.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/log.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/log1p.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/negate.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/reciprocal.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/sigmoid.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/sign.cl +7 -8
- data/lib/tensor_stream/opencl/kernels/sin.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/split.cl +17 -0
- data/lib/tensor_stream/opencl/kernels/split_n.cl +18 -0
- data/lib/tensor_stream/opencl/kernels/sqrt.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/square.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/tan.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/tanh.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/tanh_grad.cl +3 -4
- data/lib/tensor_stream/opencl/kernels/unpack.cl +23 -0
- data/lib/tensor_stream/opencl/nn_ops.rb +111 -26
- data/lib/tensor_stream/opencl/opencl_buffer.rb +9 -0
- data/lib/tensor_stream/opencl/opencl_evaluator.rb +129 -172
- data/lib/tensor_stream/opencl/version.rb +1 -1
- data/samples/iris.data +150 -0
- data/samples/iris.rb +110 -0
- data/samples/mnist_data.rb +65 -0
- data/samples/multigpu.rb +73 -0
- data/samples/nearest_neighbor.rb +56 -0
- data/samples/rnn.rb +108 -0
- data/tensor_stream-opencl.gemspec +4 -1
- metadata +62 -3
data/samples/iris.data
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
5.1,3.5,1.4,0.2,Iris-setosa
|
2
|
+
4.9,3.0,1.4,0.2,Iris-setosa
|
3
|
+
4.7,3.2,1.3,0.2,Iris-setosa
|
4
|
+
4.6,3.1,1.5,0.2,Iris-setosa
|
5
|
+
5.0,3.6,1.4,0.2,Iris-setosa
|
6
|
+
5.4,3.9,1.7,0.4,Iris-setosa
|
7
|
+
4.6,3.4,1.4,0.3,Iris-setosa
|
8
|
+
5.0,3.4,1.5,0.2,Iris-setosa
|
9
|
+
4.4,2.9,1.4,0.2,Iris-setosa
|
10
|
+
4.9,3.1,1.5,0.1,Iris-setosa
|
11
|
+
5.4,3.7,1.5,0.2,Iris-setosa
|
12
|
+
4.8,3.4,1.6,0.2,Iris-setosa
|
13
|
+
4.8,3.0,1.4,0.1,Iris-setosa
|
14
|
+
4.3,3.0,1.1,0.1,Iris-setosa
|
15
|
+
5.8,4.0,1.2,0.2,Iris-setosa
|
16
|
+
5.7,4.4,1.5,0.4,Iris-setosa
|
17
|
+
5.4,3.9,1.3,0.4,Iris-setosa
|
18
|
+
5.1,3.5,1.4,0.3,Iris-setosa
|
19
|
+
5.7,3.8,1.7,0.3,Iris-setosa
|
20
|
+
5.1,3.8,1.5,0.3,Iris-setosa
|
21
|
+
5.4,3.4,1.7,0.2,Iris-setosa
|
22
|
+
5.1,3.7,1.5,0.4,Iris-setosa
|
23
|
+
4.6,3.6,1.0,0.2,Iris-setosa
|
24
|
+
5.1,3.3,1.7,0.5,Iris-setosa
|
25
|
+
4.8,3.4,1.9,0.2,Iris-setosa
|
26
|
+
5.0,3.0,1.6,0.2,Iris-setosa
|
27
|
+
5.0,3.4,1.6,0.4,Iris-setosa
|
28
|
+
5.2,3.5,1.5,0.2,Iris-setosa
|
29
|
+
5.2,3.4,1.4,0.2,Iris-setosa
|
30
|
+
4.7,3.2,1.6,0.2,Iris-setosa
|
31
|
+
4.8,3.1,1.6,0.2,Iris-setosa
|
32
|
+
5.4,3.4,1.5,0.4,Iris-setosa
|
33
|
+
5.2,4.1,1.5,0.1,Iris-setosa
|
34
|
+
5.5,4.2,1.4,0.2,Iris-setosa
|
35
|
+
4.9,3.1,1.5,0.1,Iris-setosa
|
36
|
+
5.0,3.2,1.2,0.2,Iris-setosa
|
37
|
+
5.5,3.5,1.3,0.2,Iris-setosa
|
38
|
+
4.9,3.1,1.5,0.1,Iris-setosa
|
39
|
+
4.4,3.0,1.3,0.2,Iris-setosa
|
40
|
+
5.1,3.4,1.5,0.2,Iris-setosa
|
41
|
+
5.0,3.5,1.3,0.3,Iris-setosa
|
42
|
+
4.5,2.3,1.3,0.3,Iris-setosa
|
43
|
+
4.4,3.2,1.3,0.2,Iris-setosa
|
44
|
+
5.0,3.5,1.6,0.6,Iris-setosa
|
45
|
+
5.1,3.8,1.9,0.4,Iris-setosa
|
46
|
+
4.8,3.0,1.4,0.3,Iris-setosa
|
47
|
+
5.1,3.8,1.6,0.2,Iris-setosa
|
48
|
+
4.6,3.2,1.4,0.2,Iris-setosa
|
49
|
+
5.3,3.7,1.5,0.2,Iris-setosa
|
50
|
+
5.0,3.3,1.4,0.2,Iris-setosa
|
51
|
+
7.0,3.2,4.7,1.4,Iris-versicolor
|
52
|
+
6.4,3.2,4.5,1.5,Iris-versicolor
|
53
|
+
6.9,3.1,4.9,1.5,Iris-versicolor
|
54
|
+
5.5,2.3,4.0,1.3,Iris-versicolor
|
55
|
+
6.5,2.8,4.6,1.5,Iris-versicolor
|
56
|
+
5.7,2.8,4.5,1.3,Iris-versicolor
|
57
|
+
6.3,3.3,4.7,1.6,Iris-versicolor
|
58
|
+
4.9,2.4,3.3,1.0,Iris-versicolor
|
59
|
+
6.6,2.9,4.6,1.3,Iris-versicolor
|
60
|
+
5.2,2.7,3.9,1.4,Iris-versicolor
|
61
|
+
5.0,2.0,3.5,1.0,Iris-versicolor
|
62
|
+
5.9,3.0,4.2,1.5,Iris-versicolor
|
63
|
+
6.0,2.2,4.0,1.0,Iris-versicolor
|
64
|
+
6.1,2.9,4.7,1.4,Iris-versicolor
|
65
|
+
5.6,2.9,3.6,1.3,Iris-versicolor
|
66
|
+
6.7,3.1,4.4,1.4,Iris-versicolor
|
67
|
+
5.6,3.0,4.5,1.5,Iris-versicolor
|
68
|
+
5.8,2.7,4.1,1.0,Iris-versicolor
|
69
|
+
6.2,2.2,4.5,1.5,Iris-versicolor
|
70
|
+
5.6,2.5,3.9,1.1,Iris-versicolor
|
71
|
+
5.9,3.2,4.8,1.8,Iris-versicolor
|
72
|
+
6.1,2.8,4.0,1.3,Iris-versicolor
|
73
|
+
6.3,2.5,4.9,1.5,Iris-versicolor
|
74
|
+
6.1,2.8,4.7,1.2,Iris-versicolor
|
75
|
+
6.4,2.9,4.3,1.3,Iris-versicolor
|
76
|
+
6.6,3.0,4.4,1.4,Iris-versicolor
|
77
|
+
6.8,2.8,4.8,1.4,Iris-versicolor
|
78
|
+
6.7,3.0,5.0,1.7,Iris-versicolor
|
79
|
+
6.0,2.9,4.5,1.5,Iris-versicolor
|
80
|
+
5.7,2.6,3.5,1.0,Iris-versicolor
|
81
|
+
5.5,2.4,3.8,1.1,Iris-versicolor
|
82
|
+
5.5,2.4,3.7,1.0,Iris-versicolor
|
83
|
+
5.8,2.7,3.9,1.2,Iris-versicolor
|
84
|
+
6.0,2.7,5.1,1.6,Iris-versicolor
|
85
|
+
5.4,3.0,4.5,1.5,Iris-versicolor
|
86
|
+
6.0,3.4,4.5,1.6,Iris-versicolor
|
87
|
+
6.7,3.1,4.7,1.5,Iris-versicolor
|
88
|
+
6.3,2.3,4.4,1.3,Iris-versicolor
|
89
|
+
5.6,3.0,4.1,1.3,Iris-versicolor
|
90
|
+
5.5,2.5,4.0,1.3,Iris-versicolor
|
91
|
+
5.5,2.6,4.4,1.2,Iris-versicolor
|
92
|
+
6.1,3.0,4.6,1.4,Iris-versicolor
|
93
|
+
5.8,2.6,4.0,1.2,Iris-versicolor
|
94
|
+
5.0,2.3,3.3,1.0,Iris-versicolor
|
95
|
+
5.6,2.7,4.2,1.3,Iris-versicolor
|
96
|
+
5.7,3.0,4.2,1.2,Iris-versicolor
|
97
|
+
5.7,2.9,4.2,1.3,Iris-versicolor
|
98
|
+
6.2,2.9,4.3,1.3,Iris-versicolor
|
99
|
+
5.1,2.5,3.0,1.1,Iris-versicolor
|
100
|
+
5.7,2.8,4.1,1.3,Iris-versicolor
|
101
|
+
6.3,3.3,6.0,2.5,Iris-virginica
|
102
|
+
5.8,2.7,5.1,1.9,Iris-virginica
|
103
|
+
7.1,3.0,5.9,2.1,Iris-virginica
|
104
|
+
6.3,2.9,5.6,1.8,Iris-virginica
|
105
|
+
6.5,3.0,5.8,2.2,Iris-virginica
|
106
|
+
7.6,3.0,6.6,2.1,Iris-virginica
|
107
|
+
4.9,2.5,4.5,1.7,Iris-virginica
|
108
|
+
7.3,2.9,6.3,1.8,Iris-virginica
|
109
|
+
6.7,2.5,5.8,1.8,Iris-virginica
|
110
|
+
7.2,3.6,6.1,2.5,Iris-virginica
|
111
|
+
6.5,3.2,5.1,2.0,Iris-virginica
|
112
|
+
6.4,2.7,5.3,1.9,Iris-virginica
|
113
|
+
6.8,3.0,5.5,2.1,Iris-virginica
|
114
|
+
5.7,2.5,5.0,2.0,Iris-virginica
|
115
|
+
5.8,2.8,5.1,2.4,Iris-virginica
|
116
|
+
6.4,3.2,5.3,2.3,Iris-virginica
|
117
|
+
6.5,3.0,5.5,1.8,Iris-virginica
|
118
|
+
7.7,3.8,6.7,2.2,Iris-virginica
|
119
|
+
7.7,2.6,6.9,2.3,Iris-virginica
|
120
|
+
6.0,2.2,5.0,1.5,Iris-virginica
|
121
|
+
6.9,3.2,5.7,2.3,Iris-virginica
|
122
|
+
5.6,2.8,4.9,2.0,Iris-virginica
|
123
|
+
7.7,2.8,6.7,2.0,Iris-virginica
|
124
|
+
6.3,2.7,4.9,1.8,Iris-virginica
|
125
|
+
6.7,3.3,5.7,2.1,Iris-virginica
|
126
|
+
7.2,3.2,6.0,1.8,Iris-virginica
|
127
|
+
6.2,2.8,4.8,1.8,Iris-virginica
|
128
|
+
6.1,3.0,4.9,1.8,Iris-virginica
|
129
|
+
6.4,2.8,5.6,2.1,Iris-virginica
|
130
|
+
7.2,3.0,5.8,1.6,Iris-virginica
|
131
|
+
7.4,2.8,6.1,1.9,Iris-virginica
|
132
|
+
7.9,3.8,6.4,2.0,Iris-virginica
|
133
|
+
6.4,2.8,5.6,2.2,Iris-virginica
|
134
|
+
6.3,2.8,5.1,1.5,Iris-virginica
|
135
|
+
6.1,2.6,5.6,1.4,Iris-virginica
|
136
|
+
7.7,3.0,6.1,2.3,Iris-virginica
|
137
|
+
6.3,3.4,5.6,2.4,Iris-virginica
|
138
|
+
6.4,3.1,5.5,1.8,Iris-virginica
|
139
|
+
6.0,3.0,4.8,1.8,Iris-virginica
|
140
|
+
6.9,3.1,5.4,2.1,Iris-virginica
|
141
|
+
6.7,3.1,5.6,2.4,Iris-virginica
|
142
|
+
6.9,3.1,5.1,2.3,Iris-virginica
|
143
|
+
5.8,2.7,5.1,1.9,Iris-virginica
|
144
|
+
6.8,3.2,5.9,2.3,Iris-virginica
|
145
|
+
6.7,3.3,5.7,2.5,Iris-virginica
|
146
|
+
6.7,3.0,5.2,2.3,Iris-virginica
|
147
|
+
6.3,2.5,5.0,1.9,Iris-virginica
|
148
|
+
6.5,3.0,5.2,2.0,Iris-virginica
|
149
|
+
6.2,3.4,5.4,2.3,Iris-virginica
|
150
|
+
5.9,3.0,5.1,1.8,Iris-virginica
|
data/samples/iris.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require 'tensor_stream'
|
3
|
+
require 'tensor_stream/opencl'
|
4
|
+
|
5
|
+
# This neural network will predict the species of an iris based on sepal and petal size
|
6
|
+
# Dataset: http://en.wikipedia.org/wiki/Iris_flower_data_set
|
7
|
+
tf = TensorStream
|
8
|
+
rows = File.readlines(File.join("samples","iris.data")).map {|l| l.chomp.split(',') }
|
9
|
+
|
10
|
+
rows.shuffle!
|
11
|
+
|
12
|
+
label_encodings = {
|
13
|
+
'Iris-setosa' => [1, 0, 0],
|
14
|
+
'Iris-versicolor' => [0, 1, 0],
|
15
|
+
'Iris-virginica' => [0, 0, 1]
|
16
|
+
}
|
17
|
+
|
18
|
+
x_data = rows.map {|row| row[0,4].map(&:to_f) }
|
19
|
+
y_data = rows.map {|row| label_encodings[row[4]] }
|
20
|
+
|
21
|
+
# Normalize data values before feeding into network
|
22
|
+
normalize = -> (val, high, low) { (val - low) / (high - low) } # maps input to float between 0 and 1
|
23
|
+
|
24
|
+
columns = (0..3).map do |i|
|
25
|
+
x_data.map {|row| row[i] }
|
26
|
+
end
|
27
|
+
|
28
|
+
x_data.map! do |row|
|
29
|
+
row.map.with_index do |val, j|
|
30
|
+
max, min = columns[j].max, columns[j].min
|
31
|
+
normalize.call(val, max, min)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
x_train = x_data.slice(0, 100)
|
36
|
+
y_train = y_data.slice(0, 100)
|
37
|
+
|
38
|
+
x_test = x_data.slice(100, 50)
|
39
|
+
y_test = y_data.slice(100, 50)
|
40
|
+
|
41
|
+
test_cases = []
|
42
|
+
x_train.each_with_index do |x, index|
|
43
|
+
test_cases << [x, y_train[index]]
|
44
|
+
end
|
45
|
+
|
46
|
+
validation_cases = []
|
47
|
+
x_test.each_with_index do |x, index|
|
48
|
+
validation_cases << [x, y_test[index]]
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
def init_weights(shape)
|
54
|
+
# Weight initialization
|
55
|
+
weights = TensorStream.random_normal(shape, stddev: 0.1)
|
56
|
+
TensorStream.variable(weights)
|
57
|
+
end
|
58
|
+
|
59
|
+
def forwardprop(x, w_1, w_2)
|
60
|
+
# Forward-propagation.
|
61
|
+
# IMPORTANT: yhat is not softmax since TensorFlow's softmax_cross_entropy_with_logits() does that internally.
|
62
|
+
h = TensorStream.nn.sigmoid(TensorStream.matmul(x, w_1)) # The \sigma function
|
63
|
+
TensorStream.matmul(h, w_2) # The \varphi function
|
64
|
+
end
|
65
|
+
|
66
|
+
x_size = x_train[0].size
|
67
|
+
y_size = y_train[0].size
|
68
|
+
h_size = 256
|
69
|
+
X = tf.placeholder(:float32, shape: [nil, x_size])
|
70
|
+
y = tf.placeholder(:float32, shape: [nil, y_size])
|
71
|
+
|
72
|
+
# Weight initializations
|
73
|
+
w_1 = init_weights([x_size, h_size])
|
74
|
+
w_2 = init_weights([h_size, y_size])
|
75
|
+
|
76
|
+
# Forward propagation
|
77
|
+
yhat = forwardprop(X, w_1, w_2)
|
78
|
+
predict = tf.argmax(yhat, 1)
|
79
|
+
|
80
|
+
# Backward propagation
|
81
|
+
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels: y, logits: yhat))
|
82
|
+
|
83
|
+
updates = TensorStream::Train::GradientDescentOptimizer.new(0.01).minimize(cost)
|
84
|
+
# updates = TensorStream::Train::MomentumOptimizer.new(0.01, 0.5, use_nesterov: true).minimize(cost)
|
85
|
+
# updates = TensorStream::Train::RMSPropOptimizer.new(0.01).minimize(cost)
|
86
|
+
|
87
|
+
# Run SGD
|
88
|
+
sess = tf.session
|
89
|
+
init = tf.global_variables_initializer
|
90
|
+
sess.run(init)
|
91
|
+
loss = sess.run(cost, feed_dict: { X => x_test, y => y_test })
|
92
|
+
puts "loss test data set #{loss}"
|
93
|
+
loss = sess.run(cost, feed_dict: { X => x_train, y => y_train })
|
94
|
+
puts "Testing the untrained network..."
|
95
|
+
puts loss
|
96
|
+
start_time = Time.now
|
97
|
+
(0..100).each do |epoch|
|
98
|
+
x_train.size.times do |i|
|
99
|
+
sess.run(updates, feed_dict: {X => [x_train[i]], y => [y_train[i]]})
|
100
|
+
end
|
101
|
+
|
102
|
+
loss = sess.run(cost, feed_dict: { X => x_train, y => y_train })
|
103
|
+
puts "epoch: #{epoch}, loss #{loss}"
|
104
|
+
end
|
105
|
+
|
106
|
+
loss = sess.run(cost, feed_dict: { X => x_train, y => y_train })
|
107
|
+
puts "loss after training #{loss}"
|
108
|
+
loss = sess.run(cost, feed_dict: { X => x_test, y => y_test })
|
109
|
+
puts "loss test data set #{loss}"
|
110
|
+
puts("time elapsed ", Time.now.to_i - start_time.to_i)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# A ruby port of the example code discussed by Martin Gorner in
|
2
|
+
# "TensorFlow and Deep Learning without a PhD, Part 1 (Google Cloud Next '17)""
|
3
|
+
#
|
4
|
+
# https://www.youtube.com/watch?v=u4alGiomYP4
|
5
|
+
#
|
6
|
+
# Requirements:
|
7
|
+
# mnist-learn gem
|
8
|
+
# opencl_ruby_ffi gem
|
9
|
+
require "bundler/setup"
|
10
|
+
require 'tensor_stream'
|
11
|
+
require 'mnist-learn'
|
12
|
+
|
13
|
+
# Enable OpenCL hardware accelerated computation, not using OpenCL can be very slow
|
14
|
+
# require 'tensor_stream/opencl'
|
15
|
+
|
16
|
+
tf = TensorStream
|
17
|
+
|
18
|
+
# Import MNIST data
|
19
|
+
puts "downloading minst data"
|
20
|
+
mnist = Mnist.read_data_sets('/tmp/data', one_hot: true)
|
21
|
+
puts "downloading finished"
|
22
|
+
|
23
|
+
x = tf.placeholder(:float32, shape: [nil, 784])
|
24
|
+
w = tf.variable(tf.zeros([784, 10]))
|
25
|
+
b = tf.variable(tf.zeros([10]))
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
# model
|
30
|
+
y = tf.nn.softmax(tf.matmul(tf.reshape(x, [-1, 784]), w) + b)
|
31
|
+
|
32
|
+
y_ = tf.placeholder(:float32, shape: [nil, 10])
|
33
|
+
|
34
|
+
# loss function
|
35
|
+
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
|
36
|
+
|
37
|
+
is_correct = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
|
38
|
+
accuracy = tf.reduce_mean(tf.cast(is_correct, :float32))
|
39
|
+
|
40
|
+
optimizer = TensorStream::Train::AdamOptimizer.new
|
41
|
+
train_step = optimizer.minimize(cross_entropy)
|
42
|
+
|
43
|
+
sess = tf.session
|
44
|
+
init = tf.global_variables_initializer
|
45
|
+
sess.run(init)
|
46
|
+
|
47
|
+
(0...1000).each do |i|
|
48
|
+
# load batch of images and correct answers
|
49
|
+
batch_x, batch_y = mnist.train.next_batch(100)
|
50
|
+
train_data = { x => batch_x, y_ => batch_y }
|
51
|
+
|
52
|
+
# train
|
53
|
+
sess.run(train_step, feed_dict: train_data)
|
54
|
+
if (i % 10 == 0)
|
55
|
+
# success? add code to print it
|
56
|
+
a, c = sess.run([accuracy, cross_entropy], feed_dict: train_data)
|
57
|
+
puts "#{i} train accuracy #{a}, error #{c}"
|
58
|
+
|
59
|
+
# success on test data?
|
60
|
+
test_data = { x => mnist.test.images, y_ => mnist.test.labels }
|
61
|
+
a, c = sess.run([accuracy, cross_entropy], feed_dict: test_data)
|
62
|
+
puts " test accuracy #{a}, error #{c}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
data/samples/multigpu.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require 'tensor_stream'
|
3
|
+
require 'tensor_stream/opencl'
|
4
|
+
require 'pry-byebug'
|
5
|
+
|
6
|
+
ts = TensorStream
|
7
|
+
|
8
|
+
n = 10
|
9
|
+
DIMEN = 1024
|
10
|
+
|
11
|
+
A = ts.random_uniform([DIMEN, DIMEN]).eval
|
12
|
+
B = ts.random_uniform([DIMEN, DIMEN]).eval
|
13
|
+
|
14
|
+
|
15
|
+
# Create a graph to store results
|
16
|
+
c1 = []
|
17
|
+
c2 = []
|
18
|
+
a = nil
|
19
|
+
b = nil
|
20
|
+
|
21
|
+
def matpow(m, n)
|
22
|
+
return m if n < 1
|
23
|
+
TensorStream.matmul(m, matpow(m, n-1))
|
24
|
+
end
|
25
|
+
|
26
|
+
ts.device('/device:GPU:0') do
|
27
|
+
a = ts.placeholder(:float32, shape: [DIMEN, DIMEN])
|
28
|
+
b = ts.placeholder(:float32, shape: [DIMEN, DIMEN])
|
29
|
+
# Compute A^n and B^n and store results in c1
|
30
|
+
c1 << matpow(a, n)
|
31
|
+
c1 << matpow(b, n)
|
32
|
+
end
|
33
|
+
|
34
|
+
sum = ts.device('/device:GPU:0') do
|
35
|
+
ts.add_n(c1)
|
36
|
+
end
|
37
|
+
|
38
|
+
t1_1 = Time.now.to_i
|
39
|
+
t2_1 = nil
|
40
|
+
|
41
|
+
ts.session(log_device_placement: true) do |sess|
|
42
|
+
sess.run(sum, feed_dict: { a => A, b => B})
|
43
|
+
t2_1 = Time.now.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
# Multi GPU computing
|
47
|
+
# GPU:0 computes A^n
|
48
|
+
ts.device('/device:GPU:1') do
|
49
|
+
a = ts.placeholder(:float32, shape: [DIMEN, DIMEN])
|
50
|
+
c2 << matpow(a, n)
|
51
|
+
end
|
52
|
+
|
53
|
+
# GPU:1 computes B^n
|
54
|
+
ts.device('/device:GPU:1') do
|
55
|
+
b = ts.placeholder(:float32, shape: [DIMEN, DIMEN])
|
56
|
+
c2 << matpow(b, n)
|
57
|
+
end
|
58
|
+
|
59
|
+
ts.device('/device:GPU:1') do
|
60
|
+
sum = ts.add_n(c2) #Addition of all elements in c2, i.e. A^n + B^n
|
61
|
+
end
|
62
|
+
|
63
|
+
t1_2 = Time.now.to_i
|
64
|
+
t2_2 = nil
|
65
|
+
ts.session(log_device_placement:true) do |sess|
|
66
|
+
# Run the op.
|
67
|
+
sess.run(sum, feed_dict: {a => A, b => B})
|
68
|
+
t2_2 = Time.now.to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
print("Single GPU computation time: " + (t2_1-t1_1).to_s)
|
73
|
+
print("Multi GPU computation time: " + (t2_2-t1_2).to_s)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
'''
|
2
|
+
A nearest neighbor learning algorithm example using TensorFlow library.
|
3
|
+
This example is using the MNIST database of handwritten digits
|
4
|
+
(http://yann.lecun.com/exdb/mnist/)
|
5
|
+
|
6
|
+
Author: Aymeric Damien
|
7
|
+
Project: https://github.com/aymericdamien/TensorFlow-Examples/
|
8
|
+
|
9
|
+
Make sure to install the mnist-learn gem !!
|
10
|
+
'''
|
11
|
+
require "bundler/setup"
|
12
|
+
require 'tensor_stream'
|
13
|
+
require 'mnist-learn'
|
14
|
+
require 'tensor_stream/opencl'
|
15
|
+
|
16
|
+
tf = TensorStream
|
17
|
+
|
18
|
+
# Import MNIST data
|
19
|
+
mnist = Mnist.read_data_sets('/tmp/data', one_hot: true)
|
20
|
+
|
21
|
+
# In this example, we limit mnist data
|
22
|
+
Xtr, Ytr = mnist.train.next_batch(5000) # 5000 for training (nn candidates)
|
23
|
+
Xte, Yte = mnist.test.next_batch(200) # 200 for testing
|
24
|
+
|
25
|
+
# tf Graph Input
|
26
|
+
xtr = tf.placeholder(:float, shape: [nil, 784])
|
27
|
+
xte = tf.placeholder(:float, shape: [784])
|
28
|
+
|
29
|
+
# Nearest Neighbor calculation using L1 Distance
|
30
|
+
# Calculate L1 Distance
|
31
|
+
distance = tf.reduce_sum(tf.abs(tf.add(xtr, tf.negative(xte))), 1)
|
32
|
+
# Prediction: Get min distance index (Nearest neighbor)
|
33
|
+
pred = tf.argmin(distance, 0)
|
34
|
+
|
35
|
+
accuracy = 0.0
|
36
|
+
|
37
|
+
# Initialize the variables (i.e. assign their default value)
|
38
|
+
init = tf.global_variables_initializer()
|
39
|
+
|
40
|
+
# Start training
|
41
|
+
tf.session do |sess|
|
42
|
+
# Run the initializer
|
43
|
+
sess.run(init)
|
44
|
+
Xte.size.times do |i|
|
45
|
+
# Get nearest neighbor
|
46
|
+
nn_index = sess.run(pred, feed_dict: {xtr => Xtr, xte => Xte[i]})
|
47
|
+
print("Test ", i, "Prediction: ",Ytr[nn_index].max, \
|
48
|
+
"True Class: ", Yte[i].max, "\n")
|
49
|
+
if Ytr[nn_index].max == Yte[i].max
|
50
|
+
accuracy += 1.0/ Xte.size
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
print("Done!")
|
55
|
+
print("Accuracy:", accuracy)
|
56
|
+
end
|