tensor_stream 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +34 -34
- data/Rakefile +3 -3
- data/USAGE_GUIDE.md +235 -0
- data/bin/stubgen +20 -0
- data/exe/model_utils +2 -2
- data/lib/tensor_stream.rb +45 -44
- data/lib/tensor_stream/constant.rb +2 -2
- data/lib/tensor_stream/control_flow.rb +1 -1
- data/lib/tensor_stream/debugging/debugging.rb +2 -2
- data/lib/tensor_stream/dynamic_stitch.rb +2 -2
- data/lib/tensor_stream/evaluator/base_evaluator.rb +18 -18
- data/lib/tensor_stream/evaluator/buffer.rb +1 -1
- data/lib/tensor_stream/evaluator/evaluator.rb +2 -2
- data/lib/tensor_stream/evaluator/operation_helpers/array_ops_helper.rb +41 -41
- data/lib/tensor_stream/evaluator/operation_helpers/math_helper.rb +1 -1
- data/lib/tensor_stream/evaluator/ruby/array_ops.rb +39 -39
- data/lib/tensor_stream/evaluator/ruby/check_ops.rb +2 -2
- data/lib/tensor_stream/evaluator/ruby/images_ops.rb +18 -18
- data/lib/tensor_stream/evaluator/ruby/math_ops.rb +13 -14
- data/lib/tensor_stream/evaluator/ruby/nn_ops.rb +33 -36
- data/lib/tensor_stream/evaluator/ruby/random_ops.rb +20 -21
- data/lib/tensor_stream/evaluator/ruby_evaluator.rb +36 -49
- data/lib/tensor_stream/exceptions.rb +1 -1
- data/lib/tensor_stream/generated_stub/ops.rb +691 -0
- data/lib/tensor_stream/generated_stub/stub_file.erb +24 -0
- data/lib/tensor_stream/graph.rb +18 -18
- data/lib/tensor_stream/graph_builder.rb +17 -17
- data/lib/tensor_stream/graph_deserializers/protobuf.rb +97 -97
- data/lib/tensor_stream/graph_deserializers/yaml_loader.rb +1 -1
- data/lib/tensor_stream/graph_keys.rb +3 -3
- data/lib/tensor_stream/graph_serializers/graphml.rb +33 -33
- data/lib/tensor_stream/graph_serializers/packer.rb +23 -23
- data/lib/tensor_stream/graph_serializers/pbtext.rb +38 -42
- data/lib/tensor_stream/graph_serializers/serializer.rb +3 -2
- data/lib/tensor_stream/graph_serializers/yaml.rb +5 -5
- data/lib/tensor_stream/helpers/infer_shape.rb +56 -56
- data/lib/tensor_stream/helpers/op_helper.rb +8 -9
- data/lib/tensor_stream/helpers/string_helper.rb +15 -15
- data/lib/tensor_stream/helpers/tensor_mixins.rb +17 -17
- data/lib/tensor_stream/images.rb +1 -1
- data/lib/tensor_stream/initializer.rb +1 -1
- data/lib/tensor_stream/math_gradients.rb +28 -187
- data/lib/tensor_stream/monkey_patches/array.rb +1 -1
- data/lib/tensor_stream/monkey_patches/float.rb +1 -1
- data/lib/tensor_stream/monkey_patches/integer.rb +1 -1
- data/lib/tensor_stream/monkey_patches/op_patch.rb +5 -5
- data/lib/tensor_stream/monkey_patches/patch.rb +1 -1
- data/lib/tensor_stream/nn/nn_ops.rb +17 -15
- data/lib/tensor_stream/op_maker.rb +180 -0
- data/lib/tensor_stream/operation.rb +17 -17
- data/lib/tensor_stream/ops.rb +95 -384
- data/lib/tensor_stream/ops/add.rb +23 -0
- data/lib/tensor_stream/ops/argmax.rb +14 -0
- data/lib/tensor_stream/ops/argmin.rb +14 -0
- data/lib/tensor_stream/ops/case.rb +17 -0
- data/lib/tensor_stream/ops/cast.rb +15 -0
- data/lib/tensor_stream/ops/ceil.rb +15 -0
- data/lib/tensor_stream/ops/const.rb +0 -0
- data/lib/tensor_stream/ops/cos.rb +10 -0
- data/lib/tensor_stream/ops/div.rb +21 -0
- data/lib/tensor_stream/ops/equal.rb +15 -0
- data/lib/tensor_stream/ops/expand_dims.rb +17 -0
- data/lib/tensor_stream/ops/fill.rb +19 -0
- data/lib/tensor_stream/ops/floor.rb +15 -0
- data/lib/tensor_stream/ops/floor_div.rb +15 -0
- data/lib/tensor_stream/ops/greater.rb +11 -0
- data/lib/tensor_stream/ops/greater_equal.rb +11 -0
- data/lib/tensor_stream/ops/less_equal.rb +15 -0
- data/lib/tensor_stream/ops/log.rb +14 -0
- data/lib/tensor_stream/ops/mat_mul.rb +60 -0
- data/lib/tensor_stream/ops/max.rb +15 -0
- data/lib/tensor_stream/ops/min.rb +15 -0
- data/lib/tensor_stream/ops/mod.rb +23 -0
- data/lib/tensor_stream/ops/mul.rb +21 -0
- data/lib/tensor_stream/ops/negate.rb +14 -0
- data/lib/tensor_stream/ops/ones_like.rb +19 -0
- data/lib/tensor_stream/ops/pow.rb +25 -0
- data/lib/tensor_stream/ops/prod.rb +60 -0
- data/lib/tensor_stream/ops/random_uniform.rb +18 -0
- data/lib/tensor_stream/ops/range.rb +20 -0
- data/lib/tensor_stream/ops/rank.rb +13 -0
- data/lib/tensor_stream/ops/reshape.rb +24 -0
- data/lib/tensor_stream/ops/round.rb +15 -0
- data/lib/tensor_stream/ops/shape.rb +14 -0
- data/lib/tensor_stream/ops/sigmoid.rb +10 -0
- data/lib/tensor_stream/ops/sign.rb +12 -0
- data/lib/tensor_stream/ops/sin.rb +10 -0
- data/lib/tensor_stream/ops/size.rb +16 -0
- data/lib/tensor_stream/ops/sub.rb +24 -0
- data/lib/tensor_stream/ops/sum.rb +27 -0
- data/lib/tensor_stream/ops/tan.rb +12 -0
- data/lib/tensor_stream/ops/tanh.rb +10 -0
- data/lib/tensor_stream/ops/tile.rb +19 -0
- data/lib/tensor_stream/ops/zeros.rb +15 -0
- data/lib/tensor_stream/placeholder.rb +2 -2
- data/lib/tensor_stream/profile/report_tool.rb +3 -3
- data/lib/tensor_stream/session.rb +36 -38
- data/lib/tensor_stream/tensor.rb +2 -2
- data/lib/tensor_stream/tensor_shape.rb +4 -4
- data/lib/tensor_stream/train/adadelta_optimizer.rb +8 -8
- data/lib/tensor_stream/train/adagrad_optimizer.rb +3 -3
- data/lib/tensor_stream/train/adam_optimizer.rb +11 -11
- data/lib/tensor_stream/train/learning_rate_decay.rb +2 -2
- data/lib/tensor_stream/train/momentum_optimizer.rb +7 -7
- data/lib/tensor_stream/train/optimizer.rb +9 -9
- data/lib/tensor_stream/train/rmsprop_optimizer.rb +16 -16
- data/lib/tensor_stream/train/saver.rb +14 -14
- data/lib/tensor_stream/train/slot_creator.rb +6 -6
- data/lib/tensor_stream/train/utils.rb +12 -12
- data/lib/tensor_stream/trainer.rb +10 -10
- data/lib/tensor_stream/types.rb +1 -1
- data/lib/tensor_stream/utils.rb +33 -32
- data/lib/tensor_stream/utils/freezer.rb +5 -5
- data/lib/tensor_stream/variable.rb +5 -5
- data/lib/tensor_stream/variable_scope.rb +1 -1
- data/lib/tensor_stream/version.rb +1 -1
- data/samples/{iris.data → datasets/iris.data} +0 -0
- data/samples/jupyter_notebooks/linear_regression.ipynb +463 -0
- data/samples/{iris.rb → neural_networks/iris.rb} +21 -23
- data/samples/{mnist_data.rb → neural_networks/mnist_data.rb} +8 -8
- data/samples/neural_networks/raw_neural_net_sample.rb +112 -0
- data/samples/{rnn.rb → neural_networks/rnn.rb} +28 -31
- data/samples/{nearest_neighbor.rb → others/nearest_neighbor.rb} +12 -12
- data/samples/regression/linear_regression.rb +63 -0
- data/samples/{logistic_regression.rb → regression/logistic_regression.rb} +14 -16
- data/tensor_stream.gemspec +9 -8
- metadata +89 -19
- data/data_1.json +0 -4764
- data/data_2.json +0 -4764
- data/data_actual.json +0 -28
- data/data_expected.json +0 -28
- data/data_input.json +0 -28
- data/samples/error.graphml +0 -2755
- data/samples/gradient_sample.graphml +0 -1255
- data/samples/linear_regression.rb +0 -69
- data/samples/multigpu.rb +0 -73
- data/samples/raw_neural_net_sample.rb +0 -112
@@ -0,0 +1,19 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :ones_like do |op|
|
2
|
+
op.what_it_does "Creates a tensor with all elements set to 1."
|
3
|
+
op.what_it_does "Given a single tensor (tensor), this operation returns a"
|
4
|
+
op.what_it_does "tensor of the same type and shape as tensor with all elements set to 1."
|
5
|
+
op.what_it_does "Optionally, you can specify a new type (dtype) for the returned tensor."
|
6
|
+
|
7
|
+
|
8
|
+
op.parameter :input, "A tensor"
|
9
|
+
op.option :dtype, "Optional new data type to cast into", :nil, alias: :data_type
|
10
|
+
op.option :name, "Optional name", :nil
|
11
|
+
|
12
|
+
op.define_shape do |tensor|
|
13
|
+
tensor.inputs[0].shape.shape
|
14
|
+
end
|
15
|
+
|
16
|
+
op.define_gradient do |grad, node, params|
|
17
|
+
nil # non differentiable
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :pow do |op|
|
2
|
+
op.what_it_does "Computes the power of one value to another X^Y element wise"
|
3
|
+
|
4
|
+
op.parameter :input_a, "tensor X"
|
5
|
+
op.parameter :input_b, "tensor Y"
|
6
|
+
|
7
|
+
op.apply_data_type_coercion!
|
8
|
+
op.supports_broadcasting!
|
9
|
+
|
10
|
+
op.option :name, "Optional name", :nil
|
11
|
+
|
12
|
+
op.define_gradient do |grad, node, params|
|
13
|
+
x, y = params
|
14
|
+
z = node
|
15
|
+
sx = ts.shape(x)
|
16
|
+
sy = ts.shape(y)
|
17
|
+
rx, ry = _broadcast_gradient_args(sx, sy)
|
18
|
+
gx = ts.reduce_sum(grad * y * ts.pow(x, y - 1), rx)
|
19
|
+
|
20
|
+
log_x = ts.where(x > 0, ts.log(x), ts.zeros_like(x))
|
21
|
+
gy = ts.reduce_sum(grad * z * log_x, ry)
|
22
|
+
|
23
|
+
[gx, gy]
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :prod do |op|
|
2
|
+
op.other_names %w(reduce_prod)
|
3
|
+
op.what_it_does "Computes the product of elements across dimensions of a tensor."
|
4
|
+
op.what_it_does "Reduces input_tensor along the dimensions given in axis. Unless keepdims is true, the rank of the"
|
5
|
+
op.what_it_does "tensor is reduced by 1 for each entry in axis. If keepdims is true, the reduced dimensions are"
|
6
|
+
op.what_it_does "retained with length 1."
|
7
|
+
op.what_it_does "If axis has no entries, all dimensions are reduced, and a tensor with a single element is returned."
|
8
|
+
|
9
|
+
op.parameter :input_a, "tensor X"
|
10
|
+
op.parameter :axis, "tensor X", :nil, validate: 'INTEGER_TYPES'
|
11
|
+
|
12
|
+
op.option :name, "Optional name", :nil
|
13
|
+
op.option :keepdims, "If true, retains reduced dimensions with length 1.", :false
|
14
|
+
|
15
|
+
op.add_custom "input_a = TensorStream.convert_to_tensor(input_a)"
|
16
|
+
op.add_custom "return input_a if input_a.shape.scalar?"
|
17
|
+
op.add_custom "axis = cast_axis(input_a, axis)"
|
18
|
+
|
19
|
+
op.define_gradient do |grad, node, params|
|
20
|
+
x, y = params
|
21
|
+
input_shape = ts.shape(x)
|
22
|
+
y = ts.range(0, ts.rank(x)) if y.nil?
|
23
|
+
reduction_indices = ts.reshape(y, [-1])
|
24
|
+
|
25
|
+
output_shape_kept_dims = ts.reduced_shape(input_shape, y)
|
26
|
+
tile_scaling = _safe_shape_div(input_shape, output_shape_kept_dims)
|
27
|
+
grad = ts.reshape(grad, output_shape_kept_dims)
|
28
|
+
grad = ts.tile(grad, tile_scaling)
|
29
|
+
|
30
|
+
perm, reduced_num, other_num = ts.device("/cpu:0") {
|
31
|
+
rank = ts.rank(x)
|
32
|
+
reduction_indices = (reduction_indices + rank) % rank
|
33
|
+
reduced = ts.cast(reduction_indices, :int32)
|
34
|
+
idx = ts.range(0, rank)
|
35
|
+
other, = ts.setdiff1d(idx, reduced)
|
36
|
+
[ts.concat([reduced, other], 0),
|
37
|
+
ts.reduce_prod(ts.gather(input_shape, reduced)),
|
38
|
+
ts.reduce_prod(ts.gather(input_shape, other)),]
|
39
|
+
}
|
40
|
+
|
41
|
+
permuted = ts.transpose(x, perm)
|
42
|
+
permuted_shape = ts.shape(permuted)
|
43
|
+
|
44
|
+
reshaped = ts.reshape(permuted, [reduced_num, other_num])
|
45
|
+
|
46
|
+
# Calculate product, leaving out the current entry
|
47
|
+
left = ts.cumprod(reshaped, axis: 0, exclusive: true)
|
48
|
+
right = ts.cumprod(reshaped, axis: 0, exclusive: true, reverse: true)
|
49
|
+
y = ts.reshape(left * right, permuted_shape)
|
50
|
+
|
51
|
+
# Invert the transpose and reshape operations.
|
52
|
+
# Make sure to set the statically known shape information through a reshape.
|
53
|
+
out = grad * ts.transpose(y, ts.invert_permutation(perm))
|
54
|
+
[ts.reshape(out, input_shape, name: "prod"), nil]
|
55
|
+
end
|
56
|
+
|
57
|
+
op.define_shape do |tensor|
|
58
|
+
_infer_reduction_op_shape(tensor)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :random_uniform do |op|
|
2
|
+
op.what_it_does "Outputs random values from a uniform distribution."
|
3
|
+
|
4
|
+
op.parameter :shape, "A 1-D integer Tensor or array. The shape of the output tensor."
|
5
|
+
|
6
|
+
op.option :name, "Optional name", :nil
|
7
|
+
op.option :dtype, "The type of the output: float16, float32, float64, int32, or int64", ":float32"
|
8
|
+
op.option :minval, "A 0-D Tensor or ruby value of type dtype. The lower bound on the range of random values to generate. Defaults to 0.", 0
|
9
|
+
op.option :maxval, "A 0-D Tensor or ruby value of type dtype. The upper bound on the range of random values to generate. Defaults to 1 if dtype is floating point.", 1
|
10
|
+
op.option :seed, " A ruby integer. Used to create a random seed for the distribution. See set_random_seed for behavior.", :nil
|
11
|
+
|
12
|
+
op.define_shape do |tensor|
|
13
|
+
a_shape = tensor.inputs[0] ? tensor.inputs[0].const_value : tensor.options[:shape]
|
14
|
+
next nil if a_shape.nil?
|
15
|
+
|
16
|
+
a_shape.is_a?(Array) ? a_shape : [a_shape]
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :range do |op|
|
2
|
+
op.what_it_does "Creates a sequence of numbers."
|
3
|
+
op.what_it_does "Creates a sequence of numbers that begins at start and extends by increments of delta up to but not including limit."
|
4
|
+
|
5
|
+
op.parameter :start, "Acts as first entry in the range if limit is not nil; otherwise, acts as range limit and first entry defaults to 0.", "0"
|
6
|
+
op.parameter :limit, "Upper limit of sequence, exclusive. If nil, defaults to the value of start while the first entry of the range defaults to 0.", "0"
|
7
|
+
op.parameter :delta, "Number that increments start. Defaults to 1.", 1
|
8
|
+
|
9
|
+
op.option :name, " A name for the operation. Defaults to \"range\".", "\"range\""
|
10
|
+
op.option :dtype, "The type of the elements of the resulting tensor.", :nil
|
11
|
+
op.option :output_type, "Output data type defaults to int32", ":int32"
|
12
|
+
|
13
|
+
op.define_gradient do |grad, node, params|
|
14
|
+
nil # non differentiable
|
15
|
+
end
|
16
|
+
|
17
|
+
op.define_shape do |tensor|
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :rank do |op|
|
2
|
+
op.what_it_does "Returns the rank of a tensor"
|
3
|
+
|
4
|
+
op.parameter :input, "A tensor"
|
5
|
+
op.option :name, "Optional name", :nil
|
6
|
+
|
7
|
+
op.add_custom "input = convert_to_tensor(input)"
|
8
|
+
op.add_custom "return cons(input.shape.ndims) if input.shape.known?"
|
9
|
+
|
10
|
+
op.define_shape do |tensor|
|
11
|
+
[]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :reshape do |op|
|
2
|
+
op.what_it_does "Reshapes a tensor."
|
3
|
+
op.what_it_does "Given tensor, this operation returns a tensor that has the same values as tensor with shape shape."
|
4
|
+
|
5
|
+
op.parameter :input, "A tensor"
|
6
|
+
op.parameter :shape, "A new tensor shape"
|
7
|
+
op.option :name, "Optional name", :nil
|
8
|
+
|
9
|
+
op.define_gradient do |grad, node, params|
|
10
|
+
[ts.reshape(grad, ts.shape(node.inputs[0])), nil]
|
11
|
+
end
|
12
|
+
|
13
|
+
op.define_shape do |tensor|
|
14
|
+
new_shape = tensor.inputs[1]&.const_value ? tensor.inputs[1].const_value : nil
|
15
|
+
next nil if new_shape.nil?
|
16
|
+
next nil if tensor.inputs[0].shape.nil?
|
17
|
+
|
18
|
+
input_shape = tensor.inputs[0].shape.shape
|
19
|
+
next new_shape if input_shape.nil? && !new_shape.include?(-1) && !new_shape.include?(nil)
|
20
|
+
next nil if input_shape.nil? || input_shape.include?(nil)
|
21
|
+
|
22
|
+
TensorStream::TensorShape.fix_inferred_elements(new_shape, input_shape.reduce(:*))
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :round do |op|
|
2
|
+
op.what_it_does "Rounds the values of a tensor to the nearest integer, element-wise"
|
3
|
+
|
4
|
+
op.parameter :input_a, "tensor X", validate: 'FLOATING_POINT_TYPES'
|
5
|
+
|
6
|
+
op.option :name, "Optional name", :nil
|
7
|
+
|
8
|
+
op.define_gradient do |grad, node, params|
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
|
12
|
+
op.define_shape do |tensor|
|
13
|
+
tensor.inputs[0].shape.shape
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :shape do |op|
|
2
|
+
op.what_it_does "This operation returns a 1-D integer tensor representing the shape of input"
|
3
|
+
|
4
|
+
op.parameter :input, "A tensor"
|
5
|
+
op.option :name, "Optional name", :nil
|
6
|
+
op.option :out_type, "Optional output type", ":int32"
|
7
|
+
|
8
|
+
op.add_custom 'return constant(shape_eval(input, out_type), dtype: out_type, name: "Shape/#{name}") if input.is_a?(Array) && !input[0].is_a?(Tensor)'
|
9
|
+
op.add_custom 'return constant(input.shape.shape, dtype: out_type, name: "Shape/#{input.name}_c") if shape_full_specified(input)'
|
10
|
+
|
11
|
+
op.define_shape do |tensor|
|
12
|
+
tensor.inputs[0].shape.shape ? [tensor.inputs[0].shape.shape.size] : nil
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :sigmoid do |op|
|
2
|
+
op.what_it_does "Computes sigmoid of x element-wise."
|
3
|
+
|
4
|
+
op.parameter :input_a, "tensor X", validate: 'FLOATING_POINT_TYPES'
|
5
|
+
op.option :name, "Optional name", :nil
|
6
|
+
|
7
|
+
op.define_gradient do |grad, _node, params|
|
8
|
+
i_op(:sigmoid_grad, params[0], grad)
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :sign do |op|
|
2
|
+
op.what_it_does "Computes sign of input element-wise."
|
3
|
+
op.what_it_does_code "y = sign(x) = -1 if x < 0; 0 if x == 0 or tf.is_nan(x); 1 if x > 0."
|
4
|
+
op.what_it_does "Zero is returned for NaN inputs."
|
5
|
+
|
6
|
+
op.parameter :input_a, "tensor X"
|
7
|
+
op.option :name, "Optional name", :nil
|
8
|
+
|
9
|
+
op.define_gradient do |grad, node, params|
|
10
|
+
ts.zeros(ts.shape(params[0]), dtype: params[0].data_type)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :sin do |op|
|
2
|
+
op.what_it_does "Computes sin of input element-wise."
|
3
|
+
|
4
|
+
op.parameter :input_a, "tensor X", validate: 'FLOATING_POINT_TYPES'
|
5
|
+
op.option :name, "Optional name", :nil
|
6
|
+
|
7
|
+
op.define_gradient do |grad, node, params|
|
8
|
+
grad * ts.cos(params[0])
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :size do |op|
|
2
|
+
op.what_it_does "Returns the size of a tensor."
|
3
|
+
op.what_it_does "Returns a 0-D Tensor representing the number of elements in input of type out_type. Defaults to :int32."
|
4
|
+
|
5
|
+
op.parameter :input, "A tensor"
|
6
|
+
op.option :name, "Optional name", :nil
|
7
|
+
op.option :out_type, "Optional output type", ":int32"
|
8
|
+
|
9
|
+
op.define_gradient do |grad, node, params|
|
10
|
+
nil # non differentiable
|
11
|
+
end
|
12
|
+
|
13
|
+
op.define_shape do |tensor|
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :sub do |op|
|
2
|
+
op.other_names %w(subtract)
|
3
|
+
op.what_it_does "Returns x - y element-wise."
|
4
|
+
|
5
|
+
op.parameter :input_a, "tensor X"
|
6
|
+
op.parameter :input_b, "tensor Y"
|
7
|
+
|
8
|
+
op.apply_data_type_coercion!
|
9
|
+
op.supports_broadcasting!
|
10
|
+
|
11
|
+
op.option :name, "Optional name", :nil
|
12
|
+
|
13
|
+
op.define_gradient do |grad, node, params|
|
14
|
+
x, y = params
|
15
|
+
next [grad, -grad] if shapes_fully_specified_and_equal(x, y)
|
16
|
+
|
17
|
+
sx = ts.shape(x, name: "sub/shape_x")
|
18
|
+
sy = ts.shape(y, name: "sub/shape_y")
|
19
|
+
rx, ry = _broadcast_gradient_args(sx, sy)
|
20
|
+
|
21
|
+
[ts.reshape(ts.reduce_sum(grad, rx, name: "add/reduce_sub_x"), sx),
|
22
|
+
-ts.reshape(ts.reduce_sum(grad, ry, name: "add/reduce_sub_y"), sy),]
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :sum do |op|
|
2
|
+
op.other_names %w(reduce_sum)
|
3
|
+
op.what_it_does "Computes the sum of elements across dimensions of a tensor."
|
4
|
+
op.what_it_does "Reduces input_tensor along the dimensions given in axis. Unless keepdims is true, the rank of the"
|
5
|
+
op.what_it_does "tensor is reduced by 1 for each entry in axis. If keepdims is true, the reduced dimensions are"
|
6
|
+
op.what_it_does "retained with length 1."
|
7
|
+
op.what_it_does "If axis has no entries, all dimensions are reduced, and a tensor with a single element is returned."
|
8
|
+
|
9
|
+
op.parameter :input_a, "tensor X"
|
10
|
+
op.parameter :axis, "tensor X", :nil, validate: 'INTEGER_TYPES'
|
11
|
+
|
12
|
+
op.option :name, "Optional name", :nil
|
13
|
+
op.option :keepdims, "If true, retains reduced dimensions with length 1.", :false
|
14
|
+
|
15
|
+
op.add_custom "input_a = TensorStream.convert_to_tensor(input_a)"
|
16
|
+
op.add_custom "return input_a if input_a.shape.scalar?"
|
17
|
+
op.add_custom "axis = cast_axis(input_a, axis)"
|
18
|
+
|
19
|
+
op.define_gradient do |grad, node, params|
|
20
|
+
x, y = params
|
21
|
+
_sum_grad(x, y, grad)
|
22
|
+
end
|
23
|
+
|
24
|
+
op.define_shape do |tensor|
|
25
|
+
_infer_reduction_op_shape(tensor)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :tan do |op|
|
2
|
+
op.what_it_does "Computes tan of input element-wise."
|
3
|
+
|
4
|
+
op.parameter :input_a, "tensor X", validate: 'FLOATING_POINT_TYPES'
|
5
|
+
op.option :name, "Optional name", :nil
|
6
|
+
|
7
|
+
op.define_gradient do |grad, node, params|
|
8
|
+
secx = ts.reciprocal(ts.cos(params[0]))
|
9
|
+
secx2 = ts.square(secx)
|
10
|
+
grad * secx2
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :tanh do |op|
|
2
|
+
op.what_it_does "Computes tanh of input element-wise."
|
3
|
+
|
4
|
+
op.parameter :input_a, "tensor X", validate: 'FLOATING_POINT_TYPES'
|
5
|
+
op.option :name, "Optional name", :nil
|
6
|
+
|
7
|
+
op.define_gradient do |grad, node, params|
|
8
|
+
grad * i_op(:tanh_grad, params[0])
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :tile do |op|
|
2
|
+
op.what_it_does "Constructs a tensor by tiling a given tensor."
|
3
|
+
op.what_it_does "This operation creates a new tensor by replicating input multiples times."
|
4
|
+
op.what_it_does "The output tensor's i'th dimension has input.dims(i) * multiples[i] elements,"
|
5
|
+
op.what_it_does "and the values of input are replicated multiples[i] times along the 'i'th dimension. For example, tiling [a b c d] by [2] produces [a b c d a b c d]."
|
6
|
+
|
7
|
+
op.parameter :input, "A tensor"
|
8
|
+
op.parameter :multiples, "Must be one of the following types: int32, int64. 1-D. Length must be the same as the number of dimensions in input"
|
9
|
+
op.option :name, "Optional name", :nil
|
10
|
+
|
11
|
+
|
12
|
+
op.define_gradient do |grad, node, params|
|
13
|
+
nil # non differentiable
|
14
|
+
end
|
15
|
+
|
16
|
+
op.define_shape do |tensor|
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
TensorStream::OpMaker.define_operation :zeros do |op|
|
2
|
+
op.what_it_does "Creates a tensor with all elements set to zero"
|
3
|
+
|
4
|
+
op.parameter :shape, "A 1-D integer Tensor or ruby array. The shape of the output tensor."
|
5
|
+
|
6
|
+
op.option :dtype, "Optional name", ":float32"
|
7
|
+
op.option :name, "Optional name", :nil
|
8
|
+
|
9
|
+
op.define_shape do |tensor|
|
10
|
+
a_shape = tensor.inputs[0] ? tensor.inputs[0].const_value : tensor.options[:shape]
|
11
|
+
next nil if a_shape.nil?
|
12
|
+
|
13
|
+
a_shape.is_a?(Array) ? a_shape : [a_shape]
|
14
|
+
end
|
15
|
+
end
|
@@ -10,12 +10,12 @@ module TensorStream
|
|
10
10
|
@value = nil
|
11
11
|
@is_const = false
|
12
12
|
|
13
|
-
@name = [@graph.get_name_scope, options[:name] || build_name].compact.reject(&:empty?).join(
|
13
|
+
@name = [@graph.get_name_scope, options[:name] || build_name].compact.reject(&:empty?).join("/")
|
14
14
|
@op = Graph.get_default_graph.add_op!(:placeholder, data_type: @data_type, shape: @shape, internal_name: @name)
|
15
15
|
end
|
16
16
|
|
17
17
|
def inspect
|
18
|
-
"Placeholder(#{@name} shape: #{@shape ||
|
18
|
+
"Placeholder(#{@name} shape: #{@shape || "?"} data_type: #{@data_type})"
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -4,9 +4,9 @@ module TensorStream
|
|
4
4
|
class ReportTool
|
5
5
|
def self.profile_for(session, order_by: :slowest)
|
6
6
|
context = session.last_session_context
|
7
|
-
eval_times = context[:profile][:operations].map
|
7
|
+
eval_times = context[:profile][:operations].map { |name, profile|
|
8
8
|
[name, profile[:op], profile[:eval_time], profile[:shape]]
|
9
|
-
|
9
|
+
}
|
10
10
|
|
11
11
|
if order_by == :slowest
|
12
12
|
eval_times.sort_by { |a| a[2] }.reverse!
|
@@ -15,4 +15,4 @@ module TensorStream
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
-
end
|
18
|
+
end
|
@@ -19,16 +19,16 @@ module TensorStream
|
|
19
19
|
|
20
20
|
def get_evaluator_classes(evaluators)
|
21
21
|
@evaluator_classes = if evaluators.is_a?(Array)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
32
32
|
end
|
33
33
|
|
34
34
|
def clear_session_cache
|
@@ -41,10 +41,10 @@ module TensorStream
|
|
41
41
|
|
42
42
|
def run(*args)
|
43
43
|
options = if args.last.is_a?(Hash)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
args.pop
|
45
|
+
else
|
46
|
+
{}
|
47
|
+
end
|
48
48
|
|
49
49
|
@evaluator_options[:thread_pool] = @thread_pool
|
50
50
|
@evaluator_options[:log_intermediates] = options[:log_intermediates]
|
@@ -52,25 +52,23 @@ module TensorStream
|
|
52
52
|
context = {
|
53
53
|
_cache: @session_cache,
|
54
54
|
_options: options.merge(@evaluator_options),
|
55
|
-
profile: {
|
55
|
+
profile: {step: 0, operations: {}},
|
56
56
|
}
|
57
57
|
|
58
58
|
# scan for placeholders and assign value
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
raise "Invalid placeholder type passed key must be a string or a placeholder type"
|
73
|
-
end
|
59
|
+
options[:feed_dict]&.each_key do |k|
|
60
|
+
if k.is_a?(Placeholder)
|
61
|
+
context[k.name.to_sym] = options[:feed_dict][k]
|
62
|
+
elsif k.is_a?(String)
|
63
|
+
target_graph = args[0].graph
|
64
|
+
node = target_graph.get_node(k)
|
65
|
+
raise "Cannot find placeholder with the name of #{k}" if node.operation != :placeholder
|
66
|
+
|
67
|
+
context[k.to_sym] = options[:feed_dict][k]
|
68
|
+
elsif k.is_a?(Operation) && k.operation == :placeholder
|
69
|
+
context[k.name.to_sym] = options[:feed_dict][k]
|
70
|
+
else
|
71
|
+
raise "Invalid placeholder type passed key must be a string or a placeholder type"
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
@@ -82,21 +80,21 @@ module TensorStream
|
|
82
80
|
puts "#{k} : #{v[0].name}"
|
83
81
|
end
|
84
82
|
end
|
85
|
-
result = args.collect
|
83
|
+
result = args.collect { |e|
|
86
84
|
next e.value if e.is_a?(Tensor) && e.is_const && e.value
|
87
85
|
|
88
86
|
value = delegate_to_evaluator(e, context, {})
|
89
87
|
recursive_eval(value)
|
90
|
-
|
88
|
+
}
|
91
89
|
args.size == 1 ? result.first : result
|
92
90
|
end
|
93
91
|
|
94
92
|
def list_devices
|
95
|
-
TensorStream::Evaluator.evaluators.collect
|
93
|
+
TensorStream::Evaluator.evaluators.collect { |_k, v|
|
96
94
|
v[:class].query_supported_devices.collect do |device|
|
97
95
|
device
|
98
96
|
end
|
99
|
-
|
97
|
+
}.flatten
|
100
98
|
end
|
101
99
|
|
102
100
|
def close
|
@@ -117,11 +115,11 @@ module TensorStream
|
|
117
115
|
|
118
116
|
def dump_ops(tensor, selector)
|
119
117
|
graph = tensor.graph
|
120
|
-
graph.nodes.select { |k, v| selector.call(k, v) }.collect
|
118
|
+
graph.nodes.select { |k, v| selector.call(k, v) }.collect { |k, node|
|
121
119
|
next unless @last_session_context[node.name]
|
122
120
|
|
123
121
|
"#{k} #{node.to_math(true, 1)} = #{@last_session_context[node.name]}"
|
124
|
-
|
122
|
+
}.compact
|
125
123
|
end
|
126
124
|
|
127
125
|
def graph_ml(tensor, filename)
|
@@ -143,12 +141,12 @@ module TensorStream
|
|
143
141
|
end
|
144
142
|
|
145
143
|
def assign_evaluator(tensor)
|
146
|
-
device = @evaluator_classes.map
|
144
|
+
device = @evaluator_classes.map { |klass|
|
147
145
|
next nil if tensor.is_a?(Operation) && !klass.ops.include?(tensor.operation.to_sym)
|
148
146
|
next klass.default_device if tensor.device.nil?
|
149
147
|
|
150
148
|
klass.query_device(tensor.device)
|
151
|
-
|
149
|
+
}.compact.first
|
152
150
|
|
153
151
|
raise "no evaluator available to execute #{tensor.operation}" if device.nil?
|
154
152
|
|