tensor_stream 1.0.8 → 1.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 712b5d17b1b84d5289970fa578a8385c80e2a499033a42df8aadefdad654276c
4
- data.tar.gz: ed74482c5913ea6debc5d0902d01c180b52f5028ae1ed7be726bafede9671982
3
+ metadata.gz: 8f7d54f45a96ee2ed86af5916339747701171476e2b1cd6197f4f78d3f7f2eb3
4
+ data.tar.gz: f8a1c615ebf5f67de35e0e6ac84ac531fc5306b62787ac0d2d952f474eb97bad
5
5
  SHA512:
6
- metadata.gz: 95b1715323930f35aeec861efa7b5dd96f9b61c8ea2d45343306798506cbbbc64e0092fed77c615a27e53b219610b7b14384726b5fb976b800c7ce57bcfc1539
7
- data.tar.gz: 45e92e91167a39ca02cc5a1c04022c0dc1942ad863b650710b93862400174dbddd0bbe1889659ef55651bf1ca0b779420fd48811f862c8707be068cd02abed9f
6
+ metadata.gz: 4607a3c117c98f21594bcbf12b98a1e927dab88c2847d4516c4f3dd3502b821e8d4b2b8e17e085c3ed122eec1e339baced66e3822fed2c5c6e3c8e10d0121e08
7
+ data.tar.gz: dd2f7b6c971a25b90a4404319231de6386aef0b536a1df9eca84a3a881e6e9e2faa903fd7fb72b9a05ba8588ec5ffdd153be0072e6c850960fff9ecaecf7b6bc
@@ -228,11 +228,25 @@ module TensorStream
228
228
 
229
229
  def self.register_evaluator(klass, name, index = 0)
230
230
  @evaluators ||= {}
231
+ @storage_managers ||= {}
231
232
  @evaluators[name] = {name: name, class: klass, index: index}
233
+ @storage_managers[klass] = klass.get_storage_manager
232
234
  end
233
235
 
234
236
  def self.default_evaluators
235
237
  evaluators.values.sort { |v| v[:index] }.reverse.map { |v| v[:class] }
236
238
  end
239
+
240
+ def self.clear_storages(graph)
241
+ @storage_managers.values.each { |manager| manager.clear_variables(graph) }
242
+ end
243
+
244
+ def self.read_variable(graph, name)
245
+ @storage_managers.values.each do |manager|
246
+ return manager.read_value(graph, name) if manager.exists?(graph, name)
247
+ end
248
+
249
+ nil
250
+ end
237
251
  end
238
252
  end
@@ -1,5 +1,6 @@
1
1
  require "tensor_stream/evaluator/ruby_evaluator"
2
2
  require "tensor_stream/evaluator/buffer"
3
+ require "tensor_stream/evaluator/evaluator_utils"
3
4
 
4
5
  module TensorStream
5
6
  module Evaluator
@@ -0,0 +1,20 @@
1
+ module TensorStream
2
+ class EvaluatorUtils
3
+ extend TensorStream::StringHelper
4
+
5
+ def self.get_evaluator_classes(evaluators)
6
+ @evaluator_classes ||= if evaluators.is_a?(Array)
7
+ if evaluators.empty?
8
+ TensorStream::Evaluator.default_evaluators
9
+ else
10
+ evaluators.collect { |name| Object.const_get("TensorStream::Evaluator::#{camelize(name.to_s)}") }
11
+ end
12
+ elsif evaluators.nil?
13
+ TensorStream::Evaluator.default_evaluators
14
+ else
15
+ [Object.const_get("TensorStream::Evaluator::#{camelize(evaluators.to_s)}")]
16
+ end
17
+ @evaluator_classes
18
+ end
19
+ end
20
+ end
@@ -58,11 +58,19 @@ module TensorStream
58
58
  channels = 3 if channels.zero?
59
59
 
60
60
  image = Jpeg::Image.open_buffer(content)
61
+ source_channels = image.color_info == :gray ? 1 : 3
62
+
61
63
  image_data = image.raw_data.map do |pixel|
62
- pixel.map!(&:to_f) if fp_type?(tensor.data_type)
64
+ if source_channels == channels
65
+ pixel
66
+ elsif source_channels = 1 && channels == 3
67
+ [pixel, pixel, pixel]
68
+ elsif source_channels = 3 && channels == 1
69
+ raise TensorStream::ValueError, "color to grayscale not supported for jpg"
70
+ end
71
+ end.flatten
63
72
 
64
- pixel
65
- end
73
+ image_data.map!(&:to_f) if fp_type?(tensor.data_type)
66
74
 
67
75
  TensorShape.reshape(image_data, [image.height, image.width, channels])
68
76
  end
@@ -7,22 +7,20 @@ module TensorStream
7
7
  target_var, learning_rate, delta = inputs
8
8
  assign = tensor.inputs[0] || tensor
9
9
 
10
- assign.container = process_vector_math_op(tensor, target_var, delta, context) { |t, u| t - u * learning_rate }
11
- assign.container
10
+ var_assign_value(assign, process_vector_math_op(tensor, target_var, delta, context) { |t, u| t - u * learning_rate })
12
11
  end
13
12
 
14
13
  register_op :apply_momentum do |_context, tensor, inputs|
15
14
  target_var, momentum_var, learning_rate, grad, momentum = inputs
16
15
  assign = tensor.inputs[0] || tensor
17
16
  assign_acc = tensor.inputs[1]
18
- assign_acc.container = multi_array_op(->(t, u) { t * momentum + u }, momentum_var, grad)
19
- assign.container = if tensor.options[:use_nesterov]
20
- multi_array_op(->(v, g, acc) { v - (g * learning_rate + acc * momentum * learning_rate) }, target_var, grad, momentum_var)
21
- else
22
- multi_array_op(->(v, acc) { v - acc * learning_rate }, target_var, momentum_var)
23
- end
24
-
25
- assign.container
17
+ var_assign_value(assign_acc, multi_array_op(->(t, u) { t * momentum + u }, momentum_var, grad))
18
+ var = if tensor.options[:use_nesterov]
19
+ multi_array_op(->(v, g, acc) { v - (g * learning_rate + acc * momentum * learning_rate) }, target_var, grad, momentum_var)
20
+ else
21
+ multi_array_op(->(v, acc) { v - acc * learning_rate }, target_var, momentum_var)
22
+ end
23
+ var_assign_value(assign, var)
26
24
  end
27
25
 
28
26
  register_op :apply_adadelta do |_context, tensor, inputs|
@@ -30,19 +28,18 @@ module TensorStream
30
28
  assign = tensor.inputs[0] || tensor
31
29
  assign_acc = tensor.inputs[1]
32
30
  assign_acc_update = tensor.inputs[2]
33
- assign_acc.container = multi_array_op(->(acc_t, grad_t) { acc_t * rho + (grad_t * grad_t) * (1.0 - rho) }, accum, grad)
34
- update = multi_array_op(->(acc_update_t, acc_t, grad_t) { Math.sqrt(acc_update_t + epsilon) * (1.0 / Math.sqrt(acc_t + epsilon)) * grad_t }, accum_update, assign_acc.container, grad)
35
- assign.container = multi_array_op(->(v, u) { v - (u * lr) }, target_var, update)
36
- assign_acc_update.container = multi_array_op(->(acc_update_t, u) { acc_update_t * rho + (u * u) * (1.0 - rho) }, accum_update, update)
31
+ acc_val = var_assign_value(assign_acc, multi_array_op(->(acc_t, grad_t) { acc_t * rho + (grad_t * grad_t) * (1.0 - rho) }, accum, grad))
32
+ update = multi_array_op(->(acc_update_t, acc_t, grad_t) { Math.sqrt(acc_update_t + epsilon) * (1.0 / Math.sqrt(acc_t + epsilon)) * grad_t }, accum_update, acc_val, grad)
33
+ result = var_assign_value(assign, multi_array_op(->(v, u) { v - (u * lr) }, target_var, update))
34
+ var_assign_value(assign_acc_update,multi_array_op(->(acc_update_t, u) { acc_update_t * rho + (u * u) * (1.0 - rho) }, accum_update, update))
37
35
 
38
- assign.container
36
+ result
39
37
  end
40
38
 
41
39
  register_op :apply_adagrad do |_context, tensor, inputs|
42
40
  target_var, accum, lr, grad = inputs
43
41
  assign = tensor.inputs[0] || tensor
44
- assign.container = multi_array_op(->(v, a, g) { v - (g * lr * (1.0 / Math.sqrt(a))) }, target_var, accum, grad)
45
- assign.container
42
+ var_assign_value(assign, multi_array_op(->(v, a, g) { v - (g * lr * (1.0 / Math.sqrt(a))) }, target_var, accum, grad))
46
43
  end
47
44
 
48
45
  register_op :apply_adam do |_context, tensor, inputs|
@@ -52,10 +49,9 @@ module TensorStream
52
49
  assign_m = tensor.inputs[1]
53
50
  assign_v = tensor.inputs[2]
54
51
 
55
- assign_m.container = multi_array_op(->(u_d, g) { u_d + (g - u_d) * (1.0 - beta1_t) }, m, grad)
56
- assign_v.container = multi_array_op(->(u_d, v_d) { u_d + (v_d**2 - u_d) * (1.0 - beta2_t)}, v, grad)
57
- assign.container = multi_array_op(->(t, m_d, v_d) { t - ((m_d * alpha) / (Math.sqrt(v_d) + epsilon_t)) }, target_var, assign_m.container, assign_v.container)
58
- assign.container
52
+ m_val = var_assign_value(assign_m, multi_array_op(->(u_d, g) { u_d + (g - u_d) * (1.0 - beta1_t) }, m, grad))
53
+ v_val = var_assign_value(assign_v, multi_array_op(->(u_d, v_d) { u_d + (v_d**2 - u_d) * (1.0 - beta2_t)}, v, grad))
54
+ var_assign_value(assign, multi_array_op(->(t, m_d, v_d) { t - ((m_d * alpha) / (Math.sqrt(v_d) + epsilon_t)) }, target_var, m_val, v_val))
59
55
  end
60
56
 
61
57
  register_op :apply_rms_prop do |_context, tensor, inputs|
@@ -63,9 +59,9 @@ module TensorStream
63
59
  assign = tensor.inputs[0]
64
60
  assign_ms = tensor.inputs[1]
65
61
  assign_mom = tensor.inputs[2]
66
- assign_ms.container = multi_array_op(->(g, m) { m + (g * g - m) * (1.0 - rho)}, grad, ms)
67
- assign_mom.container = multi_array_op(->(mom_t, g, m) { mom_t * momentum + (g * lr) / Math.sqrt(m + epsilon)}, mom, grad, assign_ms.container)
68
- assign.container = multi_array_op(->(v, m) { v - m }, var, assign_mom.container)
62
+ ms_val = var_assign_value(assign_ms, multi_array_op(->(g, m) { m + (g * g - m) * (1.0 - rho)}, grad, ms))
63
+ mom_val = var_assign_value(assign_mom, multi_array_op(->(mom_t, g, m) { mom_t * momentum + (g * lr) / Math.sqrt(m + epsilon)}, mom, grad, ms_val))
64
+ var_assign_value(assign, multi_array_op(->(v, m) { v - m }, var, mom_val))
69
65
  end
70
66
 
71
67
  register_op :apply_centered_rms_prop do |_context, tensor, inputs|
@@ -75,11 +71,11 @@ module TensorStream
75
71
  assign_ms = tensor.inputs[2]
76
72
  assign_mom = tensor.inputs[3]
77
73
 
78
- assign_ms.container = multi_array_op(->(g, m) { m + (g * g - m) * (1.0 - rho) }, grad, ms)
79
- assign_mg.container = multi_array_op(->(g, mg_t) { (g - mg_t) * (1.0 - rho) }, grad, mg)
80
- denom = multi_array_op(->(s, mg_t) { (s - mg_t * mg_t) + epsilon }, assign_ms.container, mg)
81
- assign_mom.container = multi_array_op(->(mom_t, g, d) { mom_t * momentum + (g * lr) / Math.sqrt(d)}, mom, grad, denom)
82
- assign.container = multi_array_op(->(v, m) { v - m }, var, assign_mom.container)
74
+ val_ms = var_assign_value(assign_ms, multi_array_op(->(g, m) { m + (g * g - m) * (1.0 - rho) }, grad, ms))
75
+ var_assign_value(assign_mg, multi_array_op(->(g, mg_t) { (g - mg_t) * (1.0 - rho) }, grad, mg))
76
+ denom = multi_array_op(->(s, mg_t) { (s - mg_t * mg_t) + epsilon }, val_ms, mg)
77
+ val_mom = var_assign_value(assign_mom, multi_array_op(->(mom_t, g, d) { mom_t * momentum + (g * lr) / Math.sqrt(d)}, mom, grad, denom))
78
+ var_assign_value(assign, multi_array_op(->(v, m) { v - m }, var, val_mom))
83
79
  end
84
80
 
85
81
  register_op %i[softmax_cross_entropy_with_logits_v2 softmax_cross_entropy_with_logits] do |_context, tensor, inputs|
@@ -0,0 +1,40 @@
1
+ module TensorStream
2
+ class RubyStorageManager
3
+ def self.current_storage_manager
4
+ @storage_manager ||= RubyStorageManager.new
5
+ end
6
+
7
+ def initialize
8
+ @variables = {}
9
+ end
10
+
11
+ def exists?(graph, name)
12
+ return false if !@variables.key?(graph.object_id)
13
+
14
+ @variables[graph.object_id].key?(name.to_sym)
15
+ end
16
+
17
+ def create_variable(graph, name, value)
18
+ raise "no name specified" if name.nil?
19
+
20
+ @variables[graph.object_id][name.to_sym] = value
21
+ end
22
+
23
+ def assign_value(graph, name, value)
24
+ raise "no name specified" if name.nil?
25
+
26
+ @variables[graph.object_id] ||= {}
27
+ @variables[graph.object_id][name.to_sym] = value
28
+ end
29
+
30
+ def read_value(graph, name)
31
+ raise "no name specified" if name.nil?
32
+
33
+ @variables[graph.object_id][name.to_sym]
34
+ end
35
+
36
+ def clear_variables(graph)
37
+ @variables[graph.object_id] = {}
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,74 @@
1
+ module TensorStream
2
+ ## Collection of machine learning related ops
3
+ module VariableOps
4
+ def self.included(klass)
5
+ klass.class_eval do
6
+ register_op :variable_v2 do |_context, tensor, _inputs|
7
+ value = var_read_value(tensor)
8
+ raise "variable #{tensor.options[:var_name]} not initalized" if value.nil?
9
+
10
+ value
11
+ end
12
+
13
+ register_op :assign do |context, tensor, inputs|
14
+ var_assign_value(tensor, inputs[0])
15
+ end
16
+
17
+ register_op :assign_add, no_eval: true do |context, tensor, inputs|
18
+ current_val = var_read_value(tensor)
19
+
20
+ raise "variable #{tensor.options[:var_name]} not initialized" if current_val.nil?
21
+ eval_a, eval_b = broadcast(current_val, inputs[0])
22
+ result = multi_array_op(->(var, val) { var + val }, eval_a, eval_b)
23
+ var_assign_value(tensor, result)
24
+ end
25
+
26
+ register_op :assign_sub do |context, tensor, inputs|
27
+ current_val = var_read_value(tensor)
28
+ raise "variable #{tensor.options[:var_name]} not initialized" if current_val.nil?
29
+ eval_a, eval_b = broadcast(current_val, inputs[0])
30
+ result = multi_array_op(->(var, val) { var - val }, eval_a, eval_b)
31
+ var_assign_value(tensor, result)
32
+ end
33
+
34
+ register_op :save_ts do |_context, tensor, inputs|
35
+ outputfile = inputs[0]
36
+ inputs = tensor.inputs.dup
37
+
38
+ inputs.shift
39
+ variables = {}
40
+ inputs.each do |savable|
41
+ val = var_read_value(savable)
42
+
43
+ packed_data = Zlib::Deflate.deflate(TensorStream::Packer.pack(val, savable.data_type))
44
+ variables[savable.options[:var_name]] = {
45
+ "shape" => shape_eval(val),
46
+ "data" => Base64.strict_encode64(packed_data),
47
+ }
48
+ end
49
+
50
+ File.write(outputfile, {"variables" => variables}.to_yaml)
51
+ nil
52
+ end
53
+
54
+ register_op :restore_ts do |_context, tensor, inputs|
55
+ inputs = inputs.dup
56
+ filename = inputs.shift
57
+ tensor_names = inputs
58
+
59
+ input_dump = YAML.safe_load(File.read(filename), [Symbol])
60
+ vars = tensor.graph.get_collection(GraphKeys::GLOBAL_VARIABLES)
61
+ vars.select! { |v| input_dump["variables"].key?(v.name) && tensor_names.include?(v.name) }
62
+ vars.each do |variable|
63
+ data = TensorStream::Packer.unpack(Zlib::Inflate.inflate(Base64.decode64(input_dump["variables"][variable.name]["data"])), variable.data_type)
64
+ shape = input_dump["variables"][variable.name]["shape"]
65
+ variable.buffer = nil
66
+ var_assign_value(variable, TensorShape.reshape(data, shape))
67
+ end
68
+
69
+ nil
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -2,12 +2,14 @@ require "tensor_stream/evaluator/operation_helpers/random_gaussian"
2
2
  require "tensor_stream/evaluator/operation_helpers/array_ops_helper"
3
3
  require "tensor_stream/evaluator/operation_helpers/math_helper"
4
4
  require "tensor_stream/evaluator/base_evaluator"
5
+ require "tensor_stream/evaluator/ruby/storage_manager"
5
6
  require "tensor_stream/evaluator/ruby/math_ops"
6
7
  require "tensor_stream/evaluator/ruby/nn_ops"
7
8
  require "tensor_stream/evaluator/ruby/array_ops"
8
9
  require "tensor_stream/evaluator/ruby/random_ops"
9
10
  require "tensor_stream/evaluator/ruby/images_ops"
10
11
  require "tensor_stream/evaluator/ruby/check_ops"
12
+ require "tensor_stream/evaluator/ruby/variable_ops"
11
13
 
12
14
  module TensorStream
13
15
  module Evaluator
@@ -41,6 +43,11 @@ module TensorStream
41
43
  include TensorStream::RandomOps
42
44
  include TensorStream::ImagesOps
43
45
  include TensorStream::CheckOps
46
+ include TensorStream::VariableOps
47
+
48
+ def self.get_storage_manager
49
+ RubyStorageManager.current_storage_manager
50
+ end
44
51
 
45
52
  def run(tensor, execution_context)
46
53
  return tensor.map { |t| run(t, execution_context) } if tensor.is_a?(Array) && !tensor.empty? && tensor[0].is_a?(Tensor)
@@ -82,6 +89,18 @@ module TensorStream
82
89
 
83
90
  protected
84
91
 
92
+ def var_read_value(tensor)
93
+ @storage_manager ||= TensorStream::RubyStorageManager.current_storage_manager
94
+ @storage_manager.read_value(tensor.graph, tensor.options[:var_name])
95
+ end
96
+
97
+ def var_assign_value(tensor, value)
98
+ @storage_manager ||= TensorStream::RubyStorageManager.current_storage_manager
99
+ @storage_manager.assign_value(tensor.graph, tensor.options[:var_name] || tensor.name, value)
100
+
101
+ value
102
+ end
103
+
85
104
  def prepare_input(tensor, context, options = {})
86
105
  return nil unless tensor
87
106
 
@@ -154,37 +173,10 @@ module TensorStream
154
173
  end
155
174
  end
156
175
 
157
- register_op :variable_v2, no_eval: true do |_context, tensor, _inputs|
158
- value = tensor.options[:container].read_value
159
- raise "variable #{tensor.options[:container].name} not initalized" if value.nil?
160
-
161
- value
162
- end
163
-
164
176
  register_op :stop_gradient, no_eval: true do |_context, _tensor, inputs|
165
177
  inputs[0]
166
178
  end
167
179
 
168
- register_op :assign, noop: true do |context, tensor, _inputs|
169
- assign = tensor.inputs[0] || tensor
170
- assign.container = global_eval(tensor, tensor.inputs[1], context)
171
- assign.container
172
- end
173
-
174
- register_op :assign_add, noop: true do |context, tensor, _inputs|
175
- assign = tensor.inputs[0] || tensor
176
-
177
- assign.container = process_vector_math_op(tensor, tensor.inputs[0], tensor.inputs[1], context) { |t, u| t + u }
178
- assign.container
179
- end
180
-
181
- register_op :assign_sub, noop: true do |context, tensor, _inputs|
182
- assign = tensor.inputs[0] || tensor
183
-
184
- assign.container = process_vector_math_op(tensor, tensor.inputs[0], tensor.inputs[1], context) { |t, u| t - u }
185
- assign.container
186
- end
187
-
188
180
  register_op :less do |context, tensor, inputs|
189
181
  a, b = inputs
190
182
  call_vector_op(tensor, :less, a, b, context) { |t, u| t < u }
@@ -236,44 +228,6 @@ module TensorStream
236
228
  softmax(inputs[0])
237
229
  end
238
230
 
239
- register_op :save_ts do |_context, tensor, inputs|
240
- outputfile = inputs[0]
241
- inputs = tensor.inputs.dup
242
-
243
- inputs.shift
244
- variables = {}
245
- inputs.each do |savable|
246
- val = savable.container
247
- packed_data = Zlib::Deflate.deflate(TensorStream::Packer.pack(val, savable.data_type))
248
- variables[savable.name] = {
249
- "shape" => shape_eval(val),
250
- "data" => Base64.strict_encode64(packed_data),
251
- }
252
- end
253
-
254
- File.write(outputfile, {"variables" => variables}.to_yaml)
255
- nil
256
- end
257
-
258
- register_op :restore_ts do |_context, tensor, inputs|
259
- inputs = inputs.dup
260
- filename = inputs.shift
261
- tensor_names = inputs
262
-
263
- input_dump = YAML.safe_load(File.read(filename), [Symbol])
264
- vars = tensor.graph.get_collection(GraphKeys::GLOBAL_VARIABLES)
265
-
266
- vars.select! { |v| input_dump["variables"].key?(v.name) && tensor_names.include?(v.name) }
267
- vars.each do |variable|
268
- data = TensorStream::Packer.unpack(Zlib::Inflate.inflate(Base64.decode64(input_dump["variables"][variable.name]["data"])), variable.data_type)
269
- shape = input_dump["variables"][variable.name]["shape"]
270
- variable.buffer = nil
271
- variable.value = TensorShape.reshape(data, shape)
272
- end
273
-
274
- nil
275
- end
276
-
277
231
  register_op :check_numerics do |context, tensor, inputs|
278
232
  message = tensor.options[:message]
279
233
  call_op(inputs[0], context) do |t, _b|
@@ -379,7 +333,7 @@ module TensorStream
379
333
  elem = args[0]
380
334
  if elem.is_a?(Array)
381
335
  elem.each_with_index.collect do |_item, index|
382
- indexed_args = args.collect { |a| a[index] }
336
+ indexed_args = args.collect { |a| a = a.is_a?(Array) ? a : [a]; a[index] }
383
337
  multi_array_op(func, *indexed_args)
384
338
  end
385
339
  else
@@ -30,6 +30,7 @@ module TensorStream
30
30
  :"#{GraphKeys::TRAINABLE_VARIABLES}" => [],
31
31
  }
32
32
  @constants = {}
33
+ TensorStream::Evaluator.clear_storages(self)
33
34
  end
34
35
 
35
36
  def as_default
@@ -129,7 +130,7 @@ module TensorStream
129
130
 
130
131
  def add_op(operation, *args)
131
132
  options = if args.last.is_a?(Hash)
132
- args.pop
133
+ args.pop || {}
133
134
  else
134
135
  {}
135
136
  end
@@ -180,8 +181,7 @@ module TensorStream
180
181
 
181
182
  def add_variable!(node, options = {})
182
183
  node = add_variable(node, options)
183
- op = Graph.get_default_graph.add_op!(:variable_v2, container: node, internal_name: node.name, shape: options[:shape], data_type: options[:data_type])
184
- node.name = op.name
184
+ op = Graph.get_default_graph.add_op!(:variable_v2, var_name: node.name, shape: options[:shape], data_type: options[:data_type])
185
185
  op
186
186
  end
187
187
 
@@ -31,15 +31,13 @@ module TensorStream
31
31
  options = {}
32
32
 
33
33
  new_var = nil
34
- if op_def.dig(:attrs, :container)
34
+ if op_def[:op].to_sym == :variable_v2
35
35
  new_var = Variable.new(op_def.dig(:attrs, :data_type))
36
- var_shape = op_def.dig(:attrs, :container, :shape)
37
- var_options = op_def.dig(:attrs, :container, :options)
38
- var_options[:name] = op_def[:name]
39
36
 
40
- new_var.prepare(var_shape.size, var_shape, TensorStream.get_variable_scope, var_options)
41
- options[:container] = new_var
37
+ var_options = {}
38
+ var_options[:name] = op_def.dig(:attrs, :var_name)
42
39
 
40
+ new_var.prepare(nil, nil, TensorStream.get_variable_scope, var_options)
43
41
  @graph.add_variable(new_var, var_options)
44
42
  end
45
43
 
@@ -10,13 +10,7 @@ module TensorStream
10
10
  def self.infer_shape(tensor)
11
11
  case tensor.operation
12
12
  when :assign
13
- possible_shape = if tensor.inputs[0]&.shape&.shape
14
- tensor.inputs[0].shape.shape
15
- else
16
- tensor.inputs[1].shape.shape
17
- end
18
-
19
- possible_shape
13
+ tensor.inputs[0]&.shape&.shape
20
14
  when :const
21
15
  shape_eval(tensor.options[:value])
22
16
  when :variable_v2
@@ -7,7 +7,7 @@ module TensorStream
7
7
  attr_accessor :name, :operation, :inputs, :rank, :device, :consumers, :breakpoint
8
8
  attr_reader :outputs, :options, :is_const, :data_type, :shape
9
9
 
10
- def initialize(graph, inputs:, options:)
10
+ def initialize(graph, inputs: [], options: {})
11
11
  @consumers = Set.new
12
12
  @outputs = []
13
13
  @op = self
@@ -42,14 +42,6 @@ module TensorStream
42
42
  @options[:container] ? @options[:container].buffer : nil
43
43
  end
44
44
 
45
- def container
46
- @options[:container].read_value
47
- end
48
-
49
- def container=(value)
50
- @options[:container].value = value
51
- end
52
-
53
45
  def set_input(index, value)
54
46
  @inputs[index] = value
55
47
  @shape = TensorShape.new(TensorStream::InferShape.infer_shape(self))
@@ -58,6 +50,10 @@ module TensorStream
58
50
  @data_type = set_data_type(@options[:data_type])
59
51
  end
60
52
 
53
+ def set_option(key, value)
54
+ @options.merge!(key.to_sym => value)
55
+ end
56
+
61
57
  def infer_const
62
58
  return false if breakpoint
63
59
 
@@ -68,7 +64,7 @@ module TensorStream
68
64
  true
69
65
  when :placeholder
70
66
  false
71
- when :variable_v2
67
+ when :variable_v2, :assign, :assign_add, :assign_sub
72
68
  false
73
69
  else
74
70
  non_const = @inputs.compact.find { |input| !input.is_const }
@@ -18,17 +18,7 @@ module TensorStream
18
18
  end
19
19
 
20
20
  def get_evaluator_classes(evaluators)
21
- @evaluator_classes = if evaluators.is_a?(Array)
22
- if evaluators.empty?
23
- TensorStream::Evaluator.default_evaluators
24
- else
25
- evaluators.collect { |name| Object.const_get("TensorStream::Evaluator::#{camelize(name.to_s)}") }
26
- end
27
- elsif evaluators.nil?
28
- TensorStream::Evaluator.default_evaluators
29
- else
30
- [Object.const_get("TensorStream::Evaluator::#{camelize(evaluators.to_s)}")]
31
- end
21
+ @evaluator_classes = TensorStream::EvaluatorUtils.get_evaluator_classes(evaluators)
32
22
  end
33
23
 
34
24
  def clear_session_cache
@@ -58,7 +48,8 @@ module TensorStream
58
48
  # scan for placeholders and assign value
59
49
  options[:feed_dict]&.each_key do |k|
60
50
  if k.is_a?(Placeholder)
61
- context[k.name.to_sym] = options[:feed_dict][k]
51
+ ph = options[:feed_dict][k]
52
+ context[k.name.to_sym] = ph.is_a?(Tensor) ? ph.op : ph
62
53
  elsif k.is_a?(String)
63
54
  target_graph = args[0].graph
64
55
  node = target_graph.get_node(k)
@@ -4,6 +4,7 @@ module TensorStream
4
4
  # Base class that defines a tensor like interface
5
5
  class Tensor
6
6
  include OpHelper
7
+ extend OpHelper
7
8
  include TensorMixins
8
9
 
9
10
  attr_reader :graph, :value
@@ -50,7 +50,6 @@ module TensorStream
50
50
  meta_data = JSON.parse(File.read(meta_file))
51
51
  gs = meta_data["gs"]
52
52
  filename = File.join(modelpath, ["model", gs, ".ckpt"].compact.join("-"))
53
-
54
53
  session.run(@restore_op, feed_dict: {@filename => filename})
55
54
  end
56
55
 
@@ -45,25 +45,22 @@ module TensorStream
45
45
  # Creates a variable
46
46
  # A variable maintains state across sessions
47
47
  def variable(value, name: nil, initializer: nil, graph: nil, dtype: nil, trainable: true)
48
- op = Graph.get_default_graph.add_op(:assign, nil, value)
49
48
  common_options = {
50
- initializer: initializer || op,
49
+ initializer: TensorStream.convert_to_tensor(initializer || value),
51
50
  name: name,
52
51
  graph: graph,
53
52
  dtype: dtype,
54
53
  trainable: trainable,
55
54
  }
56
55
  tensor = if value.is_a?(String)
57
- i_var(dtype || :string, 0, [], get_variable_scope, common_options)
58
- elsif value.is_a?(Integer)
59
- i_var(dtype || :int32, 0, [], get_variable_scope, common_options)
60
- elsif value.is_a?(Float)
61
- i_var(dtype || :float32, 0, [], get_variable_scope, common_options)
62
- else
63
- i_var(dtype || :float32, 0, nil, get_variable_scope, common_options)
64
- end
65
- op.set_input(0, tensor.op)
66
- Graph.get_default_graph.add_node(op)
56
+ i_var(dtype || :string, 0, [], get_variable_scope, common_options)
57
+ elsif value.is_a?(Integer)
58
+ i_var(dtype || :int32, 0, [], get_variable_scope, common_options)
59
+ elsif value.is_a?(Float)
60
+ i_var(dtype || :float32, 0, [], get_variable_scope, common_options)
61
+ else
62
+ i_var(dtype || :float32, 0, nil, get_variable_scope, common_options)
63
+ end
67
64
  tensor
68
65
  end
69
66
 
@@ -19,7 +19,11 @@ module TensorStream
19
19
  node = graph.get_tensor_by_name(node_key)
20
20
  case node.operation
21
21
  when :variable_v2
22
- value = node.container
22
+ value = Evaluator.read_variable(node.graph, node.options[:var_name])
23
+ if value.nil?
24
+ raise "#{node.options[:var_name]} has no value"
25
+ end
26
+
23
27
  options = {
24
28
  value: value,
25
29
  data_type: node.data_type,
@@ -46,17 +46,16 @@ module TensorStream
46
46
 
47
47
  def assign(value, name: nil, use_locking: false)
48
48
  TensorStream.check_data_types(self, value)
49
- _op(:assign, self, value, name: name)
49
+ _op(:assign, value, name: name, var_name: @name)
50
50
  end
51
51
 
52
52
  def read_value
53
- @value = buffer.to_ruby if buffer
54
- @value
53
+ Evaluator.read_variable(@graph, @name)
55
54
  end
56
55
 
57
56
  def assign_add(value, name: nil)
58
57
  TensorStream.check_data_types(self, value)
59
- _op(:assign_add, self, value, data_type: data_type, name: name)
58
+ _op(:assign_add, value, data_type: data_type, name: name, var_name: @name)
60
59
  end
61
60
 
62
61
  def to_math(_tensor, _name_only = false, _max_depth = 99, _unused = 0)
@@ -65,11 +64,15 @@ module TensorStream
65
64
 
66
65
  def assign_sub(value)
67
66
  TensorStream.check_data_types(self, value)
68
- _op(:assign_sub, self, value)
67
+ _op(:assign_sub, value, data_type: data_type, name: name, var_name: @name)
69
68
  end
70
69
 
71
70
  def self.variables_initializer(collection)
72
- TensorStream.group(TensorStream.get_default_graph.get_collection(collection).map(&:initializer))
71
+ global_variables_ops = TensorStream.get_default_graph.get_collection(collection).map do |variable|
72
+ _op(:assign, variable.initializer, var_name: variable.name)
73
+ end
74
+
75
+ TensorStream.group(global_variables_ops)
73
76
  end
74
77
 
75
78
  def self.global_variables_initializer
@@ -1,5 +1,5 @@
1
1
  module TensorStream
2
- VERSION = "1.0.8".freeze
2
+ VERSION = "1.0.9".freeze
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ["lib"]
33
33
 
34
34
  spec.add_development_dependency "bundler"
35
- spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rake", "~> 12.3"
36
36
  spec.add_development_dependency "rspec", "~> 3.0"
37
37
  spec.add_development_dependency "awesome_print"
38
38
  spec.add_development_dependency "rubocop"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tensor_stream
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Emmanuel Dayo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-12 00:00:00.000000000 Z
11
+ date: 2020-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -317,6 +317,7 @@ files:
317
317
  - lib/tensor_stream/evaluator/base_evaluator.rb
318
318
  - lib/tensor_stream/evaluator/buffer.rb
319
319
  - lib/tensor_stream/evaluator/evaluator.rb
320
+ - lib/tensor_stream/evaluator/evaluator_utils.rb
320
321
  - lib/tensor_stream/evaluator/operation_helpers/array_ops_helper.rb
321
322
  - lib/tensor_stream/evaluator/operation_helpers/math_helper.rb
322
323
  - lib/tensor_stream/evaluator/operation_helpers/random_gaussian.rb
@@ -326,6 +327,8 @@ files:
326
327
  - lib/tensor_stream/evaluator/ruby/math_ops.rb
327
328
  - lib/tensor_stream/evaluator/ruby/nn_ops.rb
328
329
  - lib/tensor_stream/evaluator/ruby/random_ops.rb
330
+ - lib/tensor_stream/evaluator/ruby/storage_manager.rb
331
+ - lib/tensor_stream/evaluator/ruby/variable_ops.rb
329
332
  - lib/tensor_stream/evaluator/ruby_evaluator.rb
330
333
  - lib/tensor_stream/exceptions.rb
331
334
  - lib/tensor_stream/generated_stub/ops.rb