Class: Tensorflow::Tensor
- Inherits:
-
Object
- Object
- Tensorflow::Tensor
- Defined in:
- lib/tensorflow/tensor.rb
Overview
Tensor is an n-dimensional array or list which represents a value produced by an Operation. A tensor has a rank, and a shape. A Tensor is a symbolic handle to one of the outputs of an Operation. It does not hold the values of that operation’s output, but instead provides a means of computing those values in a TensorFlow Session. It holds a multi-dimensional array of elements of a single data type. Official documentation of tensor. This class has two primary purposes:
-
Description :
-
A Tensor can be passed as an input to another Operation. This builds a dataflow connection between
operations, which enables TensorFlow to execute an entire Graph that represents a large, multi-step computation.
-
After the graph has been launched in a session, the value of the Tensor can be computed by passing it to
a Session.
-
The Tensor class takes array as input and creates a Tensor from it using SWIG.
-
Arguments :
-
Data
-> A Ruby array to be converted to tensor.
-
-
Examples :
input = Tensor.new([[[2,3,4],[2,3,4],[2,3,4]],[[2,3,4],[2,3,4],[2,3,4]]]) input.shape => [2, 3, 3] input.rank => 3 input.element_type => Integer
Instance Attribute Summary collapse
-
#data_size ⇒ Object
Returns the value of attribute data_size.
-
#dimension_data ⇒ Object
Returns shape of the tensor in the form of a c array.
-
#element_type ⇒ Object
Return data type of the tensor element.
-
#flatten ⇒ Object
Returns data array after flattening it.
-
#rank ⇒ Object
Return the Rank of the Tensor.
-
#shape ⇒ Object
Return the shape of the tensor in an array.
-
#tensor ⇒ Object
Returns the value of attribute tensor.
-
#tensor_data ⇒ Object
Returns serialized data in the form of a c array.
-
#tensor_shape_proto ⇒ Object
Returns the value of attribute tensor_shape_proto.
-
#type_num ⇒ Object
Return the enum value of data type.
Instance Method Summary collapse
-
#delete ⇒ Object
Deletes the tensor which will also ensure that the tensor_deallocator function is called and the C++ memory is freed properly.
-
#find_type(data) ⇒ Object
Converts a give ruby array to C array (using SWIG) by detecting the data type automatically.
-
#getval(dimension) ⇒ Object
Returns the value of the element contained in the specified position in the tensor.
-
#initialize(value, type = nil) ⇒ Tensor
constructor
A new instance of Tensor.
-
#ruby_array_to_c(array, type) ⇒ Object
Converts a give ruby array to C array (using SWIG) by detecting the data type automatically.
-
#set_type(type) ⇒ Object
Helper function to automatically set the data type of tensor.
Constructor Details
#initialize(value, type = nil) ⇒ Tensor
Returns a new instance of Tensor.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/tensorflow/tensor.rb', line 43 def initialize(value, type = nil) self.shape = self.class.shape_of(value) self.rank = shape.size self.element_type = type.nil? ? find_type(value) : set_type(type) if rank > 1 && type_num == Tensorflow::TF_STRING raise 'Multi-dimensional tensor not supported for string value type.' end self.flatten = [value].flatten self.tensor_data = ruby_array_to_c(flatten, type_num) self.dimension_data = ruby_array_to_c( rank.zero? ? [1] : shape, Tensorflow::TF_INT64 ) if type_num == Tensorflow::TF_STRING self.tensor = Tensorflow::String_encoder(CString(value), CString([0].pack("Q")) ) return self end self.tensor = Tensorflow::TF_NewTensor_wrapper(type_num, dimension_data, rank, tensor_data, data_size * flatten.length) end |
Instance Attribute Details
#data_size ⇒ Object
Returns the value of attribute data_size.
27 28 29 |
# File 'lib/tensorflow/tensor.rb', line 27 def data_size @data_size end |
#dimension_data ⇒ Object
Returns shape of the tensor in the form of a c array.
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def dimension_data @dimension_data end |
#element_type ⇒ Object
Return data type of the tensor element. (It is best if proper design decision is made regarding this. Because Currently data type support is limited to int64 and double.)
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def element_type @element_type end |
#flatten ⇒ Object
Returns data array after flattening it.
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def flatten @flatten end |
#rank ⇒ Object
Return the Rank of the Tensor.
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def rank @rank end |
#shape ⇒ Object
Return the shape of the tensor in an array.
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def shape @shape end |
#tensor ⇒ Object
Returns the value of attribute tensor.
27 28 29 |
# File 'lib/tensorflow/tensor.rb', line 27 def tensor @tensor end |
#tensor_data ⇒ Object
Returns serialized data in the form of a c array.
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def tensor_data @tensor_data end |
#tensor_shape_proto ⇒ Object
Returns the value of attribute tensor_shape_proto.
27 28 29 |
# File 'lib/tensorflow/tensor.rb', line 27 def tensor_shape_proto @tensor_shape_proto end |
#type_num ⇒ Object
Return the enum value of data type.
43 44 45 |
# File 'lib/tensorflow/tensor.rb', line 43 def type_num @type_num end |
Instance Method Details
#delete ⇒ Object
Deletes the tensor which will also ensure that the tensor_deallocator function is called and the C++ memory is freed properly. A memory leak will occur anytime the ruby garbage collector deletes a tensor before this function is called.
66 67 68 |
# File 'lib/tensorflow/tensor.rb', line 66 def delete() Tensorflow::TF_DeleteTensor(@tensor) end |
#find_type(data) ⇒ Object
Converts a give ruby array to C array (using SWIG) by detecting the data type automatically. Design decision needs to be made regarding this so the all the data types are supported. Currently Integer(Ruby) is converted to long long© and Float(Ruby) is converted double©.
-
Returns :
-
Data type
-
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/tensorflow/tensor.rb', line 100 def find_type(data) first_element = rank.zero? ? data : data.flatten[0] type, self.type_num, self.data_size = case first_element when Integer [Integer, Tensorflow::TF_INT64, 8] when Float, nil [Float, Tensorflow::TF_DOUBLE, 8] when String [String, Tensorflow::TF_STRING, 8] when Complex [Complex, Tensorflow::TF_COMPLEX128, 16] else raise 'Data type not supported.' end return type if rank == 0 if type == Integer || type == Float float_flag = type == Float ? 1 : 0 data.flatten.each do |i| raise 'Different data types in array.' unless i.is_a?(Float) || i.is_a?(Integer) float_flag = 1 if i.is_a?(Float) end if float_flag == 1 type = Float self.type_num = Tensorflow::TF_DOUBLE self.data_size = 8 end else data.flatten.each do |i| raise 'Different data types in array.' unless i.is_a?(type) end end type end |
#getval(dimension) ⇒ Object
Returns the value of the element contained in the specified position in the tensor.
-
Input :
-
Dimension array(1 based indexing).
-
-
Returns :
-
Value of the element contained in the specified position in the tensor.
-
181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/tensorflow/tensor.rb', line 181 def getval(dimension) raise('Invalid dimension array passed as input.', ShapeError) if dimension.length != shape.length (0..dimension.length - 1).each do |i| raise('Invalid dimension array passed as input.', ShapeError) if dimension[i] > shape[i] || dimension[i] < 1 || !(dimension[i].is_a? Integer) end sum = dimension.last - 1 prod = shape.last (0..dimension.length - 2).each do |i| sum += (dimension[dimension.length - 2 - i] - 1) * prod prod *= shape[shape.length - 2 - i] end flatten[sum] end |
#ruby_array_to_c(array, type) ⇒ Object
Converts a give ruby array to C array (using SWIG) by detecting the data type automatically. Design decision needs to be made regarding this so the all the data types are supported. Currently Integer(Ruby) is converted to long long© and Float(Ruby) is converted double©.
-
Returns :
-
A c array.
-
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/tensorflow/tensor.rb', line 145 def ruby_array_to_c(array, type) c_array = [] case type when Tensorflow::TF_FLOAT c_array = Tensorflow::Float.new(array.length) array.each_with_index { |value, i| c_array[i] = value } when Tensorflow::TF_DOUBLE c_array = Tensorflow::Double.new(array.length) array.each_with_index { |value, i| c_array[i] = value } when Tensorflow::TF_INT32 c_array = Tensorflow::Int.new(array.length) array.each_with_index { |value, i| c_array[i] = value } when Tensorflow::TF_INT64 c_array = Tensorflow::Long_long.new(array.length) array.each_with_index { |value, i| c_array[i] = value } when Tensorflow::TF_STRING c_array = Tensorflow::String_Vector.new array.each_with_index { |value, i| c_array[i] = value } c_array = Tensorflow.string_array_from_string_vector(c_array) else c_array = Tensorflow::Complex_Vector.new array.each_with_index { |value, i| c_array[i] = value } c_array = Tensorflow.complex_array_from_complex_vector(c_array) end c_array end |
#set_type(type) ⇒ Object
Helper function to automatically set the data type of tensor.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/tensorflow/tensor.rb', line 73 def set_type(type) self.type_num, self.data_size, self.element_type = case type when :float [Tensorflow::TF_FLOAT, 8, Float] when :float64 [Tensorflow::TF_DOUBLE, 8, Float] when :int32 [Tensorflow::TF_INT32, 4, Integer] when :int64 [Tensorflow::TF_INT64, 8, Integer] when :string [Tensorflow::TF_STRING, 8, String] when :complex [Tensorflow::TF_COMPLEX128, 16, Complex] else raise ArgumentError, "Data type #{type} not supported" end end |