# Tensors Tensor is flexible data structure. The important parameter is the dimensionality of the tensor. It can have anything from a scalar to vector/matrix to multi dimensional tensor Creating a Tensor ```python a = tf.constant([1,2,3]) ``` Tensors have two fundamental properties: - shape - dtype tf.constant can reshape the vectors using the shape parameter. Once set the Tensor is immutable. Operating on it produces a new Tensor. `tf.constant(-1.0, shape=[2,3])` ## Operations - Addition `tf.add(a, b)` overloaded with `+` - Square `tf.square(5)` overloaded with `**` - Reduce sum`tf.reduce_sum([1,2,3]) => tf.tensor(6, shape=() dtype=int32)` - Casting `tf.cast(tensor, dtype=tf.float32)` - converts the tensor into float32 type - reshaping `tf.reshape(tensor, [2,3])` - Reshaping will "work" for any new shape with the same total number of elements, but it will not do anything useful if you do not respect the order of the axes - transpose `tf.transpose(tensor)` - matmul `tf.matmul(a,b)` If you add operate with tensors and numpy/python numbers, they get cast before adding to the tensor. Broadcasting works with tensors just like on numpy arrays ## tf.Variable `tf.Variable(initial_value=[1., 2.], dtype='float32')` It is used to create a "variable" (which looks and acts like a tensor). dtype and shape are derived from the initial value if it is set an not explicitly declared. After construction, the type and shape of the variable are fixed. The value can be changed using one of the assign methods. If you cast/reshape it, it creates a new Tensor and does not change the variable You can assign a new value to the variable ```python a = tf.Variable([2., 3.]) a.assign([1, 2]) # This will keep the same dtype float32 a.assign_add([1,1]) # This will add 1 to both elements of the variable ``` if you assign a tensor to another variable, it makes a full copy of it. The two variables will not share memory The shape argument to Variable's constructor allows you to construct a variable with a less defined shape than its `initial_value` Note "Variable" is spelled with a capital V ## Ragged Tensor Ragged tensor are tensors with variable number of elements along some axis. ![[Pasted image 20210206195609.png]] ```python ragged_list = [ [0, 1, 2, 3], [4, 5], [6, 7, 8], [9]] ragged_tensor = tf.ragged.constant(ragged_list) ``` ## String Tensor You can represent data as strings (variable-length byte arrays) in tensors.The strings are atomic and cannot be indexed the way Python strings are. The length of the string is not one of the axes of the tensor. `tf.string` has functions for manipulating them ## Sparse Tensor It stores sparse data efficiently ```python # Sparse tensors store values by index in a memory-efficient mannersparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4]) ``` You can convert sparse tensors to dense ```python tf.sparse.to_dense(sparse_tensor) ```