Trabalhando com tensores esparsos | TensorFlow Core
Trabalhando com tensores esparsos
Ao trabalhar com tensores que contêm muitos valores zero, é importante armazená-los de maneira eficiente em termos de espaço e tempo. Os tensores esparsos permitem o armazenamento e processamento eficientes de tensores que contêm muitos valores zero. Tensores esparsos são usados extensivamente em esquemas de codificação como TF-IDF como parte de pré-processamento de dados em aplicações de PNL e para imagens de pré-processamento com um monte de pixels escuros em aplicações de visão computacional.
Tensores esparsos no TensorFlow
TensorFlow representa tensores esparso através da tf.SparseTensor objecto. Atualmente, tensores esparsos no TensorFlow são codificados usando o formato de lista de coordenadas (COO). Este formato de codificação é otimizado para matrizes hiperesparsas, como embeddings.
A codificação COO para tensores esparsos é composta por:
values : A 1D tensor com forma [N] contendo todos os valores diferentes de zero.
indices : Um tensor de 2D com a forma [N, rank] , contendo os índices dos valores diferentes de zero.
dense_shape : Um 1D tensor com forma [rank] , especificando a forma do tensor.
Um valor diferente de zero no contexto de um tf.SparseTensor é um valor que não é codificado explicitamente. É possível incluir explicitamente os valores zero nos values de matriz de um COO escassos, mas estes "zeros explícitas" geralmente não são incluídos quando se refere a valores diferentes de zero em um tensor escassa.
Nota: tf.SparseTensor não requer que os índices / valores estar em qualquer ordem particular, mas várias ops assumir que eles estão em ordem da maior linha. Use tf.sparse.reorder para criar uma cópia do tensor esparsos que é classificada na ordem da maior linha canônica.
Criando um tf.SparseTensor
Construir tensores esparsas especificando diretamente sua values , indices e dense_shape .
Quando você usa o print() função para imprimir um tensor escassa, ele mostra o conteúdo dos três tensores de componentes:
É mais fácil de entender o conteúdo de um tensor escassa se os diferentes de zero values estão alinhados com seus correspondentes indices . Defina uma função auxiliar para imprimir tensores esparsos de forma que cada valor diferente de zero seja mostrado em sua própria linha.
Você também pode construir tensores esparsas de tensores densas usando tf.sparse.from_dense , e convertê-los de volta para tensores densas usando tf.sparse.to_dense .
Manipulando tensores esparsos
Utilizar os utilitários no tf.sparse pacote para manipular tensores esparsas. Ops como tf.math.add que você pode usar para manipulação aritmética dos tensores densas não funcionam com tensores esparsas.
Adicionar tensores esparsos da mesma forma usando tf.sparse.add .
Use tf.sparse.sparse_dense_matmul para tensores multiplicam esparsos com matrizes densas.
Coloque tensores esparsas juntos usando tf.sparse.concat e desmontá-los usando tf.sparse.slice .
Se você estiver usando TensorFlow 2.4 ou acima, use tf.sparse.map_values para operações elemento a elemento em valores diferentes de zero em tensores esparsas.
Observe que apenas os valores diferentes de zero foram modificados - os valores zero permanecem zero.
Da mesma forma, você pode seguir o padrão de design abaixo para versões anteriores do TensorFlow:
Usando tf.SparseTensor com outras APIs TensorFlow
Os tensores esparsos funcionam de forma transparente com estas APIs do TensorFlow:
Exemplos são mostrados abaixo para algumas das APIs acima.
Um subconjunto de tf.keras API suporta esparsas tensores sem caros de fundição ou de conversão ops. A API Keras permite que você passe tensores esparsos como entradas para um modelo Keras. Set sparse=True ao chamar tf.keras.Input ou tf.keras.layers.InputLayer . Você pode passar tensores esparsos entre as camadas Keras e também fazer com que os modelos Keras os retornem como saídas. Se você usar tensores esparsas no tf.keras.layers.Dense camadas no seu modelo, eles vão tensores densas de saída.
O exemplo abaixo mostra como passar um tensor esparso como uma entrada para um modelo Keras se você usar apenas camadas que suportam entradas esparsas.
array([[-1.3111044 , -1.7598825 ,  0.07225233, -0.44544357],
[ 0.8517609 , -0.16835624,  0.7307872 , -0.14531797],
[-0.8916302 , -0.9417639 ,  0.24563438, -0.9029659 ]],
O tf.data API permite construir dutos de entrada complexos de peças simples, reutilizáveis. A sua estrutura de dados de núcleo é tf.data.Dataset , que representa uma sequência de elementos em que cada elemento é constituído de um ou mais componentes.
Construindo conjuntos de dados com tensores esparsos
Construir a partir de conjuntos de dados tensores esparsos, utilizando os mesmos métodos que são usados para construir os de tf.Tensor matrizes s ou Numpy, tais como tf.data.Dataset.from_tensor_slices . Esta operação preserva a dispersão (ou natureza esparsa) dos dados.
Batching e unbatching datasets com tensores esparsos
Pode lote (combinar elementos consecutivos em um único elemento) e conjuntos de dados unbatch com tensores esparsos usando o Dataset.batch e Dataset.unbatch métodos respectivamente.
Você também pode usar tf.data.experimental.dense_to_sparse_batch a elementos do conjunto de dados de lote de formas variadas em tensores esparsas.
Transformando conjuntos de dados com tensores esparsos
Transformar e criar tensores esparsos em conjuntos de dados, utilizando Dataset.map .
tf.train.Example é uma codificação Protobuf padrão para dados TensorFlow. Ao usar tensores esparsos com tf.train.Example , você pode:
Ler os dados de comprimento variável para um tf.SparseTensor usando tf.io.VarLenFeature . No entanto, você deve considerar o uso tf.io.RaggedFeature vez.
Leia dados esparsos arbitrárias em um tf.SparseTensor usando tf.io.SparseFeature , que usa três teclas de funções separadas para armazenar os indices , values , e dense_shape .
Os tf.function precomputes decorador TensorFlow gráficos para funções Python, que pode melhorar substancialmente o desempenho do seu código TensorFlow. Tensores esparsas trabalhar de forma transparente tanto com tf.function e funções concretas .
Distinguir valores ausentes de valores zero
A maioria dos ops no tf.SparseTensor valores em falta tratar s e valores explícitos de zero de forma idêntica. Isso ocorre por design - um tf.SparseTensor é suposto para agir apenas como um tensor densa.
No entanto, existem alguns casos em que pode ser útil distinguir valores zero de valores ausentes. Em particular, isso permite uma maneira de codificar dados ausentes / desconhecidos em seus dados de treinamento. Por exemplo, considere um caso de uso onde você tem um tensor de pontuações (que pode ter qualquer valor de ponto flutuante de -Inf a + Inf), com algumas pontuações ausentes. Você pode codificar esse tensor usando um tensor esparso onde os zeros explícitos são pontuações zero conhecidas, mas os valores zero implícitos na verdade representam dados ausentes e não zero.
Nota: Este não é geralmente o uso pretendido de tf.SparseTensor s; e você também pode querer considerar outras técnicas para codificar isso, como, por exemplo, usar um tensor de máscara separado que identifica as localizações de valores conhecidos / desconhecidos. No entanto, tenha cuidado ao usar essa abordagem, uma vez que a maioria das operações esparsas tratará valores zero explícitos e implícitos de forma idêntica.
Note-se que alguns ops como tf.sparse.reduce_max não tratar valores ausentes como se fossem zero. Por exemplo, quando você executar o bloco de código abaixo, o resultado esperado é 0 . No entanto, devido a esta excepção, a saída é -3 .
Em contraste, quando você aplica tf.math.reduce_max a um tensor densa, a saída é 0 como esperado.
Consulte o guia tensor para aprender sobre tensores.
Leia o guia tensor irregular para aprender a trabalhar com tensores esfarrapados, um tipo de tensor que permite trabalhar com dados não-uniformes.
Confira este modelo de detecção de objeto no TensorFlow Modelo Garden que usa tensores esparsas em um tf.Example decodificador de dados .