Path: blob/master/site/en-snapshot/guide/sparse_tensor.ipynb
38523 views
Copyright 2020 The TensorFlow Authors.
Working with sparse tensors
When working with tensors that contain a lot of zero values, it is important to store them in a space- and time-efficient manner. Sparse tensors enable efficient storage and processing of tensors that contain a lot of zero values. Sparse tensors are used extensively in encoding schemes like TF-IDF as part of data pre-processing in NLP applications and for pre-processing images with a lot of dark pixels in computer vision applications.
Sparse tensors in TensorFlow
TensorFlow represents sparse tensors through the tf.sparse.SparseTensor object. Currently, sparse tensors in TensorFlow are encoded using the coordinate list (COO) format. This encoding format is optimized for hyper-sparse matrices such as embeddings.
The COO encoding for sparse tensors is comprised of:
values: A 1D tensor with shape[N]containing all nonzero values.indices: A 2D tensor with shape[N, rank], containing the indices of the nonzero values.dense_shape: A 1D tensor with shape[rank], specifying the shape of the tensor.
A nonzero value in the context of a tf.sparse.SparseTensor is a value that's not explicitly encoded. It is possible to explicitly include zero values in the values of a COO sparse matrix, but these "explicit zeros" are generally not included when referring to nonzero values in a sparse tensor.
Note: tf.sparse.SparseTensor does not require that indices/values be in any particular order, but several ops assume that they're in row-major order. Use tf.sparse.reorder to create a copy of the sparse tensor that is sorted in the canonical row-major order.
Creating a tf.sparse.SparseTensor
Construct sparse tensors by directly specifying their values, indices, and dense_shape.

When you use the print() function to print a sparse tensor, it shows the contents of the three component tensors:
It is easier to understand the contents of a sparse tensor if the nonzero values are aligned with their corresponding indices. Define a helper function to pretty-print sparse tensors such that each nonzero value is shown on its own line.
You can also construct sparse tensors from dense tensors by using tf.sparse.from_dense, and convert them back to dense tensors by using tf.sparse.to_dense.
Manipulating sparse tensors
Use the utilities in the tf.sparse package to manipulate sparse tensors. Ops like tf.math.add that you can use for arithmetic manipulation of dense tensors do not work with sparse tensors.
Add sparse tensors of the same shape by using tf.sparse.add.
Use tf.sparse.sparse_dense_matmul to multiply sparse tensors with dense matrices.
Put sparse tensors together by using tf.sparse.concat and take them apart by using tf.sparse.slice.
If you're using TensorFlow 2.4 or above, use tf.sparse.map_values for elementwise operations on nonzero values in sparse tensors.
Note that only the nonzero values were modified – the zero values stay zero.
Equivalently, you can follow the design pattern below for earlier versions of TensorFlow:
Using tf.sparse.SparseTensor with other TensorFlow APIs
Sparse tensors work transparently with these TensorFlow APIs:
tf.kerastf.datatf.Train.Exampleprotobuftf.functiontf.while_looptf.condtf.identitytf.casttf.printtf.saved_modeltf.io.serialize_sparsetf.io.serialize_many_sparsetf.io.deserialize_many_sparsetf.math.abstf.math.negativetf.math.signtf.math.squaretf.math.sqrttf.math.erftf.math.tanhtf.math.bessel_i0etf.math.bessel_i1e
Examples are shown below for a few of the above APIs.
tf.keras
A subset of the tf.keras API supports sparse tensors without expensive casting or conversion ops. The Keras API lets you pass sparse tensors as inputs to a Keras model. Set sparse=True when calling tf.keras.Input or tf.keras.layers.InputLayer. You can pass sparse tensors between Keras layers, and also have Keras models return them as outputs. If you use sparse tensors in tf.keras.layers.Dense layers in your model, they will output dense tensors.
The example below shows you how to pass a sparse tensor as an input to a Keras model if you use only layers that support sparse inputs.
tf.data
The tf.data API enables you to build complex input pipelines from simple, reusable pieces. Its core data structure is tf.data.Dataset, which represents a sequence of elements in which each element consists of one or more components.
Building datasets with sparse tensors
Build datasets from sparse tensors using the same methods that are used to build them from tf.Tensors or NumPy arrays, such as tf.data.Dataset.from_tensor_slices. This op preserves the sparsity (or sparse nature) of the data.
Batching and unbatching datasets with sparse tensors
You can batch (combine consecutive elements into a single element) and unbatch datasets with sparse tensors using the Dataset.batch and Dataset.unbatch methods respectively.
You can also use tf.data.experimental.dense_to_sparse_batch to batch dataset elements of varying shapes into sparse tensors.
Transforming Datasets with sparse tensors
Transform and create sparse tensors in Datasets using Dataset.map.
tf.train.Example
tf.train.Example is a standard protobuf encoding for TensorFlow data. When using sparse tensors with tf.train.Example, you can:
Read variable-length data into a
tf.sparse.SparseTensorusingtf.io.VarLenFeature. However, you should consider usingtf.io.RaggedFeatureinstead.Read arbitrary sparse data into a
tf.sparse.SparseTensorusingtf.io.SparseFeature, which uses three separate feature keys to store theindices,values, anddense_shape.
tf.function
The tf.function decorator precomputes TensorFlow graphs for Python functions, which can substantially improve the performance of your TensorFlow code. Sparse tensors work transparently with both tf.function and concrete functions.
Distinguishing missing values from zero values
Most ops on tf.sparse.SparseTensors treat missing values and explicit zero values identically. This is by design — a tf.sparse.SparseTensor is supposed to act just like a dense tensor.
However, there are a few cases where it can be useful to distinguish zero values from missing values. In particular, this allows for one way to encode missing/unknown data in your training data. For example, consider a use case where you have a tensor of scores (that can have any floating point value from -Inf to +Inf), with some missing scores. You can encode this tensor using a sparse tensor where the explicit zeros are known zero scores but the implicit zero values actually represent missing data and not zero.
Note: This is generally not the intended usage of tf.sparse.SparseTensors; and you might want to also consier other techniques for encoding this such as for example using a separate mask tensor that identifies the locations of known/unknown values. However, exercise caution while using this approach, since most sparse operations will treat explicit and implicit zero values identically.
Note that some ops like tf.sparse.reduce_max do not treat missing values as if they were zero. For example, when you run the code block below, the expected output is 0. However, because of this exception, the output is -3.
In contrast, when you apply tf.math.reduce_max to a dense tensor, the output is 0 as expected.
Further reading and resources
Refer to the tensor guide to learn about tensors.
Read the ragged tensor guide to learn how to work with ragged tensors, a type of tensor that lets you work with non-uniform data.
Check out this object detection model in the TensorFlow Model Garden that uses sparse tensors in a
tf.Exampledata decoder.
View on TensorFlow.org
Run in Google Colab
View on GitHub
Download notebook