HTTP/2 200
content-type: application/octet-stream
x-guploader-uploadid: ABgVH8-iR4yuamsTQOEQ4cARS8WtatWhs6MTprJWP8nLYO9VvBCR6L-fsExkOLTRN2sY5O8JJvMOEtY
expires: Sat, 19 Jul 2025 09:25:37 GMT
date: Sat, 19 Jul 2025 08:25:37 GMT
cache-control: public, max-age=3600
last-modified: Thu, 15 Aug 2024 03:16:08 GMT
etag: "a303ef9c5a67b98b1a72efb4fe644d45"
x-goog-generation: 1723691767927877
x-goog-metageneration: 1
x-goog-stored-content-encoding: identity
x-goog-stored-content-length: 38187
x-goog-hash: crc32c=RxH52Q==
x-goog-hash: md5=owPvnFpnuYsacu+0/mRNRQ==
x-goog-storage-class: MULTI_REGIONAL
accept-ranges: bytes
content-length: 38187
server: UploadServer
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "Tce3stUlHN0L"
},
"source": [
"##### Copyright 2020 The TensorFlow Authors."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2024-08-15T02:59:22.123211Z",
"iopub.status.busy": "2024-08-15T02:59:22.122612Z",
"iopub.status.idle": "2024-08-15T02:59:22.126635Z",
"shell.execute_reply": "2024-08-15T02:59:22.125975Z"
},
"id": "tuOe1ymfHZPu"
},
"outputs": [],
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VZ-KA8k5kybx"
},
"source": [
"# Introduction to tensor slicing"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MfBg1C5NB3X0"
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AixIdVeRk3CO"
},
"source": [
"When working on ML applications such as object detection and NLP, it is sometimes necessary to work with sub-sections (slices) of tensors. For example, if your model architecture includes routing, where one layer might control which training example gets routed to the next layer. In this case, you could use tensor slicing ops to split the tensors up and put them back together in the right order.\n",
"\n",
"In NLP applications, you can use tensor slicing to perform word masking while training. For example, you can generate training data from a list of sentences by choosing a word index to mask in each sentence, taking the word out as a label, and then replacing the chosen word with a mask token. \n",
"\n",
"In this guide, you will learn how to use the TensorFlow APIs to:\n",
"\n",
"* Extract slices from a tensor\n",
"* Insert data at specific indices in a tensor\n",
"\n",
"This guide assumes familiarity with tensor indexing. Read the indexing sections of the [Tensor](https://www.tensorflow.org/guide/tensor#indexing) and [TensorFlow NumPy](https://www.tensorflow.org/guide/tf_numpy#indexing) guides before getting started with this guide."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FcWhWYn7eXkF"
},
"source": [
"## Setup\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:22.130292Z",
"iopub.status.busy": "2024-08-15T02:59:22.129698Z",
"iopub.status.idle": "2024-08-15T02:59:24.484003Z",
"shell.execute_reply": "2024-08-15T02:59:24.483309Z"
},
"id": "m6uvewqi0jso"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-08-15 02:59:22.387959: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:485] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
"2024-08-15 02:59:22.409014: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:8454] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
"2024-08-15 02:59:22.415391: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1452] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "K-muS4ej5zoN"
},
"source": [
"## Extract tensor slices\n",
"\n",
"Perform NumPy-like tensor slicing using `tf.slice`.\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:24.488540Z",
"iopub.status.busy": "2024-08-15T02:59:24.488182Z",
"iopub.status.idle": "2024-08-15T02:59:26.716102Z",
"shell.execute_reply": "2024-08-15T02:59:26.715372Z"
},
"id": "wZep0cjs0Oai"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([1 2 3], shape=(3,), dtype=int32)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
"I0000 00:00:1723690765.029742 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.033507 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.037154 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.040869 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.052765 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.056359 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.059719 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.063138 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.066532 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.070040 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.073650 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690765.077235 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.300773 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.302797 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.304766 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.306851 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.308843 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.310723 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.312589 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.314574 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.316423 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.318291 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.320168 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.322150 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.360968 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.362946 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.364849 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.366867 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.368710 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.370591 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.372447 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.374435 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.376302 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.378677 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.380966 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n",
"I0000 00:00:1723690766.383365 169903 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355\n"
]
}
],
"source": [
"t1 = tf.constant([0, 1, 2, 3, 4, 5, 6, 7])\n",
"\n",
"print(tf.slice(t1,\n",
" begin=[1],\n",
" size=[3]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Vh3xI3j0DRJ2"
},
"source": [
"Alternatively, you can use a more Pythonic syntax. Note that tensor slices are evenly spaced over a start-stop range."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.719473Z",
"iopub.status.busy": "2024-08-15T02:59:26.719229Z",
"iopub.status.idle": "2024-08-15T02:59:26.724625Z",
"shell.execute_reply": "2024-08-15T02:59:26.723996Z"
},
"id": "P1MtEyKuWuDD"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([1 2 3], shape=(3,), dtype=int32)\n"
]
}
],
"source": [
"print(t1[1:4])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cjq1o8D2wKKs"
},
"source": [
"

"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.727843Z",
"iopub.status.busy": "2024-08-15T02:59:26.727398Z",
"iopub.status.idle": "2024-08-15T02:59:26.732360Z",
"shell.execute_reply": "2024-08-15T02:59:26.731768Z"
},
"id": "UunuLTIuwDA-"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([5 6 7], shape=(3,), dtype=int32)\n"
]
}
],
"source": [
"print(t1[-3:])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EHvRB-XTwRTd"
},
"source": [
"

"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SW1zFFTnUpCQ"
},
"source": [
"For 2-dimensional tensors,you can use something like:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.735715Z",
"iopub.status.busy": "2024-08-15T02:59:26.735147Z",
"iopub.status.idle": "2024-08-15T02:59:26.741016Z",
"shell.execute_reply": "2024-08-15T02:59:26.740443Z"
},
"id": "kThZhmpAVAQw"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[ 1 2]\n",
" [ 6 7]\n",
" [11 12]], shape=(3, 2), dtype=int32)\n"
]
}
],
"source": [
"t2 = tf.constant([[0, 1, 2, 3, 4],\n",
" [5, 6, 7, 8, 9],\n",
" [10, 11, 12, 13, 14],\n",
" [15, 16, 17, 18, 19]])\n",
"\n",
"print(t2[:-1, 1:3])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xA5Xt4OdVUui"
},
"source": [
"

"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "iJPggqsH15fI"
},
"source": [
"You can use `tf.slice` on higher dimensional tensors as well."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.744224Z",
"iopub.status.busy": "2024-08-15T02:59:26.743760Z",
"iopub.status.idle": "2024-08-15T02:59:26.748681Z",
"shell.execute_reply": "2024-08-15T02:59:26.748101Z"
},
"id": "Re5eX1OXnKOZ"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([[[25 27]]], shape=(1, 1, 2), dtype=int32)\n"
]
}
],
"source": [
"t3 = tf.constant([[[1, 3, 5, 7],\n",
" [9, 11, 13, 15]],\n",
" [[17, 19, 21, 23],\n",
" [25, 27, 29, 31]]\n",
" ])\n",
"\n",
"print(tf.slice(t3,\n",
" begin=[1, 1, 0],\n",
" size=[1, 1, 2]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "x-O5FNV9qOJK"
},
"source": [
"You can also use `tf.strided_slice` to extract slices of tensors by 'striding' over the tensor dimensions."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "b9FhvrOnJsJb"
},
"source": [
"Use `tf.gather` to extract specific indices from a single axis of a tensor."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.751912Z",
"iopub.status.busy": "2024-08-15T02:59:26.751461Z",
"iopub.status.idle": "2024-08-15T02:59:26.773755Z",
"shell.execute_reply": "2024-08-15T02:59:26.773193Z"
},
"id": "TwviZrrIj2h7"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([0 3 6], shape=(3,), dtype=int32)\n"
]
},
{
"data": {
"text/plain": [
"
"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(tf.gather(t1,\n",
" indices=[0, 3, 6]))\n",
"\n",
"# This is similar to doing\n",
"\n",
"t1[::3]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oKyjGi2zyzEC"
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "obrjeKy1WfTN"
},
"source": [
"`tf.gather` does not require indices to be evenly spaced."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.777232Z",
"iopub.status.busy": "2024-08-15T02:59:26.776618Z",
"iopub.status.idle": "2024-08-15T02:59:26.782573Z",
"shell.execute_reply": "2024-08-15T02:59:26.781874Z"
},
"id": "LjJcwcZ0druw"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([b'c' b'a' b't' b's'], shape=(4,), dtype=string)\n"
]
}
],
"source": [
"alphabet = tf.constant(list('abcdefghijklmnopqrstuvwxyz'))\n",
"\n",
"print(tf.gather(alphabet,\n",
" indices=[2, 0, 19, 18]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mSHmUXIyeaJG"
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XsxMx49SOaVu"
},
"source": [
"To extract slices from multiple axes of a tensor, use `tf.gather_nd`. This is useful when you want to gather the elements of a matrix as opposed to just its rows or columns."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.785915Z",
"iopub.status.busy": "2024-08-15T02:59:26.785305Z",
"iopub.status.idle": "2024-08-15T02:59:26.797557Z",
"shell.execute_reply": "2024-08-15T02:59:26.796974Z"
},
"id": "mT52NFWVdiTe"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[2 7]\n",
" [3 8]\n",
" [0 5]], shape=(3, 2), dtype=int32)\n"
]
}
],
"source": [
"t4 = tf.constant([[0, 5],\n",
" [1, 6],\n",
" [2, 7],\n",
" [3, 8],\n",
" [4, 9]])\n",
"\n",
"print(tf.gather_nd(t4,\n",
" indices=[[2], [3], [0]]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "87NN7YQhh2-a"
},
"source": [
"
"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.800666Z",
"iopub.status.busy": "2024-08-15T02:59:26.800096Z",
"iopub.status.idle": "2024-08-15T02:59:26.806983Z",
"shell.execute_reply": "2024-08-15T02:59:26.806274Z"
},
"id": "_z6F2WcPJ9Rh"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([ 0 16], shape=(2,), dtype=int64)\n"
]
}
],
"source": [
"t5 = np.reshape(np.arange(18), [2, 3, 3])\n",
"\n",
"print(tf.gather_nd(t5,\n",
" indices=[[0, 0, 0], [1, 2, 1]]))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.810063Z",
"iopub.status.busy": "2024-08-15T02:59:26.809486Z",
"iopub.status.idle": "2024-08-15T02:59:26.814332Z",
"shell.execute_reply": "2024-08-15T02:59:26.813757Z"
},
"id": "gyIjhm7cV2N0"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[[ 0 1 2]\n",
" [ 6 7 8]]\n",
"\n",
" [[ 9 10 11]\n",
" [15 16 17]]], shape=(2, 2, 3), dtype=int64)\n"
]
}
],
"source": [
"# Return a list of two matrices\n",
"\n",
"print(tf.gather_nd(t5,\n",
" indices=[[[0, 0], [0, 2]], [[1, 0], [1, 2]]]))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.817439Z",
"iopub.status.busy": "2024-08-15T02:59:26.816968Z",
"iopub.status.idle": "2024-08-15T02:59:26.821715Z",
"shell.execute_reply": "2024-08-15T02:59:26.821153Z"
},
"id": "368D4ciDWB3r"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[ 0 1 2]\n",
" [ 6 7 8]\n",
" [ 9 10 11]\n",
" [15 16 17]], shape=(4, 3), dtype=int64)\n"
]
}
],
"source": [
"# Return one matrix\n",
"\n",
"print(tf.gather_nd(t5,\n",
" indices=[[0, 0], [0, 2], [1, 0], [1, 2]]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "od51VzS2SSPS"
},
"source": [
"## Insert data into tensors\n",
"\n",
"Use `tf.scatter_nd` to insert data at specific slices/indices of a tensor. Note that the tensor into which you insert values is zero-initialized."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.824884Z",
"iopub.status.busy": "2024-08-15T02:59:26.824336Z",
"iopub.status.idle": "2024-08-15T02:59:26.830117Z",
"shell.execute_reply": "2024-08-15T02:59:26.829492Z"
},
"id": "jlALYLWm1KhN"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor([ 0 2 0 4 0 6 0 8 0 10], shape=(10,), dtype=int32)\n"
]
}
],
"source": [
"t6 = tf.constant([10])\n",
"indices = tf.constant([[1], [3], [5], [7], [9]])\n",
"data = tf.constant([2, 4, 6, 8, 10])\n",
"\n",
"print(tf.scatter_nd(indices=indices,\n",
" updates=data,\n",
" shape=t6))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CD5vd-kxksW7"
},
"source": [
"Methods like `tf.scatter_nd` which require zero-initialized tensors are similar to sparse tensor initializers. You can use `tf.gather_nd` and `tf.scatter_nd` to mimic the behavior of sparse tensor ops.\n",
"\n",
"Consider an example where you construct a sparse tensor using these two methods in conjunction."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.833252Z",
"iopub.status.busy": "2024-08-15T02:59:26.832707Z",
"iopub.status.idle": "2024-08-15T02:59:26.836734Z",
"shell.execute_reply": "2024-08-15T02:59:26.836085Z"
},
"id": "xyK69QgRmrlW"
},
"outputs": [],
"source": [
"# Gather values from one tensor by specifying indices\n",
"\n",
"new_indices = tf.constant([[0, 2], [2, 1], [3, 3]])\n",
"t7 = tf.gather_nd(t2, indices=new_indices)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_7V_Qfa4qkdn"
},
"source": [
"
"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.839736Z",
"iopub.status.busy": "2024-08-15T02:59:26.839326Z",
"iopub.status.idle": "2024-08-15T02:59:26.843628Z",
"shell.execute_reply": "2024-08-15T02:59:26.843021Z"
},
"id": "QWT1E1Weqjx2"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[ 0 0 2 0 0]\n",
" [ 0 0 0 0 0]\n",
" [ 0 11 0 0 0]\n",
" [ 0 0 0 18 0]], shape=(4, 5), dtype=int32)\n"
]
}
],
"source": [
"# Add these values into a new tensor\n",
"\n",
"t8 = tf.scatter_nd(indices=new_indices, updates=t7, shape=tf.constant([4, 5]))\n",
"\n",
"print(t8)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NUyYjnvCn_vu"
},
"source": [
"This is similar to:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.846678Z",
"iopub.status.busy": "2024-08-15T02:59:26.846414Z",
"iopub.status.idle": "2024-08-15T02:59:26.851689Z",
"shell.execute_reply": "2024-08-15T02:59:26.851087Z"
},
"id": "LeqFwUgroE4j"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"SparseTensor(indices=tf.Tensor(\n",
"[[0 2]\n",
" [2 1]\n",
" [3 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([ 2 11 18], shape=(3,), dtype=int32), dense_shape=tf.Tensor([4 5], shape=(2,), dtype=int64))\n"
]
}
],
"source": [
"t9 = tf.SparseTensor(indices=[[0, 2], [2, 1], [3, 3]],\n",
" values=[2, 11, 18],\n",
" dense_shape=[4, 5])\n",
"\n",
"print(t9)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.854916Z",
"iopub.status.busy": "2024-08-15T02:59:26.854327Z",
"iopub.status.idle": "2024-08-15T02:59:26.864541Z",
"shell.execute_reply": "2024-08-15T02:59:26.863932Z"
},
"id": "5MaF6RlJot33"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[ 0 0 2 0 0]\n",
" [ 0 0 0 0 0]\n",
" [ 0 11 0 0 0]\n",
" [ 0 0 0 18 0]], shape=(4, 5), dtype=int32)\n"
]
}
],
"source": [
"# Convert the sparse tensor into a dense tensor\n",
"\n",
"t10 = tf.sparse.to_dense(t9)\n",
"\n",
"print(t10)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4sf3F3Xk56Bt"
},
"source": [
"To insert data into a tensor with pre-existing values, use `tf.tensor_scatter_nd_add`."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.867679Z",
"iopub.status.busy": "2024-08-15T02:59:26.867270Z",
"iopub.status.idle": "2024-08-15T02:59:26.873043Z",
"shell.execute_reply": "2024-08-15T02:59:26.872450Z"
},
"id": "mte2ifOb6sQO"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[2 7 6]\n",
" [9 5 1]\n",
" [4 3 8]], shape=(3, 3), dtype=int32)\n"
]
}
],
"source": [
"t11 = tf.constant([[2, 7, 0],\n",
" [9, 0, 1],\n",
" [0, 3, 8]])\n",
"\n",
"# Convert the tensor into a magic square by inserting numbers at appropriate indices\n",
"\n",
"t12 = tf.tensor_scatter_nd_add(t11,\n",
" indices=[[0, 2], [1, 1], [2, 0]],\n",
" updates=[6, 5, 4])\n",
"\n",
"print(t12)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2dQYyROU09G6"
},
"source": [
"Similarly, use `tf.tensor_scatter_nd_sub` to subtract values from a tensor with pre-existing values."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.876266Z",
"iopub.status.busy": "2024-08-15T02:59:26.875638Z",
"iopub.status.idle": "2024-08-15T02:59:26.881519Z",
"shell.execute_reply": "2024-08-15T02:59:26.880893Z"
},
"id": "ac6_i6uK1EI6"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[1 0 0]\n",
" [0 1 0]\n",
" [0 0 1]], shape=(3, 3), dtype=int32)\n"
]
}
],
"source": [
"# Convert the tensor into an identity matrix\n",
"\n",
"t13 = tf.tensor_scatter_nd_sub(t11,\n",
" indices=[[0, 0], [0, 1], [1, 0], [1, 1], [1, 2], [2, 1], [2, 2]],\n",
" updates=[1, 7, 9, -1, 1, 3, 7])\n",
"\n",
"print(t13)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "B_2DuzRRwVc8"
},
"source": [
"Use `tf.tensor_scatter_nd_min` to copy element-wise minimum values from one tensor to another."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.884525Z",
"iopub.status.busy": "2024-08-15T02:59:26.884307Z",
"iopub.status.idle": "2024-08-15T02:59:26.890059Z",
"shell.execute_reply": "2024-08-15T02:59:26.889463Z"
},
"id": "T_4FrHrHlkHK"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[-2 -7 -6]\n",
" [-9 -5 1]\n",
" [-4 -3 -8]], shape=(3, 3), dtype=int32)\n"
]
}
],
"source": [
"t14 = tf.constant([[-2, -7, 0],\n",
" [-9, 0, 1],\n",
" [0, -3, -8]])\n",
"\n",
"t15 = tf.tensor_scatter_nd_min(t14,\n",
" indices=[[0, 2], [1, 1], [2, 0]],\n",
" updates=[-6, -5, -4])\n",
"\n",
"print(t15)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "PkaiKyrF0WtX"
},
"source": [
"Similarly, use `tf.tensor_scatter_nd_max` to copy element-wise maximum values from one tensor to another."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"execution": {
"iopub.execute_input": "2024-08-15T02:59:26.892803Z",
"iopub.status.busy": "2024-08-15T02:59:26.892585Z",
"iopub.status.idle": "2024-08-15T02:59:26.897512Z",
"shell.execute_reply": "2024-08-15T02:59:26.897000Z"
},
"id": "izJu0nXi0GDq"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(\n",
"[[-2 -7 6]\n",
" [-9 5 1]\n",
" [ 4 -3 -8]], shape=(3, 3), dtype=int32)\n"
]
}
],
"source": [
"t16 = tf.tensor_scatter_nd_max(t14,\n",
" indices=[[0, 2], [1, 1], [2, 0]],\n",
" updates=[6, 5, 4])\n",
"\n",
"print(t16)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QAffUOa-85lF"
},
"source": [
"## Further reading and resources\n",
"\n",
"In this guide, you learned how to use the tensor slicing ops available with TensorFlow to exert finer control over the elements in your tensors.\n",
"\n",
"* Check out the slicing ops available with TensorFlow NumPy such as `tf.experimental.numpy.take_along_axis` and `tf.experimental.numpy.take`.\n",
"\n",
"* Also check out the [Tensor guide](https://www.tensorflow.org/guide/tensor) and the [Variable guide](https://www.tensorflow.org/guide/variable)."
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "tensor_slicing.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.19"
}
},
"nbformat": 4,
"nbformat_minor": 0
}