Copyright 2020 The TensorFlow Authors.
Introdução aos tensores
Tensores são vetores multidimensionais com um tipo uniforme (chamado dtype
). Você pode ver todos os dtypes
suportados em tf.dtypes.DType
.
Se você estiver familiarizado com NumPy{:.external}, os tensores são (mais ou menos) como os np.arrays
.
Todos os tensores são imutáveis como números e strings do Python: você nunca pode atualizar o conteúdo de um tensor, apenas criar um novo.
Fundamentos
Primeiro, crie alguns tensores básicos.
Eis um "escalar", ou tensor de "posto 0". Um escalar contém um único valor e nenhum "eixo" (axis).
Um "vetor", ou tensor de "posto 1", é como uma lista de valores. Um vetor tem um eixo:
Uma "matriz", ou tensor de "posto 2" tem dois eixos:
Um escalar: formato: []
|
Um vetor, formato: [3]
|
Uma matriz, formato: [3, 2]
|
---|---|---|
![]() |


Tensores podem ter mais eixos (também chamados de dimensões). Eis aqui um tensor com três eixos:
Há diversas maneiras de visualizar um tensor com mais de dois eixos.
Um tensor de 3 eixos, formato: [3, 2, 5]
|
|
---|---|
![]() |
![]() |

Você pode converter um tensor para um array NumPy usando np.array
ou o método tensor.numpy
:
Os tensores geralmente contêm floats e ints, mas podem também conter muitos outros tipos, incluindo:
números complexos
strings
A classe base tf.Tensor
requer que os tensores sejam "retangulares", ou seja, que ao longo de cada eixo, cada elemento tenha o mesmo tamanho. No entanto, existem tipos especializados de tensores que podem lidar com diferentes formatos:
Tensores irregulares (veja RaggedTensor abaixo)
Tensores esparsos (veja SparseTensor abaixo)
Você pode realizar matemática básica com tensores, inclusive adição, multiplicação elemento a elemento e multiplicação matricial.
Tensores são usados em todos os tipos de operações (ou "ops").
Observação: normalmente, em qualquer lugar onde uma função do TensorFlow aceite um Tensor
como entrada, essa função também aceitará qualquer coisa que possa ser convertida num Tensor
usando tf.convert_to_tensor
. Veja abaixo um exemplo.
Sobre formatos
Os tensores têm formatos. Eis um breve glossário:
Formato: O comprimento (número de elementos) de cada um dos eixos de um tensor.
Posto: Número de eixos tensores. Um escalar tem posto 0, um vetor tem posto 1, uma matriz tem posto 2.
Eixo ou Dimensão: Uma dimensão específica de um tensor.
Tamanho: O número total de itens no tensor, o produto dos elementos do vetor de formato.
Observação: Embora você possa ver alguém se referir a um "tensor de duas dimensões", um tensor de posto 2 geralmente não descreve um espaço 2D.
Os objetos tensores e tf.TensorShape
têm propriedades convenientes para acessá-los:
Um tensor de posto 4, formato: [3, 2, 4, 5]
|
|
---|---|
![]() |
![]() |
Mas observe que os atributos Tensor.ndim
e Tensor.shape
não retornam objetos Tensor
. Se você precisar de um Tensor
use a função tf.rank
ou tf.shape
. Essa diferença é sutil, mas pode ser importante ao construir grafos (posteriormente).
Embora frequentemente nos referimos ao eixos pelos seus índices, você deve sempre acompanhar o significado de cada um. Freqüentemente, os eixos são ordenados de global para local: primeiro o eixo do lote, seguido pelas dimensões espaciais e por último as características de cada local. Dessa forma, os vetores de características serão regiões contíguas da memória.
Ordem típica dos eixos |
---|
![]() |
Indexação
Indexação de eixo único
O TensorFlow segue as regras de indexação padrão do Python, que são semelhantes à indexação de uma lista ou string em Python{:.external}, e as regras básicas para indexação do NumPy.
índices começam em
0
índices negativos contam de trás para frente a partir do final
dois pontos (
:
) são usados para separar fatias:start:stop:step
A indexação com um escalar remove o eixo:
A indexação com uma fatia :
mantém o eixo:
Indexação multieixo
Tensores de posto mais alto são indexados passando múltiplos índices.
As mesmas regras do caso de eixo único aplicam-se a cada eixo independentemente.
Passando um número inteiro para cada índice, o resultado será um escalar.
Você pode indexar usando qualquer combinação de números inteiros e fatias:
Eis um exemplo com um tensor de 3 eixos:
Selecionando a última característica em todos os locais em cada exemplo do lote | |
---|---|
![]() |
![]() |
Leia o guia de divisão de tensores para saber como aplicar a indexação para manipular elementos individuais em seus tensores.
Manipulação de formatos
A alteração do formato de um tensor é de grande utilidade.
Você pode mudar o formato de um tensor para que ele tenha um novo formato. A operação tf.reshape
faz isso de forma rápida e barata porque os dados subjacentes não precisam ser duplicados.
Os dados mantêm seu layout na memória e um novo tensor é criado, com o formato solicitado, apontando para os mesmos dados. O TensorFlow usa ordenação de memória "linha principal" (row-major) no estilo C, onde o incremento do índice mais à direita corresponde a uma única etapa na memória.
Se você achatar um tensor, poderá ver em que ordem ele está disposto na memória.
Normalmente, o único uso razoável de tf.reshape
é combinar ou dividir eixos adjacentes (ou adicionar/remover valores 1
).
Para este tensor 3x2x5, alterar o formato para (3x2)x5 ou 3x(2x5) são coisas razoáveis a serem feitas, já que as fatias não se misturam:
Algumas boas alterações de formato. | ||
---|---|---|
![]() |
![]() |
![]() |
A alteração de formato "funcionará" para qualquer novo formato 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.
Algumas alterações de formato ruins. | ||
---|---|---|
![]() |
![]() |
![]() |
Você poderá se deparar com formatos não totalmente especificados. Ou o formato contém um None
(o comprimento do eixo é desconhecido) ou todo o formato é None
(o posto do tensor é desconhecido).
Com exceção de tf.RaggedTensor, esses formatos ocorrerão apenas no contexto das APIs simbólicas de construção de grafos 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
a partir de um objeto Python, você pode opcionalmente especificar o tipo de dados.
Se você não fizer isso, o TensorFlow escolherá um tipo de dados que possa representar seus dados. O TensorFlow converte números inteiros do Python em tf.int32
e números de ponto flutuante do Python em tf.float32
. Caso contrário, o TensorFlow usará as mesmas regras que o NumPy usa ao converter em arrays.
Você pode fazer um cast de um tipo para outro.
Broadcasting
Broadcasting é um conceito emprestado do recurso equivalente em NumPy{:.external}. 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, é feito o broadcast do escalar para que ele tenha o mesmo formato do outro argumento.
Da mesma forma, eixos com comprimento 1 podem ser esticados para corresponder aos outros argumentos. Ambos os argumentos podem ser esticados na mesma computação.
Neste caso, uma matriz 3x1 é multiplicada elemento a elemento por uma matriz 1x4 para produzir uma matriz 3x4. Observe como o 1 inicial é opcional: O formato de y é [4]
.
Broadcast de uma adição: a [3, 1] vezes a [1, 4] produz [3,4]
|
---|
![]() |
Aqui está a mesma operação sem broadcasting:
Na maioria das vezes, o broadcasting é eficiente em termos de tempo e espaço, pois a operação de broadcasting nunca materializa os tensores expandidos na memória.
Você pode ver como vai ficar o broadcast usando tf.broadcast_to
.
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.
Pode ficar ainda mais complicado. Esta seção{:.external} do livro Python Data Science Handbook de Jake VanderPlas mostra mais truques de broadcasting (novamente usando NumPy).
tf.convert_to_tensor
A maioria das ops, como tf.matmul
e tf.reshape
aceitam argumentos da classe tf.Tensor
. No entanto, você notará que no caso acima, objetos Python em forma de tensores são aceitos.
A maioria, mas não todas as operações 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
do NumPy, serão convertidas automaticamente.
Veja tf.register_tensor_conversion_function
para mais detalhes e, se você tiver seu próprio tipo que gostaria de converter automaticamente em um tensor.
Tensores irregulares
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`, formato: [4, None]
|
---|
![]() |
Em vez disso, crie um tf.RaggedTensor
usando tf.ragged.constant
:
O formato de um tf.RaggedTensor
conterá alguns eixos com comprimentos desconhecidos:
Tensores de string
tf.string
é um dtype
, o que significa que você pode representar dados como strings (arrays de bytes de comprimento variável) em tensores.
Strings são atômicas e não podem ser indexadas da mesma forma que as strings do Python. O comprimento da string não é um dos eixos do tensor. Veja tf.strings
para conhecer funções para manipulá-las.
Aqui está um tensor de strings escalar:
E um vetor de strings:
Um vetor de strings, formato: [3,]
|
---|
![]() |
Na listagem acima, o prefixo b
indica que o dtype tf.string
não é uma string unicode, mas uma string de bytes. Consulte o Tutorial Unicode para saber mais sobre como trabalhar com texto Unicode no TensorFlow.
Se você passar caracteres Unicode, eles serão codificados em utf-8.
Algumas funções básicas com strings podem ser encontradas em tf.strings
, incluindo tf.strings.split
.
Split de três strings, formato: [3, None]
|
---|
![]() |
E tf.strings.to_number
:
Embora você não possa usar tf.cast
para transformar um tensor de string em números, você pode convertê-lo em bytes e depois em números.
O dtype tf.string
é 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, inclusive decodificação de imagens e processamento de CSV.
Tensores esparsos
Às vezes, seus dados são esparsos, como um espaço de embedding muito largo. O TensorFlow oferece suporte a tf.sparse.SparseTensor
e operações relacionadas para armazenar dados esparsos com eficiência.
Um `tf.SparseTensor`, formato: [3, 4]
|
---|
![]() |