module TensorStream::Ops

Class that defines all available ops supported by TensorStream

Constants

FLOATING_POINT_TYPES
INTEGER_TYPES
NUMERIC_TYPES

Public Instance Methods

abs(input, name: nil) click to toggle source

Computes the absolute value of a tensor.

# File lib/tensor_stream/ops.rb, line 403
def abs(input, name: nil)
  _op(:abs, input, name: name)
end
acos(input, name: nil) click to toggle source

Computes acos of input element-wise

# File lib/tensor_stream/ops.rb, line 307
def acos(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:acos, input, name: name)
end
add_n(inputs, name: nil) click to toggle source

Adds all input tensors element-wise.

Elements must all be the same shape and type

# File lib/tensor_stream/ops.rb, line 294
def add_n(inputs, name: nil)
  _op(:add_n, *inputs, name: name)
end
asin(input, name: nil) click to toggle source

Computes asin of input element-wise

# File lib/tensor_stream/ops.rb, line 300
def asin(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:asin, input, name: name)
end
assert_equal(x, y, data: nil, summarize: nil, message: nil, name: nil) click to toggle source

Assert the condition x == y holds element-wise.

Argmuments

x Numeric Tensor. y Numeric Tensor, same dtype as and broadcastable to x.

Returns Op that raises InvalidArgumentError if x == y is false

# File lib/tensor_stream/ops.rb, line 29
def assert_equal(x, y, data: nil, summarize: nil, message: nil, name: nil)
  _op(:assert_equal, x, y, data: data, summarize: summarize, message: message, name: name)
end
atan(input, name: nil) click to toggle source

Computes atan of input element-wise

# File lib/tensor_stream/ops.rb, line 314
def atan(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:atan, input, name: name)
end
broadcast_gradient_args(shape_a, shape_b, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 466
def broadcast_gradient_args(shape_a, shape_b, name: nil)
  op_result = _op(:broadcast_gradient_args, shape_a, shape_b, name: name)
  [op_result[0], op_result[1]]
end
case(args = {}) click to toggle source

Create a case operation.

The pred_fn_pairs parameter is a dict or list of pairs of size N. Each pair contains a boolean scalar tensor and a proc that creates the tensors to be returned if the boolean evaluates to true. default is a proc generating a list of tensors. All the proc in pred_fn_pairs as well as default (if provided) should return the same number and types of tensors.

# File lib/tensor_stream/ops.rb, line 558
def case(args = {})
  args = args.dup
  default = args.delete(:default)
  exclusive = args.delete(:exclusive)
  strict = args.delete(:strict)
  name = args.delete(:name)

  predicates = []
  functions = []

  args.each do |k, v|
    raise "Invalid argment or option #{k}" unless k.is_a?(Tensor)

    predicates << k
    functions << (v.is_a?(Proc) ? v.call : v)
  end

  _op(:case, predicates, default, *functions, exclusive: exclusive, strict: strict, name: name)
end
cast(input, dtype, name: nil) click to toggle source

Casts a tensor to a new type, if needed

# File lib/tensor_stream/ops.rb, line 328
def cast(input, dtype, name: nil)
  input = convert_to_tensor(input)
  return input if input.data_type == dtype

  _op(:cast, input, data_type: dtype, name: name)
end
cast_axis(input, axis) click to toggle source
# File lib/tensor_stream/ops.rb, line 586
def cast_axis(input, axis)
  if !axis.nil?
    axis
  elsif input.shape.known?
    (0...input.shape.ndims).to_a
  else
    range(0, rank(input))
  end
end
check_numerics(tensor, message, name: nil) click to toggle source

Checks a tensor for NaN and Inf values. When run, reports an InvalidArgument error if tensor has any values that are not a number (NaN) or infinity (Inf). Otherwise, passes tensor as-is.

# File lib/tensor_stream/ops.rb, line 458
def check_numerics(tensor, message, name: nil)
  _op(:check_numerics, tensor, message: message, name: name)
end
clip_by_norm(tensor, clip_norm, axes: nil, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 535
def clip_by_norm(tensor, clip_norm, axes: nil, name: nil)
end
concat(values, axis, name: "concat") click to toggle source

Concatenates tensors along one dimension.

# File lib/tensor_stream/ops.rb, line 189
def concat(values, axis, name: "concat")
  if values.is_a?(Array)
    _op(:concat, axis, *values, name: name)
  else
    _op(:concat, axis, values, name: name)
  end
end
cond(pred, true_fn, false_fn, name: nil) click to toggle source

Return true_fn() if the predicate pred is true else false_fn().

# File lib/tensor_stream/ops.rb, line 280
def cond(pred, true_fn, false_fn, name: nil)
  _op(:case, [pred], false_fn, true_fn, name: name)
end
constant_initializer(value, dtype: nil, verify_shape: false) click to toggle source
# File lib/tensor_stream/ops.rb, line 129
def constant_initializer(value, dtype: nil, verify_shape: false)
  TensorStream::Initializer.new(-> { _op(:fill, nil, convert_to_tensor(value, dtype: dtype)) })
end
cumprod(x, axis: 0, exclusive: false, reverse: false, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 578
def cumprod(x, axis: 0, exclusive: false, reverse: false, name: nil)
  _op(:cumprod, x, axis: axis, exclusive: exclusive, reverse: reverse, name: name)
end
dynamic_partition(data, partitions, num_partitions, name: nil) click to toggle source

Partitions data into num_partitions tensors using indices from partitions

# File lib/tensor_stream/ops.rb, line 199
def dynamic_partition(data, partitions, num_partitions, name: nil)
  result = _op(:dynamic_partition, data, partitions, num_partitions: num_partitions, name: nil)
  num_partitions.times.map do |index|
    result[index]
  end
end
exp(input, name: nil) click to toggle source

Computes exponential of x element-wise.

# File lib/tensor_stream/ops.rb, line 437
def exp(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:exp, input, name: name)
end
expand_dims(input, axis = nil, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 91
def expand_dims(input, axis = nil, name: nil)
  _op(:expand_dims, input, axis, name: name)
end
eye(num_rows, num_columns: nil, dtype: :float32, name: nil) click to toggle source

Construct an identity matrix

# File lib/tensor_stream/ops.rb, line 87
def eye(num_rows, num_columns: nil, dtype: :float32, name: nil)
  _op(:eye, num_rows, num_columns || num_rows, data_type: dtype, name: name)
end
floor_div(input_a, input_b, name: nil) click to toggle source

Returns element-wise integer divistion.

# File lib/tensor_stream/ops.rb, line 321
def floor_div(input_a, input_b, name: nil)
  check_data_types(input_a, input_b)
  _op(:floor_div, input_a, input_b, name: name)
end
gather(params, indices, validate_indices: nil, name: nil, axis: 0) click to toggle source

Gather slices from params and axis according to indices.

# File lib/tensor_stream/ops.rb, line 474
def gather(params, indices, validate_indices: nil,
  name: nil,
  axis: 0)
  _op(:gather, params, indices, validate_indices: validate_indices, name: name, axis: axis)
end
glorot_uniform_initializer(seed: nil, dtype: nil) click to toggle source

The Glorot uniform initializer, also called Xavier uniform initializer.

It draws samples from a uniform distribution within [-limit, limit] where limit is sqrt(6 / (fan_in + fan_out)) where fan_in is the number of input units in the weight tensor and fan_out is the number of output units in the weight tensor.

# File lib/tensor_stream/ops.rb, line 139
def glorot_uniform_initializer(seed: nil, dtype: nil)
  TensorStream::Initializer.new(-> { _op(:glorot_uniform, seed: seed, data_type: dtype) })
end
gradients(tensor_ys, wrt_xs, name: "gradients", stop_gradients: nil) click to toggle source

Constructs symbolic derivatives of ys of input w.r.t. x in wrt_xs.

ys and xs are each a Tensor or a list of tensors. grad_ys is a list of Tensor, holding the gradients received by the ys. The list must be the same length as ys.

Arguments: tensor_ys : A Tensor or list of tensors to be differentiated. wrt_xs : A Tensor or list of tensors to be used for differentiation. stop_gradients : Optional. A Tensor or list of tensors not to differentiate through

# File lib/tensor_stream/ops.rb, line 42
def gradients(tensor_ys, wrt_xs, name: "gradients", stop_gradients: nil)
  tensor_ys = tensor_ys.op
  gs = wrt_xs.map(&:op).collect { |x|
    stops = stop_gradients ? stop_gradients.map(&:name).join("_") : ""
    gradient_program_name = "grad_#{tensor_ys.name}_#{x.name}_#{stops}".to_sym
    tensor_graph = tensor_ys.graph

    tensor_program = if tensor_graph.node_added?(gradient_program_name)
      tensor_graph.get_node(gradient_program_name)
    else
      tensor_graph.name_scope("gradient_wrt_#{x.name}") do
        derivative_ops = TensorStream::MathGradients.derivative(tensor_ys, x, graph: tensor_graph,
                                                                              stop_gradients: stop_gradients)
        tensor_graph.add_node!(gradient_program_name, derivative_ops)
      end
    end
    tensor_program
  }

  gs
end
identity(input, name: nil) click to toggle source

Return a tensor with the same shape and contents as input.

# File lib/tensor_stream/ops.rb, line 389
def identity(input, name: nil)
  _op(:identity, input, name: name)
end
index(tensor, sel, name: nil) click to toggle source

select an index in an array or a set of tensor outputs

# File lib/tensor_stream/ops.rb, line 254
def index(tensor, sel, name: nil)
  _op(:index, tensor, sel, name: name)
end
invert_permutation(x, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 582
def invert_permutation(x, name: nil)
  _op(:invert_permutation, x, name: name)
end
log(input, name: nil) click to toggle source

Computes natural logarithm of x element-wise.

# File lib/tensor_stream/ops.rb, line 423
def log(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:log, input, name: name)
end
log1p(input, name: nil) click to toggle source

Computes natural logarithm of (1 + x) element-wise.

# File lib/tensor_stream/ops.rb, line 430
def log1p(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:log1p, input, name: name)
end
logical_and(input_a, input_b, name: nil) click to toggle source

Returns the truth value of x AND y element-wise.

# File lib/tensor_stream/ops.rb, line 167
def logical_and(input_a, input_b, name: nil)
  check_data_types(input_a, input_b)
  _op(:logical_and, input_a, input_b, name: name)
end
maximum(input_a, input_b, name: nil) click to toggle source

Returns the max of x and y (i.e. x > y ? x : y) element-wise.

# File lib/tensor_stream/ops.rb, line 337
def maximum(input_a, input_b, name: nil)
  max(input_a, input_b, name: name)
end
minimum(input_a, input_b, name: nil) click to toggle source

Returns the min of x and y (i.e. x < y ? x : y) element-wise.

# File lib/tensor_stream/ops.rb, line 343
def minimum(input_a, input_b, name: nil)
  min(input_a, input_b, name: name)
end
multiply(input_a, input_b, name: nil) click to toggle source

Returns x * y element-wise. This operation supports broadcasting

# File lib/tensor_stream/ops.rb, line 396
def multiply(input_a, input_b, name: nil)
  check_data_types(input_a, input_b)
  _op(:mul, input_a, input_b, name: name)
end
negative(input, name: nil) click to toggle source

Computes numerical negative value element-wise.

# File lib/tensor_stream/ops.rb, line 357
def negative(input, name: nil)
  negate(input, name: name)
end
not_equal(input_a, input_b, name: nil) click to toggle source

Returns the truth value of (x != y) element-wise. This ops supports broadcasting

# File lib/tensor_stream/ops.rb, line 364
def not_equal(input_a, input_b, name: nil)
  check_data_types(input_a, input_b)
  _op(:not_equal, input_a, input_b, name: name)
end
ones(shape, dtype: :float32, name: nil) click to toggle source

Creates a tensor with all elements set to 1.

# File lib/tensor_stream/ops.rb, line 161
def ones(shape, dtype: :float32, name: nil)
  _op(:ones, shape, data_type: dtype, name: name)
end
ones_initializer(dtype: :float32) click to toggle source

initializer that generates tensors initialized to 1.

# File lib/tensor_stream/ops.rb, line 125
def ones_initializer(dtype: :float32)
  TensorStream::Initializer.new(-> { _op(:ones, data_type: dtype) })
end
ones_like(tensor, dtype: nil, name: nil) click to toggle source

Creates a tensor with all elements set to 1. Given a single tensor (tensor), this operation returns a tensor of the same type and shape as tensor with all elements set to 1. Optionally, you can specify a new type (dtype) for the returned tensor.

# File lib/tensor_stream/ops.rb, line 383
def ones_like(tensor, dtype: nil, name: nil)
  _op(:ones_like, tensor, data_type: dtype, name: name)
end
pack(values, axis: 0, name: "pack") click to toggle source

Same as stack

# File lib/tensor_stream/ops.rb, line 515
def pack(values, axis: 0, name: "pack")
  _op(:stack, *values, axis: axis, name: name)
end
pad(tensor, paddings, mode: "CONSTANT", name: nil) click to toggle source

Pads a tensor. This operation pads a tensor according to the paddings you specify.

# File lib/tensor_stream/ops.rb, line 451
def pad(tensor, paddings, mode: "CONSTANT", name: nil)
  _op(:pad, tensor, paddings, mode: mode, name: name)
end
print(input, data, message: nil, name: nil) click to toggle source

Prints a list of tensors.

This is an identity op (behaves like tf.identity) with the side effect of printing data when evaluating.

random_normal(shape, dtype: :float32, mean: 0.0, stddev: 1.0, seed: nil, name: nil) click to toggle source

Outputs random values from a normal distribution.

# File lib/tensor_stream/ops.rb, line 66
def random_normal(shape, dtype: :float32, mean: 0.0, stddev: 1.0, seed: nil, name: nil)
  options = {dtype: dtype, mean: mean, stddev: stddev, seed: seed, name: name}
  _op(:random_standard_normal, shape, options)
end
random_uniform_initializer(minval: 0, maxval: 1, seed: nil, dtype: nil) click to toggle source

Initializer that generates tensors with a uniform distribution.

# File lib/tensor_stream/ops.rb, line 145
def random_uniform_initializer(minval: 0, maxval: 1, seed: nil, dtype: nil)
  TensorStream::Initializer.new(-> { _op(:random_uniform, minval: 0, maxval: 1, seed: seed, data_type: dtype) })
end
reciprocal(tensor, name: nil) click to toggle source

Computes the reciprocal of x element-wise.

# File lib/tensor_stream/ops.rb, line 274
def reciprocal(tensor, name: nil)
  _op(:reciprocal, tensor, name: name)
end
reduce(op, input, axis = nil, keepdims: false, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 178
def reduce(op, input, axis = nil, keepdims: false, name: nil)
  input = TensorStream.convert_to_tensor(input)
  return input if input.shape.scalar?

  axis = cast_axis(input, axis)

  _op(op, input, axis, keepdims: keepdims, name: name)
end
reduce_mean(input_tensor, axis = nil, keepdims: false, name: nil) click to toggle source

Computes the mean of elements across dimensions of a tensor.

# File lib/tensor_stream/ops.rb, line 174
def reduce_mean(input_tensor, axis = nil, keepdims: false, name: nil)
  reduce(:mean, input_tensor, axis, keepdims: keepdims, name: name)
end
reshape(tensor, shape, name: nil) click to toggle source

Reshapes a tensor.

Given tensor, this operation returns a tensor that has the same values as tensor with shape shape.

# File lib/tensor_stream/ops.rb, line 262
def reshape(tensor, shape, name: nil)
  _op(:reshape, tensor, shape, name: name)
end
sec(input, name: nil) click to toggle source

Computes sec of input element-wise.

# File lib/tensor_stream/ops.rb, line 409
def sec(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:sec, input, name: name)
end
setdiff1d(x, y, index_dtype: :int32, name: nil) click to toggle source

Computes the difference between two lists of numbers or strings. Given a list x and a list y, this operation returns a list out that represents all values that are in x but not in y. The returned list out is sorted in the same order that the numbers appear in x (duplicates are preserved). This operation also returns a list idx that represents the position of each out element in x. In other words:

# File lib/tensor_stream/ops.rb, line 545
def setdiff1d(x, y, index_dtype: :int32, name: nil)
  result = _op(:setdiff1d, x, y, index_dtype: index_dtype, name: name)
  [result[0], result[1]]
end
shape_n(inputs, name: nil, out_type: :int32) click to toggle source
# File lib/tensor_stream/ops.rb, line 96
def shape_n(inputs, name: nil, out_type: :int32)
  shapes_known = true
  inputs.each do |input|
    unless input.shape.known?
      shapes_known = false
      break
    end
  end

  if shapes_known
    inputs.collect { |input| cons(input.shape.shape, dtype: out_type).op }
  else
    res = _op(:shape_n, *inputs, out_type: out_type, name: name)
    Array.new(inputs.size) do |index|
      res[index]
    end
  end
end
slice(input, start, size, name: nil) click to toggle source

Extracts a slice from a tensor.

This operation extracts a slice of size size from a tensor input starting at the location specified by begin. The slice size is represented as a tensor shape, where size is the number of elements of the 'i'th dimension of input that you want to slice. The starting location (begin) for the slice is represented as an offset in each dimension of input. In other words, begin is the offset into the 'i'th dimension of input that you want to slice from.

# File lib/tensor_stream/ops.rb, line 155
def slice(input, start, size, name: nil)
  _op(:slice, input, start, size: size, name: name)
end
split(value, num_or_size_splits, axis: 0, num: nil, name: "split") click to toggle source
# File lib/tensor_stream/ops.rb, line 206
def split(value, num_or_size_splits, axis: 0, num: nil, name: "split")
  value = convert_to_tensor(value)
  num_or_size_splits = convert_to_tensor(num_or_size_splits)
  axis = convert_to_tensor(axis)

  raise TensorStream::ValueError, "num_or_size_splits must be integer dtype" unless INTEGER_TYPES.include?(num_or_size_splits.data_type)

  res = _op(:split, value, num_or_size_splits, axis, name: name)

  pieces = if value.shape.known? && num_or_size_splits.is_const && num_or_size_splits.value && axis.is_const
    if num_or_size_splits.shape.scalar?
      raise TensorStream::ValueError, "num_or_size_splits must divide dimension #{value.shape.shape[axis.value]} evenly" unless (value.shape.shape[axis.value] % num_or_size_splits.value).zero?

      div = num_or_size_splits.value
      n = value.shape.shape[axis.value] / div

      Array.new(div) do
        new_shape = value.shape.shape.dup
        new_shape[axis.value] = n
        new_shape
      end
    elsif num_or_size_splits.shape.ndims == 1
      raise TensorStream::ValueError, "Sum of splits do not match total dimen in axis #{value.shape.shape[axis.value]} != #{num_or_size_splits.value.reduce(:+)}" if value.shape.shape[axis.value] != num_or_size_splits.value.reduce(:+)

      num_or_size_splits.value.collect do |v|
        new_shape = value.shape.shape.dup
        new_shape[axis.value] = v
        new_shape
      end
    else
      raise TensorStream::ValueError, "Scalar or 1D Tensor expected for num_or_size_splits"
    end
  else
    raise TensorStream::ValueError, "Cannot automatically determine num, please specify num: in options" if num.nil?

    Array.new(num) { nil }
  end

  pieces.collect.with_index do |shape, i|
    op = index(res, i, name: "split/index:#{i}")
    op.shape = TensorShape.new(shape) if shape

    op
  end
end
sqrt(input, name: nil) click to toggle source

Computes sqrt of input element-wise.

# File lib/tensor_stream/ops.rb, line 416
def sqrt(input, name: nil)
  check_allowed_types(input, FLOATING_POINT_TYPES)
  _op(:sqrt, input, name: name)
end
square(tensor, name: nil) click to toggle source

Computes square of x element-wise.

# File lib/tensor_stream/ops.rb, line 268
def square(tensor, name: nil)
  _op(:square, tensor, name: name)
end
squared_difference(input_a, input_b, name: nil) click to toggle source
# File lib/tensor_stream/ops.rb, line 462
def squared_difference(input_a, input_b, name: nil)
  _op(:squared_difference, input_a, input_b, name: name)
end
squeeze(value, axis: [], name: nil) click to toggle source

Removes dimensions of size 1 from the shape of a tensor.

Given a tensor input, this operation returns a tensor of the same type with all dimensions of size 1 removed. If you don't want to remove all size 1 dimensions, you can remove specific size 1 dimensions by specifying axis.

# File lib/tensor_stream/ops.rb, line 531
def squeeze(value, axis: [], name: nil)
  _op(:squeeze, value, axis: axis, name: nil)
end
stack(values, axis: 0, name: "stack") click to toggle source

Stacks a list of rank-R tensors into one rank-(R+1) tensor.

# File lib/tensor_stream/ops.rb, line 483
def stack(values, axis: 0, name: "stack")
  _op(:stack, *values, axis: axis, name: name)
end
stop_gradient(tensor, options = {}) click to toggle source

Stops gradient computation.

When executed in a graph, this op outputs its input tensor as-is.

# File lib/tensor_stream/ops.rb, line 81
def stop_gradient(tensor, options = {})
  _op(:stop_gradient, tensor, options)
end
transpose(tensor, perm = nil, name: "transpose") click to toggle source

Transposes a. Permutes the dimensions according to perm.

# File lib/tensor_stream/ops.rb, line 444
def transpose(tensor, perm = nil, name: "transpose")
  _op(:transpose, tensor, perm, name: name)
end
truncated_normal(shape, dtype: :float32, mean: 0.0, stddev: 1.0, seed: nil, name: nil, pre_gen_table_size: nil) click to toggle source

Outputs random values from a truncated normal distribution.

# File lib/tensor_stream/ops.rb, line 73
def truncated_normal(shape, dtype: :float32, mean: 0.0, stddev: 1.0, seed: nil, name: nil, pre_gen_table_size: nil)
  _op(:truncated_normal, shape, dtype: dtype, mean: mean, stddev: stddev, seed: seed, name: name, pre_gen_table_size: pre_gen_table_size)
end
unpack(value, num: nil, axis: 0, name: "unpack") click to toggle source

Same as unstack

# File lib/tensor_stream/ops.rb, line 522
def unpack(value, num: nil, axis: 0, name: "unpack")
  unstack(value, num: num, axis: axis, name: name)
end
unstack(value, num: nil, axis: 0, name: "unstack") click to toggle source

Unpacks the given dimension of a rank-R tensor into rank-(R-1) tensors.

# File lib/tensor_stream/ops.rb, line 490
def unstack(value, num: nil, axis: 0, name: "unstack")
  res = _op(:unstack, value, num: num, axis: axis, name: name)

  num_vars = if value.shape.known?
    new_shape = value.shape.shape.dup
    rank = new_shape.size - 1
    axis = rank + axis if axis < 0
    rotated_shape = Array.new(axis + 1) { new_shape.shift }
    new_shape = rotated_shape.rotate!(-1) + new_shape
    new_shape[0]
  else
    raise TensorStream::ValueError, "num is unspecified and cannot be inferred." if num.nil?

    num
  end

  return res[0] if num_vars == 1

  Array.new(num_vars) do |i|
    index(res, i, name: "unstack/index:#{i}")
  end
end
where(condition, true_t = nil, false_t = nil, name: nil) click to toggle source

Return the elements, either from x or y, depending on the condition.

# File lib/tensor_stream/ops.rb, line 286
def where(condition, true_t = nil, false_t = nil, name: nil)
  _op(:where, condition, true_t, false_t, name: name)
end
zeros_initializer(dtype: :float32) click to toggle source

initializer that generates tensors initialized to 0.

# File lib/tensor_stream/ops.rb, line 118
def zeros_initializer(dtype: :float32)
  TensorStream::Initializer.new(-> { _op(:zeros, data_type: dtype) })
end
zeros_like(tensor, dtype: nil, name: nil) click to toggle source

reates a tensor with all elements set to zero. Given a single tensor (tensor), this operation returns a tensor of the same type and shape as tensor with all elements set to zero. Optionally, you can use dtype to specify a new type for the returned tensor.

# File lib/tensor_stream/ops.rb, line 374
def zeros_like(tensor, dtype: nil, name: nil)
  _op(:zeros_like, tensor, data_type: dtype, name: name)
end