|
79 | 79 | "source": [
|
80 | 80 | "## Sparse tensors in TensorFlow\n",
|
81 | 81 | "\n",
|
82 |
| - "TensorFlow represents sparse tensors through the `tf.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.\n", |
| 82 | + "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.\n", |
83 | 83 | "\n",
|
84 | 84 | "The COO encoding for sparse tensors is comprised of:\n",
|
85 | 85 | "\n",
|
86 | 86 | " * `values`: A 1D tensor with shape `[N]` containing all nonzero values.\n",
|
87 | 87 | " * `indices`: A 2D tensor with shape `[N, rank]`, containing the indices of the nonzero values.\n",
|
88 | 88 | " * `dense_shape`: A 1D tensor with shape `[rank]`, specifying the shape of the tensor.\n",
|
89 | 89 | "\n",
|
90 |
| - "A ***nonzero*** value in the context of a `tf.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.\n", |
| 90 | + "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.\n", |
91 | 91 | "\n",
|
92 |
| - "Note: `tf.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. " |
| 92 | + "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. " |
93 | 93 | ]
|
94 | 94 | },
|
95 | 95 | {
|
|
98 | 98 | "id": "6Aq7ruwlyz79"
|
99 | 99 | },
|
100 | 100 | "source": [
|
101 |
| - "## Creating a `tf.SparseTensor`\n", |
| 101 | + "## Creating a `tf.sparse.SparseTensor`\n", |
102 | 102 | "\n",
|
103 | 103 | "Construct sparse tensors by directly specifying their `values`, `indices`, and `dense_shape`."
|
104 | 104 | ]
|
|
122 | 122 | },
|
123 | 123 | "outputs": [],
|
124 | 124 | "source": [
|
125 |
| - "st1 = tf.SparseTensor(indices=[[0, 3], [2, 4]],\n", |
| 125 | + "st1 = tf.sparse.SparseTensor(indices=[[0, 3], [2, 4]],\n", |
126 | 126 | " values=[10, 20],\n",
|
127 | 127 | " dense_shape=[3, 10])"
|
128 | 128 | ]
|
|
252 | 252 | },
|
253 | 253 | "outputs": [],
|
254 | 254 | "source": [
|
255 |
| - "st_a = tf.SparseTensor(indices=[[0, 2], [3, 4]],\n", |
| 255 | + "st_a = tf.sparse.SparseTensor(indices=[[0, 2], [3, 4]],\n", |
256 | 256 | " values=[31, 2], \n",
|
257 | 257 | " dense_shape=[4, 10])\n",
|
258 | 258 | "\n",
|
259 |
| - "st_b = tf.SparseTensor(indices=[[0, 2], [7, 0]],\n", |
| 259 | + "st_b = tf.sparse.SparseTensor(indices=[[0, 2], [7, 0]],\n", |
260 | 260 | " values=[56, 38],\n",
|
261 | 261 | " dense_shape=[4, 10])\n",
|
262 | 262 | "\n",
|
|
282 | 282 | },
|
283 | 283 | "outputs": [],
|
284 | 284 | "source": [
|
285 |
| - "st_c = tf.SparseTensor(indices=([0, 1], [1, 0], [1, 1]),\n", |
| 285 | + "st_c = tf.sparse.SparseTensor(indices=([0, 1], [1, 0], [1, 1]),\n", |
286 | 286 | " values=[13, 15, 17],\n",
|
287 | 287 | " dense_shape=(2,2))\n",
|
288 | 288 | "\n",
|
|
309 | 309 | },
|
310 | 310 | "outputs": [],
|
311 | 311 | "source": [
|
312 |
| - "sparse_pattern_A = tf.SparseTensor(indices = [[2,4], [3,3], [3,4], [4,3], [4,4], [5,4]],\n", |
| 312 | + "sparse_pattern_A = tf.sparse.SparseTensor(indices = [[2,4], [3,3], [3,4], [4,3], [4,4], [5,4]],\n", |
313 | 313 | " values = [1,1,1,1,1,1],\n",
|
314 | 314 | " dense_shape = [8,5])\n",
|
315 |
| - "sparse_pattern_B = tf.SparseTensor(indices = [[0,2], [1,1], [1,3], [2,0], [2,4], [2,5], [3,5], \n", |
| 315 | + "sparse_pattern_B = tf.sparse.SparseTensor(indices = [[0,2], [1,1], [1,3], [2,0], [2,4], [2,5], [3,5], \n", |
316 | 316 | " [4,5], [5,0], [5,4], [5,5], [6,1], [6,3], [7,2]],\n",
|
317 | 317 | " values = [1,1,1,1,1,1,1,1,1,1,1,1,1,1],\n",
|
318 | 318 | " dense_shape = [8,6])\n",
|
319 |
| - "sparse_pattern_C = tf.SparseTensor(indices = [[3,0], [4,0]],\n", |
| 319 | + "sparse_pattern_C = tf.sparse.SparseTensor(indices = [[3,0], [4,0]],\n", |
320 | 320 | " values = [1,1],\n",
|
321 | 321 | " dense_shape = [8,6])\n",
|
322 | 322 | "\n",
|
|
381 | 381 | },
|
382 | 382 | "outputs": [],
|
383 | 383 | "source": [
|
384 |
| - "st2_plus_5 = tf.SparseTensor(\n", |
| 384 | + "st2_plus_5 = tf.sparse.SparseTensor(\n", |
385 | 385 | " st2.indices,\n",
|
386 | 386 | " st2.values + 5,\n",
|
387 | 387 | " st2.dense_shape)\n",
|
|
394 | 394 | "id": "GFhO2ZZ53ga1"
|
395 | 395 | },
|
396 | 396 | "source": [
|
397 |
| - "## Using `tf.SparseTensor` with other TensorFlow APIs\n", |
| 397 | + "## Using `tf.sparse.SparseTensor` with other TensorFlow APIs\n", |
398 | 398 | "\n",
|
399 | 399 | "Sparse tensors work transparently with these TensorFlow APIs:\n",
|
400 | 400 | "\n",
|
|
449 | 449 | "y = tf.keras.layers.Dense(4)(x)\n",
|
450 | 450 | "model = tf.keras.Model(x, y)\n",
|
451 | 451 | "\n",
|
452 |
| - "sparse_data = tf.SparseTensor(\n", |
| 452 | + "sparse_data = tf.sparse.SparseTensor(\n", |
453 | 453 | " indices = [(0,0),(0,1),(0,2),\n",
|
454 | 454 | " (4,3),(5,0),(5,1)],\n",
|
455 | 455 | " values = [1,1,1,1,1,1],\n",
|
|
569 | 569 | "\n",
|
570 | 570 | "`tf.train.Example` is a standard protobuf encoding for TensorFlow data. When using sparse tensors with `tf.train.Example`, you can:\n",
|
571 | 571 | "\n",
|
572 |
| - "* Read variable-length data into a `tf.SparseTensor` using `tf.io.VarLenFeature`. However, you should consider using `tf.io.RaggedFeature` instead.\n", |
| 572 | + "* Read variable-length data into a `tf.sparse.SparseTensor` using `tf.io.VarLenFeature`. However, you should consider using `tf.io.RaggedFeature` instead.\n", |
573 | 573 | "\n",
|
574 |
| - "* Read arbitrary sparse data into a `tf.SparseTensor` using `tf.io.SparseFeature`, which uses three separate feature keys to store the `indices`, `values`, and `dense_shape`." |
| 574 | + "* Read arbitrary sparse data into a `tf.sparse.SparseTensor` using `tf.io.SparseFeature`, which uses three separate feature keys to store the `indices`, `values`, and `dense_shape`." |
575 | 575 | ]
|
576 | 576 | },
|
577 | 577 | {
|
|
597 | 597 | "def f(x,y):\n",
|
598 | 598 | " return tf.sparse.sparse_dense_matmul(x,y)\n",
|
599 | 599 | "\n",
|
600 |
| - "a = tf.SparseTensor(indices=[[0, 3], [2, 4]],\n", |
| 600 | + "a = tf.sparse.SparseTensor(indices=[[0, 3], [2, 4]],\n", |
601 | 601 | " values=[15, 25],\n",
|
602 | 602 | " dense_shape=[3, 10])\n",
|
603 | 603 | "\n",
|
|
616 | 616 | "source": [
|
617 | 617 | "## Distinguishing missing values from zero values\n",
|
618 | 618 | "\n",
|
619 |
| - "Most ops on `tf.SparseTensor`s treat missing values and explicit zero values identically. This is by design — a `tf.SparseTensor` is supposed to act just like a dense tensor.\n", |
| 619 | + "Most ops on `tf.sparse.SparseTensor`s 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.\n", |
620 | 620 | "\n",
|
621 | 621 | "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. \n",
|
622 | 622 | "\n",
|
623 |
| - "Note: This is generally not the intended usage of `tf.SparseTensor`s; 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." |
| 623 | + "Note: This is generally not the intended usage of `tf.sparse.SparseTensor`s; 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." |
624 | 624 | ]
|
625 | 625 | },
|
626 | 626 | {
|
|
680 | 680 | "metadata": {
|
681 | 681 | "colab": {
|
682 | 682 | "collapsed_sections": [],
|
683 |
| - "name": "sparse_tensor_guide.ipynb", |
684 |
| - "provenance": [], |
| 683 | + "name": "sparse_tensor.ipynb", |
685 | 684 | "toc_visible": true
|
686 | 685 | },
|
687 | 686 | "kernelspec": {
|
|
0 commit comments