Esta página foi traduzida pela API Cloud Translation.
Switch to English

Introdução aos tensores

Ver no TensorFlow.org Executar no Google Colab Ver fonte no GitHub Baixar caderno
import tensorflow as tf
import numpy as np

Os tensores são matrizes multidimensionais com um tipo uniforme (denominado dtype ). Você pode ver todos os dtypes suportados em tf.dtypes.DType .

Se você estiver familiarizado com o NumPy , os tensores são (mais ou menos) como np.arrays .

Todos os tensores são imutáveis ​​como os números e strings do Python: você nunca pode atualizar o conteúdo de um tensor, apenas criar um novo.

Fundamentos

Vamos criar alguns tensores básicos.

Aqui está um tensor "escalar" ou "categoria 0". Um escalar contém um único valor e nenhum "eixo".

# 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)

Um tensor de "vetor" ou "classificação 1" é como uma lista de valores. Um vetor tem 1 eixo:

# 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)

Um tensor de "matriz" ou "posto 2" tem 2 eixos:

# If we want to be specific, we 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)

Um escalar, forma: [] Um vetor, forma: [3] Uma matriz, forma: [3, 2]
Um escalar, o número 4A linha com 3 seções, cada uma contendo um número.Uma grade 3x2, com cada célula contendo um número.

Os tensores podem ter mais eixos, aqui está um tensor com 3 eixos:

# 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)

Existem muitas maneiras de visualizar um tensor com mais de 2 eixos.

Um tensor de 3 eixos, forma: [3, 2, 5]

Você pode converter um tensor em uma matriz NumPy usando np.array ou o método 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)

Os tensores geralmente contêm flutuadores e ints, mas têm muitos outros tipos, incluindo:

  • números complexos
  • cordas

A classe base tf.Tensor requer que os tensores sejam "retangulares" - isto é, ao longo de cada eixo, cada elemento tem o mesmo tamanho. No entanto, existem tipos especializados de tensores que podem lidar com diferentes formas:

Podemos fazer matemática básica em tensores, incluindo adição, multiplicação por elemento e multiplicação de matriz.

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) 


Tensores são usados ​​em todos os tipos de operações (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.3105860e-01]
 [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)

Sobre formas

Os tensores têm formas. Algum vocabulário:

  • Forma : O comprimento (número de elementos) de cada uma das dimensões de um tensor.
  • Rank : Número de dimensões do tensor. Um escalar tem posto 0, um vetor tem posto 1, uma matriz tem posto 2.
  • Eixo ou dimensão : uma dimensão particular de um tensor.
  • Tamanho : o número total de itens no tensor, o vetor de forma do produto

tf.TensorShape objetos tf.TensorShape e tf.TensorShape têm propriedades convenientes para acessá-los:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
Um tensor de classificação 4, forma: [3, 2, 4, 5]
Uma forma de tensor é como um vetor.Um tensor de 4 eixos
print("Type of every element:", rank_4_tensor.dtype)
print("Number of dimensions:", 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 dimensions: 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

Embora os eixos sejam freqüentemente referidos por seus índices, você deve sempre acompanhar o significado de cada um. Freqüentemente, os eixos são ordenados do global ao local: o eixo do lote primeiro, seguido pelas dimensões espaciais e recursos para cada local por último. Dessa forma, os vetores de recursos são regiões contíguas da memória.

Ordem típica do eixo
Acompanhe o que cada eixo é. Um tensor de 4 eixos pode ser: Lote, Largura, Altura, Freatures

Indexando

Indexação de eixo único

O TensorFlow segue as regras de indexação padrão do Python, semelhantes à indexação de uma lista ou string em Python , e as regras básicas para indexação NumPy.

  • índices começam em 0
  • índices negativos contam para trás a partir do final
  • dois pontos, : , são usados ​​para fatias: 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]

Indexar com um escalar remove a dimensão:

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

A indexação com um : slice mantém a dimensão:

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]

Indexação multi-eixo

Os tensores de classificação mais alta são indexados passando vários índices.

As mesmas regras de eixo único que no caso de eixo único se aplicam a cada eixo independentemente.

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

Passando um inteiro para cada índice, o resultado é um escalar.

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

Você pode indexar usando qualquer combinação de inteiros e fatias:

# 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.]] 


Aqui está um exemplo com um tensor de 3 eixos:

print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)

Seleção do último recurso em todos os locais em cada exemplo do lote
Um tensor 3x2x5 com todos os valores no índice 4 do último eixo selecionado.Os valores selecionados são compactados em um tensor de 2 eixos.

Manipulando formas

Remodelar um tensor é de grande utilidade.

# Shape returns a `TensorShape` object that shows the size on each dimension
var_x = tf.Variable(tf.constant([[1], [2], [3]]))
print(var_x.shape)
(3, 1)

# You can convert this object into a Python list, too
print(var_x.shape.as_list())
[3, 1]

Você pode remodelar um tensor em uma nova forma. A operação tf.reshape é rápida e barata, pois os dados subjacentes não precisam ser duplicados.

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

Os dados mantêm seu layout na memória e um novo tensor é criado, com a forma solicitada, apontando para os mesmos dados. O TensorFlow usa ordenação de memória "linha principal" estilo C, em que o incremento do índice mais à direita corresponde a uma única etapa na memória.

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)

Se você nivelar um tensor, poderá ver em que ordem ele está colocado na memória.

# 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)

Normalmente, os únicos usos razoáveis ​​de tf.reshape são combinar ou dividir eixos adjacentes (ou adicionar / remover 1 s).

Para este tensor 3x2x5, remodelar para (3x2) x5 ou 3x (2x5) são coisas razoáveis ​​a se fazer, já que as fatias não se misturam:

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)

Algumas boas remodelações.
Um tensor 3x2x5Os mesmos dados foram remodelados para (3x2) x5Os mesmos dados foram remodelados para 3x (2x5)

A remodelagem "funcionará" para qualquer nova forma com o mesmo número total de elementos, mas não fará nada de útil se você não respeitar a ordem dos eixos.

Trocar eixos em tf.reshape não funciona, você precisa de tf.transpose para isso.

# 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]

Algumas remodelações ruins.
Você não pode reordenar eixos, use tf.transpose para issoQualquer coisa que combine as fatias de dados provavelmente está errada.A nova forma deve se ajustar exatamente.

Você pode encontrar formas não totalmente especificadas. A forma contém um None (o comprimento da dimensão é desconhecido) ou a forma é None (a classificação do tensor é desconhecida).

Exceto para tf.RaggedTensor , essas formas só ocorrerão no contexto das APIs simbólicas de criação de gráficos do TensorFlow:

Mais sobre DTypes

Para inspecionar o tipo de dados de um tf.Tensor , use a propriedade Tensor.dtype .

Ao criar um tf.Tensor de um objeto Python, você pode opcionalmente especificar o tipo de dados.

Caso contrário, o TensorFlow escolhe um tipo de dados que pode representar seus dados. O TensorFlow converte inteiros Python em tf.int32 e números de ponto flutuante Python em tf.float32 . Caso contrário, o TensorFlow usa as mesmas regras que o NumPy usa ao converter para matrizes.

Você pode lançar de um tipo para outro.

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)

Transmissão

A transmissão é um conceito emprestado do recurso equivalente do NumPy . Resumindo, sob certas condições, tensores menores são "alongados" automaticamente para caber em tensores maiores ao executar operações combinadas neles.

O caso mais simples e comum é quando você tenta multiplicar ou adicionar um tensor a um escalar. Nesse caso, o escalar é transmitido para ter a mesma forma que o outro argumento.

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)

Da mesma forma, dimensões de 1 tamanho podem ser estendidas para corresponder aos outros argumentos. Ambos os argumentos podem ser estendidos na mesma computação.

Nesse caso, uma matriz 3x1 é multiplicada por elemento por uma matriz 1x4 para produzir uma matriz 3x4. Observe como o 1 inicial é opcional: A forma de y é [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)

Um anúncio transmitido: a [3, 1] vezes a [1, 4] dá a [3,4]
Adicionar uma matriz 3x1 a uma matriz 4x1 resulta em uma matriz 3x4

Aqui está a mesma operação sem transmissão:

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)

Na maioria das vezes, a transmissão é eficiente no tempo e no espaço, já que a operação de transmissão nunca materializa os tensores expandidos na memória.

Você vê a aparência da transmissão usando 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)

Ao contrário de uma operação matemática, por exemplo, broadcast_to não faz nada de especial para economizar memória. Aqui, você está materializando o tensor.

Isso pode ficar ainda mais complicado. Esta seção do livro de Jake VanderPlas, Python Data Science Handbook, mostra mais truques de transmissão (novamente em NumPy).

tf.convert_to_tensor

A maioria das operações, como tf.matmul e tf.reshape recebe argumentos da classe tf.Tensor . No entanto, você notará no caso acima, frequentemente passamos objetos Python em forma de tensores.

A maioria, mas não todos, os ops chamam convert_to_tensor em argumentos não tensores. Há um registro de conversões, e a maioria das classes de objetos, como ndarray , TensorShape , listas Python e tf.Variable , todas serão convertidas automaticamente.

Veja tf.register_tensor_conversion_function para mais detalhes, e se você tiver seu próprio tipo, gostaria de converter automaticamente para um tensor.

Tensores Ragged

Um tensor com número variável de elementos ao longo de algum eixo é chamado de "irregular". Use tf.ragged.RaggedTensor para dados irregulares.

Por exemplo, isto não pode ser representado como um tensor regular:

Um tf.RaggedTensor , forma: [4, None]
Um tensor irregular de 2 eixos, cada linha pode ter um comprimento diferente.
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.

Em vez disso, crie um tf.RaggedTensor usando 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]]>

A forma de um tf.RaggedTensor contém dimensões desconhecidas:

print(ragged_tensor.shape)
(4, None)

Tensores de corda

tf.string é um dtype , o que significa que podemos representar dados como strings (matrizes de bytes de comprimento variável) em tensores.

As strings são atômicas e não podem ser indexadas como as strings do Python. O comprimento da corda não é uma das dimensões do tensor. Veja tf.strings para funções para manipulá-los.

Aqui está um tensor de string escalar:

# 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)

E um vetor de strings:

Um vetor de cordas, forma: [3,]
O comprimento da corda não é um dos eixos do tensor.
# If we 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)

Na impressão acima, o prefixo b indica que tf.string dtype não é uma string Unicode, mas uma string de bytes. Consulte o Tutorial Unicode para mais informações sobre como trabalhar com texto Unicode no TensorFlow.

Se você passar caracteres Unicode, eles serão codificados em utf-8.

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

Algumas funções básicas com strings podem ser encontradas em tf.strings , incluindo tf.strings.split .

# We 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 we 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']]>

Três cordas divididas, forma: [3, None]
A divisão de várias strings retorna um tf.RaggedTensor

E 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)

Embora você não possa usar tf.cast para transformar um tensor de string em números, você pode convertê-lo em bytes e, em seguida, em números.

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)

O tf.string dtype é usado para todos os dados de bytes brutos no TensorFlow. O módulo tf.io contém funções para converter dados de e para bytes, incluindo a decodificação de imagens e análise de csv.

Tensores esparsos

Às vezes, seus dados são esparsos, como um espaço de incorporação muito amplo. O TensorFlow é compatível com tf.sparse.SparseTensor e operações relacionadas para armazenar dados esparsos com eficiência.

Um tf.SparseTensor , forma: [3, 4]
Uma grade 3x4, com valores em apenas duas das células.
# 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")

# We 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)