Помогают защитить Большой Барьерный Риф с TensorFlow на Kaggle Присоединяйтесь вызов

Введение в тензоры

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть исходный код на GitHub Скачать блокнот
import tensorflow as tf
import numpy as np

Тензоры многомерные массивы с типом равномерного (называется dtype ). Вы можете увидеть все поддерживаемые dtypes на tf.dtypes.DType .

Если вы знакомы с NumPy , тензоры (вид) , как np.arrays .

Все тензоры неизменяемы, как числа и строки Python: вы никогда не можете обновить содержимое тензора, а только создать новый.

Основы

Создадим несколько основных тензоров.

Вот тензор «скаляра» или «ранга 0». Скаляр содержит одно значение и не содержит «осей».

# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)

Тензор «вектора» или «ранга-1» подобен списку значений. Вектор имеет одну ось:

# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)

Тензор «матрицы» или «ранга-2» имеет две оси:

# If you want to be specific, you can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
                             [3, 4],
                             [5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor(
[[1. 2.]
 [3. 4.]
 [5. 6.]], shape=(3, 2), dtype=float16)
Скалярное, форма: [] Вектор, форма: [3] Матрица, форма: [3, 2]
Скаляр, число 4Строка из 3 частей, каждая из которых содержит номер.Сетка 3x2, каждая ячейка которой содержит число.

У тензоров может быть больше осей; вот тензор с тремя осями:

# There can be an arbitrary number of
# axes (sometimes called "dimensions")
rank_3_tensor = tf.constant([
  [[0, 1, 2, 3, 4],
   [5, 6, 7, 8, 9]],
  [[10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19]],
  [[20, 21, 22, 23, 24],
   [25, 26, 27, 28, 29]],])

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Есть много способов визуализировать тензор с более чем двумя осями.

А 3-осевой тензор, форма: [3, 2, 5]

Вы можете преобразовать тензор в массив NumPy либо с помощью np.array или tensor.numpy метода:

np.array(rank_2_tensor)
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)
rank_2_tensor.numpy()
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)

Тензоры часто содержат числа с плавающей запятой и целые числа, но имеют много других типов, в том числе:

  • сложные числа
  • струны

База tf.Tensor класс требует тензоров быть «прямоугольным» --- то есть, вдоль каждой оси, каждый элемент имеет такой же размер. Однако существуют специальные типы тензоров, которые могут обрабатывать различные формы:

  • Рваные тензоры (см RaggedTensor ниже)
  • Разреженных тензоры (см SparseTensor ниже)

Вы можете выполнять основную математику с тензорами, включая сложение, поэлементное умножение и умножение матриц.

a = tf.constant([[1, 2],
                 [3, 4]])
b = tf.constant([[1, 1],
                 [1, 1]]) # Could have also said `tf.ones([2,2])`

print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)
print(a + b, "\n") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)

Тензоры используются во всех видах операций (ops).

c = tf.constant([[4.0, 5.0], [10.0, 1.0]])

# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32)
tf.Tensor([1 0], shape=(2,), dtype=int64)
tf.Tensor(
[[2.6894143e-01 7.3105854e-01]
 [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)

О формах

У тензоров есть формы. Немного словарного запаса:

  • Форма: Длина (количество элементов) каждый из осей тензора.
  • Ранг: Количество осей тензора. Скаляр имеет ранг 0, вектор - ранг 1, матрица - ранг 2.
  • Ось или измерение: Конкретный размер тензора.
  • Размер: Общее число элементов в тензоре, вектор формы продукта.

Тензоры и tf.TensorShape объекты имеют удобные свойства для доступа к этим:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
Ранг-4 тензора, форма: [3, 2, 4, 5]
Тензорная форма похожа на вектор.4-осевой тензор
print("Type of every element:", rank_4_tensor.dtype)
print("Number of axes:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements along axis 0 of tensor:", rank_4_tensor.shape[0])
print("Elements along the last axis of tensor:", rank_4_tensor.shape[-1])
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy())
Type of every element: <dtype: 'float32'>
Number of axes: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*4*5):  120

Хотя оси часто называют их индексами, вы всегда должны отслеживать значение каждой из них. Часто оси располагаются в порядке от глобального к локальному: сначала ось партии, затем пространственные размеры и особенности для каждого местоположения в последнюю очередь. Таким образом, векторы признаков представляют собой непрерывные области памяти.

Типичный порядок осей
Следите за каждой осью. 4-осевой тензор может быть: Пакет, Ширина, Высота, Характеристики.

Индексирование

Одноосное индексирование

TensorFlow следует стандартным правилам индексации Python, аналогичные индексации списка или строки в Python , а также основные правила NumPy индексации.

  • Индексы начинаются с 0
  • отрицательные индексы считаются в обратном порядке с конца
  • колоны, : , используются для срезов: start:stop:step
rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print(rank_1_tensor.numpy())
[ 0  1  1  2  3  5  8 13 21 34]

Индексирование со скаляром удаляет ось:

print("First:", rank_1_tensor[0].numpy())
print("Second:", rank_1_tensor[1].numpy())
print("Last:", rank_1_tensor[-1].numpy())
First: 0
Second: 1
Last: 34

Индексация с : ломтиком держит ось:

print("Everything:", rank_1_tensor[:].numpy())
print("Before 4:", rank_1_tensor[:4].numpy())
print("From 4 to the end:", rank_1_tensor[4:].numpy())
print("From 2, before 7:", rank_1_tensor[2:7].numpy())
print("Every other item:", rank_1_tensor[::2].numpy())
print("Reversed:", rank_1_tensor[::-1].numpy())
Everything: [ 0  1  1  2  3  5  8 13 21 34]
Before 4: [0 1 1 2]
From 4 to the end: [ 3  5  8 13 21 34]
From 2, before 7: [1 2 3 5 8]
Every other item: [ 0  1  3  8 21]
Reversed: [34 21 13  8  5  3  2  1  1  0]

Многоосевая индексация

Тензоры более высокого ранга индексируются путем передачи нескольких индексов.

Те же правила, что и в случае с одной осью, применяются к каждой оси независимо.

print(rank_2_tensor.numpy())
[[1. 2.]
 [3. 4.]
 [5. 6.]]

Передавая целое число для каждого индекса, результатом будет скаляр.

# Pull out a single value from a 2-rank tensor
print(rank_2_tensor[1, 1].numpy())
4.0

Вы можете индексировать, используя любую комбинацию целых чисел и срезов:

# Get row and column tensors
print("Second row:", rank_2_tensor[1, :].numpy())
print("Second column:", rank_2_tensor[:, 1].numpy())
print("Last row:", rank_2_tensor[-1, :].numpy())
print("First item in last column:", rank_2_tensor[0, -1].numpy())
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n")
Second row: [3. 4.]
Second column: [2. 4. 6.]
Last row: [5. 6.]
First item in last column: 2.0
Skip the first row:
[[3. 4.]
 [5. 6.]]

Вот пример с 3-осевым тензором:

print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)
Выбор последней функции во всех местах в каждом примере в партии
Тензор 3x2x5 со всеми значениями в индексе 4 последней выбранной оси.Выбранные значения упакованы в 2-осевой тензор.

Прочитайте руководство для нарезки тензорной , чтобы узнать , как вы можете применять индексацию манипулировать отдельные элементы в ваших тензорах.

Манипулирование формами

Изменение формы тензора очень полезно.

# Shape returns a `TensorShape` object that shows the size along each axis
x = tf.constant([[1], [2], [3]])
print(x.shape)
(3, 1)
# You can convert this object into a Python list, too
print(x.shape.as_list())
[3, 1]

Вы можете преобразовать тензор в новую форму. tf.reshape операция быстро и дешево , как базовые данные не должны дублироваться.

# You can reshape a tensor to a new shape.
# Note that you're passing in a list
reshaped = tf.reshape(x, [1, 3])
print(x.shape)
print(reshaped.shape)
(3, 1)
(1, 3)

Данные сохраняют свой макет в памяти, и создается новый тензор с запрошенной формой, указывающий на те же данные. TensorFlow использует «строковое» упорядочение памяти в стиле C, где приращение крайнего правого индекса соответствует одному шагу в памяти.

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Если вы сгладите тензор, вы увидите, в каком порядке он размещен в памяти.

# A `-1` passed in the `shape` argument says "Whatever fits".
print(tf.reshape(rank_3_tensor, [-1]))
tf.Tensor(
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29], shape=(30,), dtype=int32)

Как правило, только разумное использование tf.reshape , чтобы объединить или разделить смежную ось (или добавить / удалить 1 с).

Для этого тензора 3x2x5 изменение формы до (3x2) x5 или 3x (2x5) является разумным решением, поскольку срезы не смешиваются:

print(tf.reshape(rank_3_tensor, [3*2, 5]), "\n")
print(tf.reshape(rank_3_tensor, [3, -1]))
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]
 [25 26 27 28 29]], shape=(6, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]], shape=(3, 10), dtype=int32)
Несколько хороших изменений.
Тензор 3x2x5Те же данные преобразованы в (3x2) x5Те же данные преобразованы в 3x (2x5)

Изменение формы будет "работать" для любой новой формы с тем же общим числом элементов, но не принесет ничего полезного, если вы не соблюдаете порядок осей.

Перестановка осей в tf.reshape не работает; вам нужно tf.transpose для этого.

# Bad examples: don't do this

# You can't reorder axes with reshape.
print(tf.reshape(rank_3_tensor, [2, 3, 5]), "\n") 

# This is a mess
print(tf.reshape(rank_3_tensor, [5, 6]), "\n")

# This doesn't work at all
try:
  tf.reshape(rank_3_tensor, [7, -1])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]]

 [[15 16 17 18 19]
  [20 21 22 23 24]
  [25 26 27 28 29]]], shape=(2, 3, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]
 [24 25 26 27 28 29]], shape=(5, 6), dtype=int32) 

InvalidArgumentError: Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]
Некоторые плохие изменения.
Вы не можете изменить порядок осей, используйте для этого tf.transposeВсе, что объединяет фрагменты данных вместе, вероятно, неправильно.Новая форма должна точно соответствовать.

Вы можете встретить не полностью заданные формы. Либо форма содержит None (ось длина неизвестна) или вся форма не является None (ранг тензора неизвестна).

За исключением tf.RaggedTensor такие формы будут происходить только в контексте символических графах построения интерфейсов TensorFlow в:

Подробнее о DTypes

Инспектировать tf.Tensor использовать тип данных «s в Tensor.dtype собственности.

При создании tf.Tensor из объекта Python , вы можете дополнительно указать тип данных.

Если вы этого не сделаете, TensorFlow выберет тип данных, который может представлять ваши данные. TensorFlow преобразует целые Python в tf.int32 и Python чисел с плавающей запятой в tf.float32 . В противном случае TensorFlow использует те же правила, что и NumPy при преобразовании в массивы.

Вы можете преобразовывать от типа к типу.

the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)
the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)
# Now, cast to an uint8 and lose the decimal precision
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)

Вещание

Вещание концепция заимствована из эквивалентной функции в NumPy . Короче говоря, при определенных условиях меньшие тензоры автоматически «растягиваются», чтобы соответствовать большим тензорам при выполнении над ними комбинированных операций.

Самый простой и распространенный случай - это попытка умножить или добавить тензор к скаляру. В этом случае скаляр транслируется, чтобы иметь ту же форму, что и другой аргумент.

x = tf.constant([1, 2, 3])

y = tf.constant(2)
z = tf.constant([2, 2, 2])
# All of these are the same computation
print(tf.multiply(x, 2))
print(x * y)
print(x * z)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)

Точно так же оси с длиной 1 могут быть растянуты, чтобы соответствовать другим аргументам. Оба аргумента могут быть растянуты в одном вычислении.

В этом случае матрица 3x1 поэлементно умножается на матрицу 1x4 для получения матрицы 3x4. Обратите внимание , как ведущий 1 является необязательным: Форма у равна [4] .

# These are the same computations
x = tf.reshape(x,[3,1])
y = tf.range(1, 5)
print(x, "\n")
print(y, "\n")
print(tf.multiply(x, y))
tf.Tensor(
[[1]
 [2]
 [3]], shape=(3, 1), dtype=int32) 

tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) 

tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)
Эфир добавить: а [3, 1] раза в [1, 4] дает [3,4]
Добавление матрицы 3x1 к матрице 4x1 приводит к матрице 3x4

Вот такая же операция без трансляции:

x_stretch = tf.constant([[1, 1, 1, 1],
                         [2, 2, 2, 2],
                         [3, 3, 3, 3]])

y_stretch = tf.constant([[1, 2, 3, 4],
                         [1, 2, 3, 4],
                         [1, 2, 3, 4]])

print(x_stretch * y_stretch)  # Again, operator overloading
tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)

В большинстве случаев широковещательная передача эффективна как по времени, так и по пространству, поскольку операция широковещательной передачи никогда не материализует расширенные тензоры в памяти.

Вы видите , что вещание выглядит как с помощью tf.broadcast_to .

print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))
tf.Tensor(
[[1 2 3]
 [1 2 3]
 [1 2 3]], shape=(3, 3), dtype=int32)

В отличие от математической оп, например, broadcast_to делает ничего особенного , чтобы сохранить память. Здесь вы материализуете тензор.

Это может быть еще более сложным. В этом разделе книги Джейка VanderPlas в Python Справочник научных данных показывает более вещания фокусов (опять же в NumPy).

tf.convert_to_tensor

Большинство ОПС, как tf.matmul и tf.reshape принимают аргументы класса tf.Tensor . Однако вы заметите, что в приведенном выше случае принимаются объекты Python в форме тензоров.

Большинство, но не все, опс называют convert_to_tensor на не тензорных аргументов. Существует реестр преобразований, и большинство классов объектов , как Numpy в ndarray , TensorShape , списки Python, и tf.Variable будет все преобразования автоматически.

См tf.register_tensor_conversion_function для получения более подробной информации, и если у вас есть свой собственный типа , который вы хотели бы, чтобы автоматически преобразовать в тензор.

Рваные тензоры

Тензор с переменным числом элементов вдоль некоторой оси называется рваным. Использование tf.ragged.RaggedTensor для рваных данных.

Например, это нельзя представить как обычный тензор:

tf.RaggedTensor , форма: [4, None]
Двухосный рваный тензор, каждая строка может иметь разную длину.
ragged_list = [
    [0, 1, 2, 3],
    [4, 5],
    [6, 7, 8],
    [9]]
try:
  tensor = tf.constant(ragged_list)
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Can't convert non-rectangular Python sequence to Tensor.

Вместо того, чтобы создать tf.RaggedTensor с помощью tf.ragged.constant :

ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor)
<tf.RaggedTensor [[0, 1, 2, 3], [4, 5], [6, 7, 8], [9]]>

Форма tf.RaggedTensor будет содержать несколько осей с неизвестными длинами:

print(ragged_tensor.shape)
(4, None)

Струнные тензоры

tf.string является dtype , который должен сказать , вы можете представлять данные в виде строк (переменной длиной байтовых массивов) в тензорах.

Строки являются атомарными и не могут быть проиндексированы так, как строки Python. Длина строки не является одной из осей тензора. См tf.strings для функций , чтобы управлять ими.

Вот тензор скалярной струны:

# Tensors can be strings, too here is a scalar string.
scalar_string_tensor = tf.constant("Gray wolf")
print(scalar_string_tensor)
tf.Tensor(b'Gray wolf', shape=(), dtype=string)

И вектор строк:

Вектор строк, форма: [3,]
Длина струны не является одной из осей тензора.
# If you have three string tensors of different lengths, this is OK.
tensor_of_strings = tf.constant(["Gray wolf",
                                 "Quick brown fox",
                                 "Lazy dog"])
# Note that the shape is (3,). The string length is not included.
print(tensor_of_strings)
tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)

В приведенном выше распечатке b префикс указывает на то, что tf.string DTYPE не Юникода строка, но байт-строка. Смотрите Учебник Unicode для больше о работе с текстом в юникод TensorFlow.

Если вы передаете символы юникода, они кодируются в кодировке utf-8.

tf.constant("🥳👍")
<tf.Tensor: shape=(), dtype=string, numpy=b'\xf0\x9f\xa5\xb3\xf0\x9f\x91\x8d'>

Некоторые основные функции со строками могут быть найдены в tf.strings , в том числе tf.strings.split .

# You can use split to split a string into a set of tensors
print(tf.strings.split(scalar_string_tensor, sep=" "))
tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)
# ...but it turns into a `RaggedTensor` if you split up a tensor of strings,
# as each string might be split into a different number of parts.
print(tf.strings.split(tensor_of_strings))
<tf.RaggedTensor [[b'Gray', b'wolf'], [b'Quick', b'brown', b'fox'], [b'Lazy', b'dog']]>
Три строки сплит, форма: [3, None]
Разделение нескольких строк возвращает tf.RaggedTensor

И tf.string.to_number :

text = tf.constant("1 10 100")
print(tf.strings.to_number(tf.strings.split(text, " ")))
tf.Tensor([  1.  10. 100.], shape=(3,), dtype=float32)

Хотя вы не можете использовать tf.cast превратить тензор строки в число, вы можете преобразовать его в байты, а затем в число.

byte_strings = tf.strings.bytes_split(tf.constant("Duck"))
byte_ints = tf.io.decode_raw(tf.constant("Duck"), tf.uint8)
print("Byte strings:", byte_strings)
print("Bytes:", byte_ints)
Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)
Bytes: tf.Tensor([ 68 117  99 107], shape=(4,), dtype=uint8)
# Or split it up as unicode and then decode it
unicode_bytes = tf.constant("アヒル 🦆")
unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, "UTF-8")
unicode_values = tf.strings.unicode_decode(unicode_bytes, "UTF-8")

print("\nUnicode bytes:", unicode_bytes)
print("\nUnicode chars:", unicode_char_bytes)
print("\nUnicode values:", unicode_values)
Unicode bytes: tf.Tensor(b'\xe3\x82\xa2\xe3\x83\x92\xe3\x83\xab \xf0\x9f\xa6\x86', shape=(), dtype=string)

Unicode chars: tf.Tensor([b'\xe3\x82\xa2' b'\xe3\x83\x92' b'\xe3\x83\xab' b' ' b'\xf0\x9f\xa6\x86'], shape=(5,), dtype=string)

Unicode values: tf.Tensor([ 12450  12498  12523     32 129414], shape=(5,), dtype=int32)

tf.string DTYPE используется для всех необработанных данных байт в TensorFlow. tf.io модуль содержит функции для преобразования данных в и из байт, включая декодирование изображений и разбор CSV.

Редкие тензоры

Иногда ваши данные разрежены, например, очень широкое пространство для встраивания. TensorFlow поддерживает tf.sparse.SparseTensor и связанные с ними операции для эффективного хранения разреженных данных.

tf.SparseTensor , форма: [3, 4]
Сетка 3x4 со значениями только в двух ячейках.
# Sparse tensors store values by index in a memory-efficient manner
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],
                                       values=[1, 2],
                                       dense_shape=[3, 4])
print(sparse_tensor, "\n")

# You can convert sparse tensors to dense
print(tf.sparse.to_dense(sparse_tensor))
SparseTensor(indices=tf.Tensor(
[[0 0]
 [1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64)) 

tf.Tensor(
[[1 0 0 0]
 [0 0 2 0]
 [0 0 0 0]], shape=(3, 4), dtype=int32)