O Dia da Comunidade de ML é dia 9 de novembro! Junte-nos para atualização de TensorFlow, JAX, e mais Saiba mais

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

Tensores são matrizes multi-dimensionais com um tipo uniforme (chamado um dtype ). Você pode ver todos suportados dtypes em tf.dtypes.DType .

Se você estiver familiarizado com NumPy , tensores são (tipo de) 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 possui um 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 dois eixos:

# 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)
Um escalar, forma: [] Um vector, 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 três 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 dois eixos.

A 3-eixo tensor, forma: [3, 2, 5]

Você pode converter um tensor para uma matriz NumPy ou usando np.array ou o tensor.numpy método:

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 base tf.Tensor classe requer tensores para ser "rectangular" --- isto é, ao longo de cada eixo, cada elemento é o mesmo tamanho. No entanto, existem tipos especializados de tensores que podem lidar com diferentes formas:

Você pode 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)

Os 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.3105854e-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 um dos eixos de um tensor.
  • Classificação: número de eixos do tensor. Um escalar tem posto 0, um vetor tem posto 1, uma matriz tem posto 2.
  • Eixo ou Dimensão: A dimensão particular de um tensor.
  • Tamanho: O número total de itens no tensor, o vetor forma do produto.

Tensores e tf.TensorShape objetos têm propriedades convenientes para aceder a estes:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
Uma classificação de 4-tensor, 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 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

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, recursos

Indexando

Indexação de eixo único

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

  • índices iniciar a 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]

A indexação com um escalar remove o eixo:

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

Indexando com um : fatia mantém o eixo:

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 exatas no caso de um eixo se aplicam a cada eixo independentemente.

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

Passando um número 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.

Leia o guia de corte tensor para saber como você pode aplicar a indexação de manipular elementos individuais em seus tensores.

Manipulando formas

Remodelar um tensor é de grande utilidade.

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

Você pode remodelar um tensor em uma nova forma. O tf.reshape operação é rápida e barata como os dados subjacentes não precisa ser duplicada.

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

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 a única utilização razoável de tf.reshape é combinar ou dividir os 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, pois 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 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 os 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. De qualquer forma contém uma None (de um eixo de comprimento é desconhecida) ou a forma inteira é None (a classificação do tensor é desconhecido).

Exceto para tf.RaggedTensor , tais formas só ocorrerá no contexto de APIs simbólicos, construção de gráfico de TensorFlow:

Mais sobre DTypes

Para inspecionar uma tf.Tensor tipo de dados uso do Tensor.dtype propriedade.

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

Caso contrário, o TensorFlow escolhe um tipo de dados que pode representar seus dados. TensorFlow converte inteiros Python para tf.int32 e Python números de ponto flutuante para tf.float32 . Caso contrário, o TensorFlow usa as mesmas regras que o NumPy usa ao converter em 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

Broadcasting é um conceito emprestado do recurso equivalente no NumPy . Em suma, sob certas condições, tensores menores são "esticados" 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, os eixos com comprimento 1 podem ser alongados 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. Nota como a principal 1 é 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 suplemento transmitido: a [3, 1] vezes por [1, 4] dá uma [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, pois a operação de transmissão nunca materializa os tensores expandidos na memória.

Você vê o que transmitindo aparência como usar 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 um op matemática, por exemplo, broadcast_to não faz nada especial para poupar memória. Aqui, você está materializando o tensor.

Isso pode ficar ainda mais complicado. Esta seção do livro de Jake VanderPlas Python Dados Ciência Handbook mostra mais transmitindo truques (novamente em NumPy).

tf.convert_to_tensor

A maioria dos ops, como tf.matmul e tf.reshape ter argumentos de classe tf.Tensor . No entanto, você notará no caso acima, objetos Python em forma de tensores são aceitos.

A maioria, mas não todos, ops chamar convert_to_tensor em argumentos não-tensores. Há um registro de conversões, ea maioria das classes de objetos como do NumPy ndarray , TensorShape , listas de Python, e tf.Variable tudo vai converter automaticamente.

Veja tf.register_tensor_conversion_function para mais detalhes, e se você tem o seu próprio tipo que você gostaria de converter automaticamente a 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 irregular.

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 criar 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 conterá alguns eixos com comprimentos desconhecidos:

print(ragged_tensor.shape)
(4, None)

Tensores de corda

tf.string é um dtype , o que quer dizer que você pode representar dados como strings (de comprimento variável byte matrizes) 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 é um dos eixos do tensor. Veja tf.strings para funções de 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 cordas:

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

Na impressão acima da b prefixo indica que tf.string dtipo não é uma cadeia Unicode, mas um byte-corda. Veja o Tutorial Unicode para mais sobre como trabalhar com texto unicode em 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 cordas podem ser encontrados em tf.strings , incluindo 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']]>
Divisão de três cordas, 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 pode usar tf.cast para transformar um tensor string em números, você pode convertê-lo em bytes, e depois 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 dtipo é usado para todos os bytes de dados não processados em TensorFlow. O tf.io módulo contém funções para a conversão de dados de e para bytes, incluindo imagens de descodificação e analisar CSV.

Tensores esparsos

Às vezes, seus dados são esparsos, como um espaço de incorporação muito amplo. TensorFlow suporta tf.sparse.SparseTensor e operações afins para armazenar dados esparsos de forma eficiente.

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

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