tensor_stream-opencl 0.2.5 → 0.2.6
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/lib/tensor_stream/opencl/opencl_evaluator.rb +58 -11
- data/lib/tensor_stream/opencl/version.rb +1 -1
- data/mnist_model.yml +379860 -0
- data/samples/build_mnist_model.rb +130 -0
- data/samples/classify.rb +12 -0
- data/samples/mnist_data_3.0.rb +0 -1
- metadata +3 -2
- data/samples/image_sort.rb +0 -9
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# builds a frozen mnist image recognition model from scratch
|
4
|
+
# based on mnist_data_3.0.rb
|
5
|
+
|
6
|
+
require "bundler/setup"
|
7
|
+
require 'tensor_stream'
|
8
|
+
require 'mnist-learn'
|
9
|
+
require 'csv'
|
10
|
+
|
11
|
+
# Enable OpenCL hardware accelerated computation, not using OpenCL can be very slow
|
12
|
+
require 'tensor_stream/opencl'
|
13
|
+
require 'tensor_stream/utils/freezer'
|
14
|
+
|
15
|
+
epochs = (ARGV[0] || 2000).to_i
|
16
|
+
|
17
|
+
tf = TensorStream
|
18
|
+
puts "Tensorstream version #{tf.__version__} with OpenCL lib #{TensorStream::Opencl::VERSION}"
|
19
|
+
|
20
|
+
# Import MNIST data
|
21
|
+
puts "downloading minst data"
|
22
|
+
# Download images and labels into mnist.test (10K images+labels) and mnist.train (60K images+labels)
|
23
|
+
mnist = Mnist.read_data_sets('/tmp/data', one_hot: true)
|
24
|
+
|
25
|
+
puts "downloading finished"
|
26
|
+
|
27
|
+
x = tf.placeholder(:float32, shape: [nil, 28, 28, 1])
|
28
|
+
y_ = tf.placeholder(:float32, shape: [nil, 10])
|
29
|
+
step = tf.placeholder(:int32)
|
30
|
+
pkeep = tf.placeholder(tf.float32)
|
31
|
+
|
32
|
+
# Network parameters
|
33
|
+
K = 4 # first convolutional layer output depth
|
34
|
+
L = 8 # second convolutional layer output depth
|
35
|
+
M = 12 # third convolutional layer
|
36
|
+
N = 200 # fully connected layer
|
37
|
+
|
38
|
+
|
39
|
+
w1 = tf.variable(tf.truncated_normal([6, 6, 1, K], stddev: 0.1))
|
40
|
+
b1 = tf.variable(tf.ones([K])/10)
|
41
|
+
|
42
|
+
w2 = tf.variable(tf.truncated_normal([5, 5, K, L], stddev: 0.1))
|
43
|
+
b2 = tf.variable(tf.ones([L])/10)
|
44
|
+
|
45
|
+
w3 = tf.variable(tf.truncated_normal([4, 4, L, M], stddev: 0.1))
|
46
|
+
b3 = tf.variable(tf.ones([M])/10)
|
47
|
+
|
48
|
+
w4 = tf.variable(tf.truncated_normal([7 * 7 * M, N], stddev: 0.1))
|
49
|
+
b4 = tf.variable(tf.ones([N])/10)
|
50
|
+
|
51
|
+
w5 = tf.variable(tf.truncated_normal([N, 10], stddev: 0.1))
|
52
|
+
b5 = tf.variable(tf.ones([10])/10)
|
53
|
+
|
54
|
+
# The model
|
55
|
+
stride = 1 # output is 28x28
|
56
|
+
y1 = tf.nn.relu(tf.nn.conv2d(tf.reshape(x, [-1, 28, 28, 1]), w1, [1, stride, stride, 1], 'SAME') + b1)
|
57
|
+
stride = 2 # output is 14x14
|
58
|
+
y2 = tf.nn.relu(tf.nn.conv2d(y1, w2, [1, stride, stride, 1], 'SAME') + b2)
|
59
|
+
stride = 2 # output is 7x7
|
60
|
+
y3 = tf.nn.relu(tf.nn.conv2d(y2, w3, [1, stride, stride, 1], 'SAME') + b3)
|
61
|
+
|
62
|
+
# reshape the output from the third convolution for the fully connected layer
|
63
|
+
yy = tf.reshape(y3, [-1, 7 * 7 * M])
|
64
|
+
y4 = tf.nn.relu(tf.matmul(yy, w4) + b4)
|
65
|
+
|
66
|
+
ylogits = tf.matmul(y4, w5) + b5
|
67
|
+
|
68
|
+
# model
|
69
|
+
y = tf.nn.softmax(ylogits, name: 'out')
|
70
|
+
|
71
|
+
# cross-entropy loss function (= -sum(Y_i * log(Yi)) ), normalised for batches of 100 images
|
72
|
+
# TensorFlow provides the softmax_cross_entropy_with_logits function to avoid numerical stability
|
73
|
+
# problems with log(0) which is NaN
|
74
|
+
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits: ylogits, labels: y_)
|
75
|
+
cross_entropy = tf.reduce_mean(cross_entropy)*100
|
76
|
+
|
77
|
+
is_correct = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
|
78
|
+
accuracy = tf.reduce_mean(tf.cast(is_correct, :float32))
|
79
|
+
|
80
|
+
# training step, learning rate = 0.003
|
81
|
+
lr = 0.0001.t + tf.train.exponential_decay(0.003, step, 2000, 1/Math::E)
|
82
|
+
train_step = TensorStream::Train::AdamOptimizer.new(lr).minimize(cross_entropy)
|
83
|
+
|
84
|
+
sess = tf.session
|
85
|
+
# Add ops to save and restore all the variables.
|
86
|
+
|
87
|
+
init = tf.global_variables_initializer
|
88
|
+
|
89
|
+
sess.run(init)
|
90
|
+
|
91
|
+
#Setup save and restore
|
92
|
+
model_save_path = "test_models/mnist_data_3.0"
|
93
|
+
saver = tf::Train::Saver.new
|
94
|
+
saver.restore(sess, model_save_path)
|
95
|
+
|
96
|
+
mnist_train = mnist.train
|
97
|
+
test_data = { x => mnist.test.images, y_ => mnist.test.labels, pkeep => 1.0 }
|
98
|
+
|
99
|
+
puts "training #{epochs} epochs"
|
100
|
+
(0..epochs).each do |i|
|
101
|
+
# load batch of images and correct answers
|
102
|
+
batch_x, batch_y = mnist_train.next_batch(100)
|
103
|
+
train_data = { x => batch_x, y_ => batch_y, step => i, pkeep => 0.75 }
|
104
|
+
|
105
|
+
# train
|
106
|
+
sess.run(train_step, feed_dict: train_data)
|
107
|
+
|
108
|
+
if (i % 10 == 0)
|
109
|
+
|
110
|
+
a_train, c_train, l = sess.run([accuracy, cross_entropy, lr], feed_dict: { x => batch_x, y_ => batch_y, step => i, pkeep => 1.0})
|
111
|
+
puts "#{i}: accuracy:#{a_train} loss:#{c_train} (lr:#{l})"
|
112
|
+
end
|
113
|
+
|
114
|
+
if (i % 100 == 0)
|
115
|
+
# success on test data?
|
116
|
+
a_test, c_test = sess.run([accuracy, cross_entropy], feed_dict: test_data, pkeep => 1.0)
|
117
|
+
puts("#{i}: ******** test accuracy: #{a_test} test loss: #{c_test}")
|
118
|
+
|
119
|
+
# save current state of the model
|
120
|
+
save_path = saver.save(sess, model_save_path)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Freezing removes variables and turns them into constants
|
125
|
+
puts "saving frozen model"
|
126
|
+
freezer = TensorStream::Freezer.new
|
127
|
+
freezer.convert(sess, model_save_path, 'mnist_model.yml')
|
128
|
+
puts "done. model written at mnist_model.yml"
|
129
|
+
|
130
|
+
|
data/samples/classify.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
# This script reads a grayscale PNG and predicts what digit it is
|
4
|
+
# Note: You can use the dump_mnist.rb script to get those images
|
5
|
+
#
|
6
|
+
# This also requires an existing model:
|
7
|
+
#
|
8
|
+
# You can run
|
9
|
+
#
|
10
|
+
# ruby samples/build_mnist_model.rb
|
11
|
+
#
|
12
|
+
# to build a model that you can use
|
13
|
+
|
3
14
|
require "bundler/setup"
|
4
15
|
require "tensor_stream"
|
5
16
|
require 'mnist-learn'
|
@@ -14,6 +25,7 @@ input = target_graph['Placeholder']
|
|
14
25
|
output = TensorStream.argmax(target_graph['out'], 1)
|
15
26
|
sess = TensorStream.session
|
16
27
|
|
28
|
+
# invert since model was trained on a white on black png image
|
17
29
|
reshaped_image = 255.0.t - decoded_image.reshape([1, 28, 28, 1]).cast(:float32)
|
18
30
|
result = sess.run(output, feed_dict: { input => reshaped_image})
|
19
31
|
|
data/samples/mnist_data_3.0.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tensor_stream-opencl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Dayo
|
@@ -246,9 +246,10 @@ files:
|
|
246
246
|
- lib/tensor_stream/opencl/opencl_evaluator.rb
|
247
247
|
- lib/tensor_stream/opencl/opencl_template_helper.rb
|
248
248
|
- lib/tensor_stream/opencl/version.rb
|
249
|
+
- mnist_model.yml
|
250
|
+
- samples/build_mnist_model.rb
|
249
251
|
- samples/classify.rb
|
250
252
|
- samples/dump_mnist.rb
|
251
|
-
- samples/image_sort.rb
|
252
253
|
- samples/iris.data
|
253
254
|
- samples/iris.rb
|
254
255
|
- samples/logistic_regression.rb
|