{ "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-01-11T18:52:41.649547Z", "iopub.status.busy": "2024-01-11T18:52:41.648971Z", "iopub.status.idle": "2024-01-11T18:52:41.652759Z", "shell.execute_reply": "2024-01-11T18:52:41.652205Z" }, "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": "qFdPvlXBOdUN" }, "source": [ "# テンソルの基礎" ] }, { "cell_type": "markdown", "metadata": { "id": "MfBg1C5NB3X0" }, "source": [ "\n", " \n", " \n", " \n", " \n", "
TensorFlow.org で表示Google Colab で実行GitHub でソースを表示ノートブックをダウンロード
" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:41.656331Z", "iopub.status.busy": "2024-01-11T18:52:41.655757Z", "iopub.status.idle": "2024-01-11T18:52:44.035095Z", "shell.execute_reply": "2024-01-11T18:52:44.034357Z" }, "id": "AL2hzxorJiWy" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2024-01-11 18:52:42.092406: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n", "2024-01-11 18:52:42.092450: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n", "2024-01-11 18:52:42.094012: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] 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": "VQ3s2J8Vgowq" }, "source": [ "テンソルは `dtype` と呼ばれる均一型の多次元配列です。サポートされているすべての `dtypes` は、`tf.dtypes.DType` で確認できます。\n", "\n", "[NumPy](https://numpy.org/devdocs/user/quickstart.html) をよく知っているのであれば、テンソルは(どちらかと言えば)`np.arrays` のようなものです。\n", "\n", "すべてのテンソルは、Python の数値や文字列と同じように不変です。つまり、テンソルのコンテンツを更新することは不可能で、新しいテンソルのみを作成できます。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "DRK5-9EpYbzG" }, "source": [ "## 基礎\n", "\n", "まずは、基本的なテンソルを作成します。" ] }, { "cell_type": "markdown", "metadata": { "id": "uSHRFT6LJbxq" }, "source": [ "次は、「スカラー」または「階数 0」のテンソルです。スカラーには単一の値のみが含まれ、「軸」は存在しません。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:44.039327Z", "iopub.status.busy": "2024-01-11T18:52:44.038945Z", "iopub.status.idle": "2024-01-11T18:52:46.203282Z", "shell.execute_reply": "2024-01-11T18:52:46.202566Z" }, "id": "d5JcgLFR6gHv" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(4, shape=(), dtype=int32)\n" ] } ], "source": [ "# This will be an int32 tensor by default; see \"dtypes\" below.\n", "rank_0_tensor = tf.constant(4)\n", "print(rank_0_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "tdmPAn9fWYs5" }, "source": [ "「ベクトル」または「階数 1」テンソルは、値のリストとして考えられます。1 ベクトルは 1 つの軸です。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.207181Z", "iopub.status.busy": "2024-01-11T18:52:46.206512Z", "iopub.status.idle": "2024-01-11T18:52:46.214754Z", "shell.execute_reply": "2024-01-11T18:52:46.214125Z" }, "id": "oZos8o_R6oE7" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)\n" ] } ], "source": [ "# Let's make this a float tensor.\n", "rank_1_tensor = tf.constant([2.0, 3.0, 4.0])\n", "print(rank_1_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "G3IJG-ug_H4u" }, "source": [ "「行列」または「階数 2」テンソルには軸が 2 つあります。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.218243Z", "iopub.status.busy": "2024-01-11T18:52:46.217664Z", "iopub.status.idle": "2024-01-11T18:52:46.223237Z", "shell.execute_reply": "2024-01-11T18:52:46.222650Z" }, "id": "cnOIA_xb6u0M" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[1. 2.]\n", " [3. 4.]\n", " [5. 6.]], shape=(3, 2), dtype=float16)\n" ] } ], "source": [ "# If you want to be specific, you can set the dtype (see below) at creation time\n", "rank_2_tensor = tf.constant([[1, 2],\n", " [3, 4],\n", " [5, 6]], dtype=tf.float16)\n", "print(rank_2_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "19m72qEPkfxi" }, "source": [ "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", "\n", " \n", " \n", "\n", "
スカラー, 形状: [] ベクトル, 形状: [3] 行列, 形状: [3, 2]
\"スカラー、数字\"3\"3x2
\n" ] }, { "cell_type": "markdown", "metadata": { "id": "fjFvzcn4_ehD" }, "source": [ "テンソルにはさらに軸がある場合があります。次は、3 軸のテンソルです。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.226468Z", "iopub.status.busy": "2024-01-11T18:52:46.226026Z", "iopub.status.idle": "2024-01-11T18:52:46.230743Z", "shell.execute_reply": "2024-01-11T18:52:46.230060Z" }, "id": "sesW7gw6JkXy" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[[ 0 1 2 3 4]\n", " [ 5 6 7 8 9]]\n", "\n", " [[10 11 12 13 14]\n", " [15 16 17 18 19]]\n", "\n", " [[20 21 22 23 24]\n", " [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)\n" ] } ], "source": [ "# There can be an arbitrary number of\n", "# axes (sometimes called \"dimensions\")\n", "rank_3_tensor = tf.constant([\n", " [[0, 1, 2, 3, 4],\n", " [5, 6, 7, 8, 9]],\n", " [[10, 11, 12, 13, 14],\n", " [15, 16, 17, 18, 19]],\n", " [[20, 21, 22, 23, 24],\n", " [25, 26, 27, 28, 29]],])\n", "\n", "print(rank_3_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "rM2sTGIkoE3S" }, "source": [ "3 軸以上のテンソルを視覚化する方法はたくさんあります。" ] }, { "cell_type": "markdown", "metadata": { "id": "NFiYfNMMhDgL" }, "source": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", " \n", " \n", "\n", " \n", "\n", "\n", "
3 軸テンソル, 形状: [3, 2, 5]
" ] }, { "cell_type": "markdown", "metadata": { "id": "oWAc0U8OZwNb" }, "source": [ "`np.array` または `tensor.numpy` メソッドを使用して、テンソルを NumPy 配列に変換できます。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.234219Z", "iopub.status.busy": "2024-01-11T18:52:46.233631Z", "iopub.status.idle": "2024-01-11T18:52:46.240090Z", "shell.execute_reply": "2024-01-11T18:52:46.239481Z" }, "id": "J5u6_6ZYaS7B" }, "outputs": [ { "data": { "text/plain": [ "array([[1., 2.],\n", " [3., 4.],\n", " [5., 6.]], dtype=float16)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.array(rank_2_tensor)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.243084Z", "iopub.status.busy": "2024-01-11T18:52:46.242657Z", "iopub.status.idle": "2024-01-11T18:52:46.246969Z", "shell.execute_reply": "2024-01-11T18:52:46.246369Z" }, "id": "c6Taz2gIaZeo" }, "outputs": [ { "data": { "text/plain": [ "array([[1., 2.],\n", " [3., 4.],\n", " [5., 6.]], dtype=float16)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rank_2_tensor.numpy()" ] }, { "cell_type": "markdown", "metadata": { "id": "hnz19F0ocEKD" }, "source": [ "テンソルには、通常、浮動小数点型や整数型が含まれますが、次のようなほかの型も含まれます。\n", "\n", "- 複素数\n", "- 文字列\n", "\n", "基本の `tf.Tensor` クラスには、「矩形」を成すテンソルが必要です。つまり各要素は、各軸に沿って同じサイズになります。ただし、次のように、異なる形状を処理できる特殊なテンソルもあります。\n", "\n", "- 不規則(以下の [RaggedTensor](#ragged_tensors) を参照)\n", "- スパース(以下の [SparseTensor](#sparse_tensors) を参照)" ] }, { "cell_type": "markdown", "metadata": { "id": "SDC7OGeAIJr8" }, "source": [ "テンソルには、加算、要素ごとの乗算、および行列の乗算などの基本的な計算を実行できます。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.250306Z", "iopub.status.busy": "2024-01-11T18:52:46.249714Z", "iopub.status.idle": "2024-01-11T18:52:46.258271Z", "shell.execute_reply": "2024-01-11T18:52:46.257676Z" }, "id": "-DTkjwDOIIDa" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[2 3]\n", " [4 5]], shape=(2, 2), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[1 2]\n", " [3 4]], shape=(2, 2), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[3 3]\n", " [7 7]], shape=(2, 2), dtype=int32) \n", "\n" ] } ], "source": [ "a = tf.constant([[1, 2],\n", " [3, 4]])\n", "b = tf.constant([[1, 1],\n", " [1, 1]]) # Could have also said `tf.ones([2,2], dtype=tf.int32)`\n", "\n", "print(tf.add(a, b), \"\\n\")\n", "print(tf.multiply(a, b), \"\\n\")\n", "print(tf.matmul(a, b), \"\\n\")" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.261047Z", "iopub.status.busy": "2024-01-11T18:52:46.260797Z", "iopub.status.idle": "2024-01-11T18:52:46.265295Z", "shell.execute_reply": "2024-01-11T18:52:46.264714Z" }, "id": "2smoWeUz-N2q" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[2 3]\n", " [4 5]], shape=(2, 2), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[1 2]\n", " [3 4]], shape=(2, 2), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[3 3]\n", " [7 7]], shape=(2, 2), dtype=int32) \n", "\n" ] } ], "source": [ "print(a + b, \"\\n\") # element-wise addition\n", "print(a * b, \"\\n\") # element-wise multiplication\n", "print(a @ b, \"\\n\") # matrix multiplication" ] }, { "cell_type": "markdown", "metadata": { "id": "S3_vIAl2JPVc" }, "source": [ "テンソルはあらゆる種類の演算(または「Ops」)に使用されます。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.268754Z", "iopub.status.busy": "2024-01-11T18:52:46.268111Z", "iopub.status.idle": "2024-01-11T18:52:46.297471Z", "shell.execute_reply": "2024-01-11T18:52:46.296840Z" }, "id": "Gp4WUYzGIbnv" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(10.0, shape=(), dtype=float32)\n", "tf.Tensor([1 0], shape=(2,), dtype=int64)\n", "tf.Tensor(\n", "[[2.6894143e-01 7.3105854e-01]\n", " [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)\n" ] } ], "source": [ "c = tf.constant([[4.0, 5.0], [10.0, 1.0]])\n", "\n", "# Find the largest value\n", "print(tf.reduce_max(c))\n", "# Find the index of the largest value\n", "print(tf.math.argmax(c))\n", "# Compute the softmax\n", "print(tf.nn.softmax(c))" ] }, { "cell_type": "markdown", "metadata": { "id": "0MNM-q7-MZLz" }, "source": [ "注意: 通常、TensorFlow 関数が `Tensor` を入力として期待する場合、関数は `tf.convert_to_tensor` を使用して `Tensor` に変換できるものをすべて受け入れます。例については、以下をご覧ください。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.300872Z", "iopub.status.busy": "2024-01-11T18:52:46.300246Z", "iopub.status.idle": "2024-01-11T18:52:46.305377Z", "shell.execute_reply": "2024-01-11T18:52:46.304790Z" }, "id": "_wch0N8xNEt-" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.convert_to_tensor([1,2,3])" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.308466Z", "iopub.status.busy": "2024-01-11T18:52:46.307896Z", "iopub.status.idle": "2024-01-11T18:52:46.315603Z", "shell.execute_reply": "2024-01-11T18:52:46.314889Z" }, "id": "ngqIeWYeNJVI" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.reduce_max([1,2,3])" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.318753Z", "iopub.status.busy": "2024-01-11T18:52:46.318203Z", "iopub.status.idle": "2024-01-11T18:52:46.335829Z", "shell.execute_reply": "2024-01-11T18:52:46.335198Z" }, "id": "ThVMxqbVNOq3" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.reduce_max(np.array([1,2,3]))" ] }, { "cell_type": "markdown", "metadata": { "id": "NvSAbowVVuRr" }, "source": [ "## 形状について" ] }, { "cell_type": "markdown", "metadata": { "id": "hkaBIqkTCcGY" }, "source": [ "テンソルには形状があり、次のような用語が使用されます。\n", "\n", "- **形状**: テンソルの各軸の長さ(要素の数)。\n", "- **階数**: テンソルの軸数。スカラーは階数 0、ベクトルは階数 1、行列は階数 2 となります。\n", "- **軸**または**次元**: テンソルの特定の次元。\n", "- **サイズ**: 形状ベクトルの要素の積である、テンソル内の項目の総数。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "E9L3-kCQq2f6" }, "source": [ "注意: 「2 次元のテンソル」と記述されることもありますが、階数 2 のテンソルは、通常 2 次元形状ではありません。" ] }, { "cell_type": "markdown", "metadata": { "id": "VFOyG2tn8LhW" }, "source": [ "テンソルと `tf.TensorShape` オブジェクトには、次にアクセスするための便利なプロパティがあります。" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.339265Z", "iopub.status.busy": "2024-01-11T18:52:46.338731Z", "iopub.status.idle": "2024-01-11T18:52:46.345889Z", "shell.execute_reply": "2024-01-11T18:52:46.345285Z" }, "id": "RyD3yewUKdnK" }, "outputs": [], "source": [ "rank_4_tensor = tf.zeros([3, 2, 4, 5])" ] }, { "cell_type": "markdown", "metadata": { "id": "oTZZW9ziq4og" }, "source": [ "\n", "\n", " \n", "\n", "\n", " \n", "\n", " \n", "
階数 4 テンソル, 形状: [3, 2, 4, 5]
\"テンソルの形状はベクトルに似ている。\"\n", "\"4
\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.349081Z", "iopub.status.busy": "2024-01-11T18:52:46.348545Z", "iopub.status.idle": "2024-01-11T18:52:46.353531Z", "shell.execute_reply": "2024-01-11T18:52:46.352899Z" }, "id": "MHm9vSqogsBk" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Type of every element: \n", "Number of axes: 4\n", "Shape of tensor: (3, 2, 4, 5)\n", "Elements along axis 0 of tensor: 3\n", "Elements along the last axis of tensor: 5\n", "Total number of elements (3*2*4*5): 120\n" ] } ], "source": [ "print(\"Type of every element:\", rank_4_tensor.dtype)\n", "print(\"Number of axes:\", rank_4_tensor.ndim)\n", "print(\"Shape of tensor:\", rank_4_tensor.shape)\n", "print(\"Elements along axis 0 of tensor:\", rank_4_tensor.shape[0])\n", "print(\"Elements along the last axis of tensor:\", rank_4_tensor.shape[-1])\n", "print(\"Total number of elements (3*2*4*5): \", tf.size(rank_4_tensor).numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "2ZGZp_JOOPOv" }, "source": [ "ただし、`Tensor.ndim` および `Tensor.shape` 属性は `Tensor` オブジェクトを返さないことに注意してください。`Tensor` が必要な場合は、`tf.rank` または `tf.shape` 関数を使用します。この違いは微妙ですが、グラフを作成するときに重要になる場合があります(後で作成します)。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.356727Z", "iopub.status.busy": "2024-01-11T18:52:46.356170Z", "iopub.status.idle": "2024-01-11T18:52:46.360647Z", "shell.execute_reply": "2024-01-11T18:52:46.360005Z" }, "id": "Ptq0-y6APCpD" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.rank(rank_4_tensor)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.363851Z", "iopub.status.busy": "2024-01-11T18:52:46.363235Z", "iopub.status.idle": "2024-01-11T18:52:46.368459Z", "shell.execute_reply": "2024-01-11T18:52:46.367872Z" }, "id": "HslrDOEBPICN" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.shape(rank_4_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "bQmE_Vx5JilS" }, "source": [ "軸は通常、そのインデックスで参照されますが、それぞれの意味を常に把握しておく必要があります。多くの場合、軸はグローバルからローカルに順序付けられています。バッチ軸を先頭に、空間次元、そして最後に各位置の特徴量が続きます。こうすることで、特徴ベクトルは連続したメモリ領域となります。\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", "\n", "
典型的な軸の順序
\"各軸が何であるかを追跡。4
" ] }, { "cell_type": "markdown", "metadata": { "id": "FlPoVvJS75Bb" }, "source": [ "## インデックス作成" ] }, { "cell_type": "markdown", "metadata": { "id": "apOkCKqCZIZu" }, "source": [ "### 単軸のインデックス作成\n", "\n", "TensorFlow は、[Python でのリストまたは文字列のインデックス作成](https://docs.python.org/3/tutorial/introduction.html#strings){:.external}と同様の標準的な Python インデックス作成ルールや NumPy インデックス作成の基本ルールを使用しています。\n", "\n", "- インデックスは `0` から開始\n", "- 負のインデックスは後ろ側から逆順に数える\n", "- スライスにコロン `:` を使用 - `start:stop:step`\n" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.371753Z", "iopub.status.busy": "2024-01-11T18:52:46.371319Z", "iopub.status.idle": "2024-01-11T18:52:46.375266Z", "shell.execute_reply": "2024-01-11T18:52:46.374655Z" }, "id": "SQ-CrJxLXTIM" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 0 1 1 2 3 5 8 13 21 34]\n" ] } ], "source": [ "rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])\n", "print(rank_1_tensor.numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "mQYYL56PXSak" }, "source": [ "スカラーを使用してインデックスを作成すると、軸が削除されます。" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.378321Z", "iopub.status.busy": "2024-01-11T18:52:46.377787Z", "iopub.status.idle": "2024-01-11T18:52:46.384613Z", "shell.execute_reply": "2024-01-11T18:52:46.384046Z" }, "id": "n6tqHciOWMt5" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "First: 0\n", "Second: 1\n", "Last: 34\n" ] } ], "source": [ "print(\"First:\", rank_1_tensor[0].numpy())\n", "print(\"Second:\", rank_1_tensor[1].numpy())\n", "print(\"Last:\", rank_1_tensor[-1].numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "qJLHU_a2XwpG" }, "source": [ "`:` スライスを使用してインデックスを作成すると、軸が維持されます。" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.388053Z", "iopub.status.busy": "2024-01-11T18:52:46.387387Z", "iopub.status.idle": "2024-01-11T18:52:46.400009Z", "shell.execute_reply": "2024-01-11T18:52:46.399426Z" }, "id": "giVPPcfQX-cu" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Everything: [ 0 1 1 2 3 5 8 13 21 34]\n", "Before 4: [0 1 1 2]\n", "From 4 to the end: [ 3 5 8 13 21 34]\n", "From 2, before 7: [1 2 3 5 8]\n", "Every other item: [ 0 1 3 8 21]\n", "Reversed: [34 21 13 8 5 3 2 1 1 0]\n" ] } ], "source": [ "print(\"Everything:\", rank_1_tensor[:].numpy())\n", "print(\"Before 4:\", rank_1_tensor[:4].numpy())\n", "print(\"From 4 to the end:\", rank_1_tensor[4:].numpy())\n", "print(\"From 2, before 7:\", rank_1_tensor[2:7].numpy())\n", "print(\"Every other item:\", rank_1_tensor[::2].numpy())\n", "print(\"Reversed:\", rank_1_tensor[::-1].numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "elDSxXi7X-Bh" }, "source": [ "### 多軸のインデックス作成" ] }, { "cell_type": "markdown", "metadata": { "id": "Cgk0uRUYZiai" }, "source": [ "階数の高いテンソルは、複数のインデックスを渡してインデックス化されます。\n", "\n", "単軸とまったく同じルールが各軸に個別に適用されます。" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.403482Z", "iopub.status.busy": "2024-01-11T18:52:46.402893Z", "iopub.status.idle": "2024-01-11T18:52:46.406500Z", "shell.execute_reply": "2024-01-11T18:52:46.405876Z" }, "id": "Tc5X_WlsZXmd" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1. 2.]\n", " [3. 4.]\n", " [5. 6.]]\n" ] } ], "source": [ "print(rank_2_tensor.numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "w07U9vq5ipQk" }, "source": [ "各インデックスに整数を渡すと、結果はスカラーになります。" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.409730Z", "iopub.status.busy": "2024-01-11T18:52:46.409176Z", "iopub.status.idle": "2024-01-11T18:52:46.421090Z", "shell.execute_reply": "2024-01-11T18:52:46.420434Z" }, "id": "PvILXc1PjqTM" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.0\n" ] } ], "source": [ "# Pull out a single value from a 2-rank tensor\n", "print(rank_2_tensor[1, 1].numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "3RLCzAOHjfEH" }, "source": [ "整数とスライスを任意に組み合わせてインデックスを作成することができます。" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.424226Z", "iopub.status.busy": "2024-01-11T18:52:46.423769Z", "iopub.status.idle": "2024-01-11T18:52:46.435397Z", "shell.execute_reply": "2024-01-11T18:52:46.434804Z" }, "id": "YTqNqsfJkJP_" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Second row: [3. 4.]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Second column: [2. 4. 6.]\n", "Last row: [5. 6.]\n", "First item in last column: 2.0\n", "Skip the first row:\n", "[[3. 4.]\n", " [5. 6.]] \n", "\n" ] } ], "source": [ "# Get row and column tensors\n", "print(\"Second row:\", rank_2_tensor[1, :].numpy())\n", "print(\"Second column:\", rank_2_tensor[:, 1].numpy())\n", "print(\"Last row:\", rank_2_tensor[-1, :].numpy())\n", "print(\"First item in last column:\", rank_2_tensor[0, -1].numpy())\n", "print(\"Skip the first row:\")\n", "print(rank_2_tensor[1:, :].numpy(), \"\\n\")" ] }, { "cell_type": "markdown", "metadata": { "id": "P45TwSUVSK6G" }, "source": [ "次は、3 軸テンソルを使用した例です。" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.438503Z", "iopub.status.busy": "2024-01-11T18:52:46.438065Z", "iopub.status.idle": "2024-01-11T18:52:46.443240Z", "shell.execute_reply": "2024-01-11T18:52:46.442660Z" }, "id": "GuLoMoCVSLxK" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[ 4 9]\n", " [14 19]\n", " [24 29]], shape=(3, 2), dtype=int32)\n" ] } ], "source": [ "print(rank_3_tensor[:, :, 4])" ] }, { "cell_type": "markdown", "metadata": { "id": "9NgmHq27TJOE" }, "source": [ "\n", "\n", "\n", "\n", "\n", " \n", " \n", "\n", "
バッチ内の各例のすべての位置で最後の特徴量を選択する
\"A \"2
" ] }, { "cell_type": "markdown", "metadata": { "id": "t9V83-thHn89" }, "source": [ "テンソル内の複数の個別の要素にインデックス作成を適用する方法については、[テンソルのスライスガイド](https://tensorflow.org/guide/tensor_slicing)をご覧ください。" ] }, { "cell_type": "markdown", "metadata": { "id": "fpr7R0t4SVb0" }, "source": [ "## 形状の操作\n", "\n", "テンソルの形状変更は非常に便利です。\n" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.446505Z", "iopub.status.busy": "2024-01-11T18:52:46.445961Z", "iopub.status.idle": "2024-01-11T18:52:46.449620Z", "shell.execute_reply": "2024-01-11T18:52:46.449017Z" }, "id": "EMeTtga5Wq8j" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(3, 1)\n" ] } ], "source": [ "# Shape returns a `TensorShape` object that shows the size along each axis\n", "x = tf.constant([[1], [2], [3]])\n", "print(x.shape)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.452797Z", "iopub.status.busy": "2024-01-11T18:52:46.452257Z", "iopub.status.idle": "2024-01-11T18:52:46.455575Z", "shell.execute_reply": "2024-01-11T18:52:46.454961Z" }, "id": "38jc2RXziT3W" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3, 1]\n" ] } ], "source": [ "# You can convert this object into a Python list, too\n", "print(x.shape.as_list())" ] }, { "cell_type": "markdown", "metadata": { "id": "J_xRlHZMKYnF" }, "source": [ "テンソルを新しい形状に変更できます。tf.reshape 演算は、基盤のデータを複製する必要がないため、素早く簡単に行えます。" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.458621Z", "iopub.status.busy": "2024-01-11T18:52:46.458178Z", "iopub.status.idle": "2024-01-11T18:52:46.462708Z", "shell.execute_reply": "2024-01-11T18:52:46.462119Z" }, "id": "pa9JCgMLWy87" }, "outputs": [], "source": [ "# You can reshape a tensor to a new shape.\n", "# Note that you're passing in a list\n", "reshaped = tf.reshape(x, [1, 3])" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.465665Z", "iopub.status.busy": "2024-01-11T18:52:46.465342Z", "iopub.status.idle": "2024-01-11T18:52:46.468692Z", "shell.execute_reply": "2024-01-11T18:52:46.468109Z" }, "id": "Mcq7iXOkW3LK" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(3, 1)\n", "(1, 3)\n" ] } ], "source": [ "print(x.shape)\n", "print(reshaped.shape)" ] }, { "cell_type": "markdown", "metadata": { "id": "gIB2tOkoVr6E" }, "source": [ "データはレイアウトをメモリに維持したまま、同じデータにポイントする新しいテンソルが要求された形状で作成されます。TensorFlow は C 形式の「行優先」メモリ順序付けを使用しており、右端のインデックスの増分は、メモリ内の 1 ステップに相当します。" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.471870Z", "iopub.status.busy": "2024-01-11T18:52:46.471499Z", "iopub.status.idle": "2024-01-11T18:52:46.475007Z", "shell.execute_reply": "2024-01-11T18:52:46.474423Z" }, "id": "7kMfM0RpUgI8" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[[ 0 1 2 3 4]\n", " [ 5 6 7 8 9]]\n", "\n", " [[10 11 12 13 14]\n", " [15 16 17 18 19]]\n", "\n", " [[20 21 22 23 24]\n", " [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)\n" ] } ], "source": [ "print(rank_3_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "TcDtfQkJWzIx" }, "source": [ "テンソルをフラット化すると、どの順序でメモリにレイアウトされているかを確認できます。" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.477822Z", "iopub.status.busy": "2024-01-11T18:52:46.477602Z", "iopub.status.idle": "2024-01-11T18:52:46.481865Z", "shell.execute_reply": "2024-01-11T18:52:46.480494Z" }, "id": "COnHEPuaWDQp" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23\n", " 24 25 26 27 28 29], shape=(30,), dtype=int32)\n" ] } ], "source": [ "# A `-1` passed in the `shape` argument says \"Whatever fits\".\n", "print(tf.reshape(rank_3_tensor, [-1]))" ] }, { "cell_type": "markdown", "metadata": { "id": "jJZRira2W--c" }, "source": [ "通常、`tf.reshape` の唯一合理的な使用は、隣接する軸を結合または分割する(または `1` を追加/削除する)ことです。\n", "\n", "この 3x2x5 のテンソルでは、スライスは混合しないため、(3x2)x5 または 3x(2x5) に形状を変更するのが合理的です。" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.487368Z", "iopub.status.busy": "2024-01-11T18:52:46.486993Z", "iopub.status.idle": "2024-01-11T18:52:46.491725Z", "shell.execute_reply": "2024-01-11T18:52:46.491095Z" }, "id": "zP2Iqc7zWu_J" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[ 0 1 2 3 4]\n", " [ 5 6 7 8 9]\n", " [10 11 12 13 14]\n", " [15 16 17 18 19]\n", " [20 21 22 23 24]\n", " [25 26 27 28 29]], shape=(6, 5), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[ 0 1 2 3 4 5 6 7 8 9]\n", " [10 11 12 13 14 15 16 17 18 19]\n", " [20 21 22 23 24 25 26 27 28 29]], shape=(3, 10), dtype=int32)\n" ] } ], "source": [ "print(tf.reshape(rank_3_tensor, [3*2, 5]), \"\\n\")\n", "print(tf.reshape(rank_3_tensor, [3, -1]))" ] }, { "cell_type": "markdown", "metadata": { "id": "6ZsZRUhihlDB" }, "source": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "
形状変更の成功例。
\"3x2x5\"同じデータの形状が\"同じデータの形状が
\n" ] }, { "cell_type": "markdown", "metadata": { "id": "nOcRxDC3jNIU" }, "source": [ "形状変更は要素の総数が等しい新しい形状で「機能」しますが、軸の順を守らなければ役に立ちません。\n", "\n", "`tf.reshape` では軸の交換は機能しないため、それを行うには `tf.transpose` が必要です。\n" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.494809Z", "iopub.status.busy": "2024-01-11T18:52:46.494302Z", "iopub.status.idle": "2024-01-11T18:52:46.499988Z", "shell.execute_reply": "2024-01-11T18:52:46.499412Z" }, "id": "I9qDL_8u7cBH" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[[ 0 1 2 3 4]\n", " [ 5 6 7 8 9]\n", " [10 11 12 13 14]]\n", "\n", " [[15 16 17 18 19]\n", " [20 21 22 23 24]\n", " [25 26 27 28 29]]], shape=(2, 3, 5), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[ 0 1 2 3 4 5]\n", " [ 6 7 8 9 10 11]\n", " [12 13 14 15 16 17]\n", " [18 19 20 21 22 23]\n", " [24 25 26 27 28 29]], shape=(5, 6), dtype=int32) \n", "\n", "InvalidArgumentError: {{function_node __wrapped__Reshape_device_/job:localhost/replica:0/task:0/device:GPU:0}} Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]\n" ] } ], "source": [ "# Bad examples: don't do this\n", "\n", "# You can't reorder axes with reshape.\n", "print(tf.reshape(rank_3_tensor, [2, 3, 5]), \"\\n\") \n", "\n", "# This is a mess\n", "print(tf.reshape(rank_3_tensor, [5, 6]), \"\\n\")\n", "\n", "# This doesn't work at all\n", "try:\n", " tf.reshape(rank_3_tensor, [7, -1])\n", "except Exception as e:\n", " print(f\"{type(e).__name__}: {e}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "qTM9-5eh68oo" }, "source": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "
形状変更の失敗例。
\"軸の順序は変更不可。この目的には\"データのスライスが混合されたものはおそらく誤り。\"\"新しい形状は正確に適合する必要がある。\"
" ] }, { "cell_type": "markdown", "metadata": { "id": "N9r90BvHCbTt" }, "source": [ "不完全に指定された形状を実行することができます。その形状には `None`(軸の長さが不明)が含まれているか、形状が `None`(テンソルの階数が不明)であるかのいずれかです。\n", "\n", "[tf.RaggedTensor](#ragged_tensors) を除き、このような形状は TensorFlow の象徴的なグラフ構築 API のコンテキストでのみ発生します。\n", "\n", "- [tf.function](function.ipynb)\n", "- [Keras 関数型 API](https://www.tensorflow.org/guide/keras/functional)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "fDmFtFM7k0R2" }, "source": [ "## `DTypes` をさらに詳しく\n", "\n", "`tf.Tensor` のデータ型を検査するには、`Tensor.dtype` プロパティを使用します。\n", "\n", "Python オブジェクトから `tf.Tensor` を作成する場合、オプションとしてデータ型を指定できます。\n", "\n", "指定しない場合は、TensorFlow によってデータを表すデータ型が選択されます。TensorFlow は Python の整数値を `tf.int32` と Python 浮動小数点数を `tf.float32` に変換します。そうでない場合は、TensorFlow は NumPy が配列に変換する場合と同じルールを使用します。\n", "\n", "型から型にキャストすることができます。" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.503433Z", "iopub.status.busy": "2024-01-11T18:52:46.502885Z", "iopub.status.idle": "2024-01-11T18:52:46.510651Z", "shell.execute_reply": "2024-01-11T18:52:46.509966Z" }, "id": "5mSTDWbelUvu" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([2 3 4], shape=(3,), dtype=uint8)\n" ] } ], "source": [ "the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)\n", "the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)\n", "# Now, cast to an uint8 and lose the decimal precision\n", "the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)\n", "print(the_u8_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "s1yBlJsVlFSu" }, "source": [ "## ブロードキャスト\n", "\n", "ブロードキャストは、[NumPy の相当する特徴量](https://numpy.org/doc/stable/user/basics.broadcasting.html){:.external}から得た概念です。簡単に言えば、ある条件下において、より小さなテンソルに複合演算を実行する場合、より大きなテンソルに適合するように自動的に「引き延ばされる」ということです。\n", "\n", "最も単純で一般的な事例としては、テンソルをスカラーに加算または乗算する場合が挙げられます。その場合、スカラーはもう片方の引数と同じ形状になるようにブロードキャストされます。 " ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.513954Z", "iopub.status.busy": "2024-01-11T18:52:46.513423Z", "iopub.status.idle": "2024-01-11T18:52:46.518423Z", "shell.execute_reply": "2024-01-11T18:52:46.517848Z" }, "id": "P8sypqmagHQN" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([2 4 6], shape=(3,), dtype=int32)\n", "tf.Tensor([2 4 6], shape=(3,), dtype=int32)\n", "tf.Tensor([2 4 6], shape=(3,), dtype=int32)\n" ] } ], "source": [ "x = tf.constant([1, 2, 3])\n", "\n", "y = tf.constant(2)\n", "z = tf.constant([2, 2, 2])\n", "# All of these are the same computation\n", "print(tf.multiply(x, 2))\n", "print(x * y)\n", "print(x * z)" ] }, { "cell_type": "markdown", "metadata": { "id": "o0SBoR6voWcb" }, "source": [ "同様に、長さ 1 の軸を別の引数に一致するように引き延ばすことができます。両方の引数を同一の計算で引き延ばすことができます。\n", "\n", "この場合、3x1 の行列は、要素ごとに 1x4 の行列と乗算され、3x4 の行列が生成されます。最初の 1 はオプションであることに注意してください。形状 y は `[4]` です。" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.521632Z", "iopub.status.busy": "2024-01-11T18:52:46.521056Z", "iopub.status.idle": "2024-01-11T18:52:46.526062Z", "shell.execute_reply": "2024-01-11T18:52:46.525477Z" }, "id": "6sGmkPg3XANr" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[1]\n", " [2]\n", " [3]], shape=(3, 1), dtype=int32) \n", "\n", "tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) \n", "\n", "tf.Tensor(\n", "[[ 1 2 3 4]\n", " [ 2 4 6 8]\n", " [ 3 6 9 12]], shape=(3, 4), dtype=int32)\n" ] } ], "source": [ "# These are the same computations\n", "x = tf.reshape(x,[3,1])\n", "y = tf.range(1, 5)\n", "print(x, \"\\n\")\n", "print(y, \"\\n\")\n", "print(tf.multiply(x, y))" ] }, { "cell_type": "markdown", "metadata": { "id": "t_7sh-EUYLrE" }, "source": [ "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
ブロードキャストの加算: [3, 1] 掛け [1, 4] により、[3,4] を生成
\"3x1
\n" ] }, { "cell_type": "markdown", "metadata": { "id": "9V3KgSJcKDRz" }, "source": [ "次は、ブロードキャストを使用しない同一の演算です。" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.529287Z", "iopub.status.busy": "2024-01-11T18:52:46.528813Z", "iopub.status.idle": "2024-01-11T18:52:46.533666Z", "shell.execute_reply": "2024-01-11T18:52:46.533060Z" }, "id": "elrF6v63igY8" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[ 1 2 3 4]\n", " [ 2 4 6 8]\n", " [ 3 6 9 12]], shape=(3, 4), dtype=int32)\n" ] } ], "source": [ "x_stretch = tf.constant([[1, 1, 1, 1],\n", " [2, 2, 2, 2],\n", " [3, 3, 3, 3]])\n", "\n", "y_stretch = tf.constant([[1, 2, 3, 4],\n", " [1, 2, 3, 4],\n", " [1, 2, 3, 4]])\n", "\n", "print(x_stretch * y_stretch) # Again, operator overloading" ] }, { "cell_type": "markdown", "metadata": { "id": "14KobqYu85gi" }, "source": [ "ブロードキャスト演算によってメモリ内の拡張したテンソルが実体化されることがないため、ほとんどの場合、ブロードキャストは時間と空間係数の両方です。\n", "\n", "`tf.broadcast_to` を使用して、ブロードキャストがどのようなものであるかを確認します。" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.536677Z", "iopub.status.busy": "2024-01-11T18:52:46.536256Z", "iopub.status.idle": "2024-01-11T18:52:46.541079Z", "shell.execute_reply": "2024-01-11T18:52:46.540430Z" }, "id": "GW2Q59_r8hZ6" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[1 2 3]\n", " [1 2 3]\n", " [1 2 3]], shape=(3, 3), dtype=int32)\n" ] } ], "source": [ "print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))" ] }, { "cell_type": "markdown", "metadata": { "id": "Z2bAMMQY-jpP" }, "source": [ "たとえば数学的演算とは異なり、`broadcast_to` はメモリを節約する上で特に何も行いません。ここでは、テンソルの実体化が行われています。\n", "\n", "さらに複雑化することができます。Jake VanderPlas の書籍『*Python Data Science Handbook*』の[このセクション](https://jakevdp.github.io/PythonDataScienceHandbook/02.05-computation-on-arrays-broadcasting.html){:.external}では、(やはり NumPy を使った)ブロードキャストのコツがさらに紹介されています。" ] }, { "cell_type": "markdown", "metadata": { "id": "o4Rpz0xAsKSI" }, "source": [ "## tf.convert_to_tensor\n", "\n", "`tf.matmul` や `tf.reshape` といったほとんどの演算は、クラス `tf.Tensor` の引数を取りますが、上記の例では、テンソルのような形状の Python オブジェクトを渡すことがよくあります。\n", "\n", "すべてではありませんが、ほとんどの演算は、非テンソル引数に対して `convert_to_tensor` を呼び出します。変換のレジストリがあり、NumPy の `ndarray`、`TensorShape`、Python リスト、`tf.Variable` といったほとんどのオブジェクトクラスは、自動的に変換されます。\n", "\n", "詳細について、または、テンソルに自動変換する独自の型がある場合は、`tf.register_tensor_conversion_function` をご覧ください。" ] }, { "cell_type": "markdown", "metadata": { "id": "05bBVBVYV0y6" }, "source": [ "## 不規則なテンソル\n", "\n", "軸に合わせて要素の数が変化するテンソルは「不規則」と呼ばれています。不規則なデータには、`tf.ragged.RaggedTensor` を使用してください。\n", "\n", "たとえば、次の形状は通常のテンソルとして表現することはできません。" ] }, { "cell_type": "markdown", "metadata": { "id": "VPc3jGoeJqB7" }, "source": [ "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
`tf.RaggedTensor`, 形状: [4, None]
\"2
" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.544553Z", "iopub.status.busy": "2024-01-11T18:52:46.544042Z", "iopub.status.idle": "2024-01-11T18:52:46.547112Z", "shell.execute_reply": "2024-01-11T18:52:46.546568Z" }, "id": "VsbTjoFfNVBF" }, "outputs": [], "source": [ "ragged_list = [\n", " [0, 1, 2, 3],\n", " [4, 5],\n", " [6, 7, 8],\n", " [9]]" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.550164Z", "iopub.status.busy": "2024-01-11T18:52:46.549668Z", "iopub.status.idle": "2024-01-11T18:52:46.553353Z", "shell.execute_reply": "2024-01-11T18:52:46.552784Z" }, "id": "p4xKTo57tutG" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ValueError: Can't convert non-rectangular Python sequence to Tensor.\n" ] } ], "source": [ "try:\n", " tensor = tf.constant(ragged_list)\n", "except Exception as e:\n", " print(f\"{type(e).__name__}: {e}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "0cm9KuEeMLGI" }, "source": [ "代わりに、`tf.ragged.constant` を使用して `tf.RaggedTensor` を作成します。" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.556598Z", "iopub.status.busy": "2024-01-11T18:52:46.556072Z", "iopub.status.idle": "2024-01-11T18:52:46.560597Z", "shell.execute_reply": "2024-01-11T18:52:46.559884Z" }, "id": "XhF3QV3jiqTj" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "ragged_tensor = tf.ragged.constant(ragged_list)\n", "print(ragged_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "sFgHduHVNoIE" }, "source": [ "`tf.RaggedTensor` の形状には不明な長さの軸が含まれます。" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.563649Z", "iopub.status.busy": "2024-01-11T18:52:46.563241Z", "iopub.status.idle": "2024-01-11T18:52:46.566674Z", "shell.execute_reply": "2024-01-11T18:52:46.566073Z" }, "id": "Eo_3wJUWNgqB" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(4, None)\n" ] } ], "source": [ "print(ragged_tensor.shape)" ] }, { "cell_type": "markdown", "metadata": { "id": "V9njclVkkN7G" }, "source": [ "## 文字列型テンソル\n", "\n", "`tf.string` は `dtype` であるため、テンソルで文字列(可変長バイト配列)としてデータを表すことができます。\n", "\n", "文字列はアトミックであり、Python 文字列のようにインデックスを作成することはできません。文字列の長さはテンソルの軸の 1 つではありません。これらを操作するための関数については、`tf.strings` をご覧ください。" ] }, { "cell_type": "markdown", "metadata": { "id": "5P_8spEGQ0wp" }, "source": [ "次はスカラー文字列のテンソルです。" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.570003Z", "iopub.status.busy": "2024-01-11T18:52:46.569449Z", "iopub.status.idle": "2024-01-11T18:52:46.574034Z", "shell.execute_reply": "2024-01-11T18:52:46.573429Z" }, "id": "sBosmM8MkIh4" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(b'Gray wolf', shape=(), dtype=string)\n" ] } ], "source": [ "# Tensors can be strings, too here is a scalar string.\n", "scalar_string_tensor = tf.constant(\"Gray wolf\")\n", "print(scalar_string_tensor)" ] }, { "cell_type": "markdown", "metadata": { "id": "CMFBSl1FQ3vE" }, "source": [ "そして、ベクトルの文字列です。" ] }, { "cell_type": "markdown", "metadata": { "id": "IO-c3Tq3RC1L" }, "source": [ "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
文字列ベクトル, 形状: [3,]
\"文字列の長さがテンソルの軸の
" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.577222Z", "iopub.status.busy": "2024-01-11T18:52:46.576754Z", "iopub.status.idle": "2024-01-11T18:52:46.580525Z", "shell.execute_reply": "2024-01-11T18:52:46.579859Z" }, "id": "41Dv2kL9QrtO" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)\n" ] } ], "source": [ "# If you have three string tensors of different lengths, this is OK.\n", "tensor_of_strings = tf.constant([\"Gray wolf\",\n", " \"Quick brown fox\",\n", " \"Lazy dog\"])\n", "# Note that the shape is (3,). The string length is not included.\n", "print(tensor_of_strings)" ] }, { "cell_type": "markdown", "metadata": { "id": "76gQ9qrgSMzS" }, "source": [ "上記の出力では、プレフィクス `b` は `tf.string` dtype が unicode 文字列でなくバイト文字列であることを示します。TensorFlow での Unicode テキストの使用については、「[Unicode チュートリアル](https://www.tensorflow.org/tutorials/load_data/unicode)」 をご覧ください。" ] }, { "cell_type": "markdown", "metadata": { "id": "ClSBPK-lZBQp" }, "source": [ "Unicode 文字を渡した場合、utf-8 で暗号化されます。" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.583702Z", "iopub.status.busy": "2024-01-11T18:52:46.583483Z", "iopub.status.idle": "2024-01-11T18:52:46.587653Z", "shell.execute_reply": "2024-01-11T18:52:46.587083Z" }, "id": "GTgL53jxSMd9" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.constant(\"🥳👍\")" ] }, { "cell_type": "markdown", "metadata": { "id": "Ir9cY42MMAei" }, "source": [ "文字列の基本的な関数は、`tf.strings.split` などの `tf.strings` を使って見つけることができます。" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.590842Z", "iopub.status.busy": "2024-01-11T18:52:46.590303Z", "iopub.status.idle": "2024-01-11T18:52:46.622516Z", "shell.execute_reply": "2024-01-11T18:52:46.621844Z" }, "id": "8k2K0VTFyj8e" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)\n" ] } ], "source": [ "# You can use split to split a string into a set of tensors\n", "print(tf.strings.split(scalar_string_tensor, sep=\" \"))" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.625968Z", "iopub.status.busy": "2024-01-11T18:52:46.625386Z", "iopub.status.idle": "2024-01-11T18:52:46.633720Z", "shell.execute_reply": "2024-01-11T18:52:46.633075Z" }, "id": "zgGAn1dfR-04" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# ...but it turns into a `RaggedTensor` if you split up a tensor of strings,\n", "# as each string might be split into a different number of parts.\n", "print(tf.strings.split(tensor_of_strings))" ] }, { "cell_type": "markdown", "metadata": { "id": "HsAn1kPeO84m" }, "source": [ "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
3 文字列分割, 形状: [3, None]
\"複数の文字列を分割すると
" ] }, { "cell_type": "markdown", "metadata": { "id": "st9OxrUxWSKY" }, "source": [ "そして `tf.strings.to_number`:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.636955Z", "iopub.status.busy": "2024-01-11T18:52:46.636547Z", "iopub.status.idle": "2024-01-11T18:52:46.647751Z", "shell.execute_reply": "2024-01-11T18:52:46.647137Z" }, "id": "3nRtx3X9WRfN" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([ 1. 10. 100.], shape=(3,), dtype=float32)\n" ] } ], "source": [ "text = tf.constant(\"1 10 100\")\n", "print(tf.strings.to_number(tf.strings.split(text, \" \")))" ] }, { "cell_type": "markdown", "metadata": { "id": "r2EZtBbJBns4" }, "source": [ "`tf.cast` を使用して文字列テンソルを数値に変換することはできませんが、バイトに変換してから数字に変換することができます。" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.651339Z", "iopub.status.busy": "2024-01-11T18:52:46.650694Z", "iopub.status.idle": "2024-01-11T18:52:46.663175Z", "shell.execute_reply": "2024-01-11T18:52:46.662558Z" }, "id": "fo8BjmH7gyTj" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)\n", "Bytes: tf.Tensor([ 68 117 99 107], shape=(4,), dtype=uint8)\n" ] } ], "source": [ "byte_strings = tf.strings.bytes_split(tf.constant(\"Duck\"))\n", "byte_ints = tf.io.decode_raw(tf.constant(\"Duck\"), tf.uint8)\n", "print(\"Byte strings:\", byte_strings)\n", "print(\"Bytes:\", byte_ints)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.666435Z", "iopub.status.busy": "2024-01-11T18:52:46.665867Z", "iopub.status.idle": "2024-01-11T18:52:46.681170Z", "shell.execute_reply": "2024-01-11T18:52:46.680496Z" }, "id": "uSQnZ7d1jCSQ" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Unicode bytes: tf.Tensor(b'\\xe3\\x82\\xa2\\xe3\\x83\\x92\\xe3\\x83\\xab \\xf0\\x9f\\xa6\\x86', shape=(), dtype=string)\n", "\n", "Unicode chars: tf.Tensor([b'\\xe3\\x82\\xa2' b'\\xe3\\x83\\x92' b'\\xe3\\x83\\xab' b' ' b'\\xf0\\x9f\\xa6\\x86'], shape=(5,), dtype=string)\n", "\n", "Unicode values: tf.Tensor([ 12450 12498 12523 32 129414], shape=(5,), dtype=int32)\n" ] } ], "source": [ "# Or split it up as unicode and then decode it\n", "unicode_bytes = tf.constant(\"アヒル 🦆\")\n", "unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, \"UTF-8\")\n", "unicode_values = tf.strings.unicode_decode(unicode_bytes, \"UTF-8\")\n", "\n", "print(\"\\nUnicode bytes:\", unicode_bytes)\n", "print(\"\\nUnicode chars:\", unicode_char_bytes)\n", "print(\"\\nUnicode values:\", unicode_values)" ] }, { "cell_type": "markdown", "metadata": { "id": "fE7nKJ2YW3aY" }, "source": [ "TensorFlow ではすべての生のバイトに、`tf.string` dtype が使用されています。`tf.io` モジュールには、画像の解読や csv の解析など、データとバイトを変換する関数が含まれています。" ] }, { "cell_type": "markdown", "metadata": { "id": "ua8BnAzxkRKV" }, "source": [ "## スパーステンソル\n", "\n", "非常に広い埋め込みスペースであるかのうように、データがスパースである場合があります。TensorFlow は、スパースデータを効率的に保管できるように、`tf.sparse.SparseTensor` と関連する演算をサポートしています。" ] }, { "cell_type": "markdown", "metadata": { "id": "mS5zgqgUTPRb" }, "source": [ "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
`tf.SparseTensor`, 形状: [3, 4]
\"3x4
" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "execution": { "iopub.execute_input": "2024-01-11T18:52:46.684724Z", "iopub.status.busy": "2024-01-11T18:52:46.684344Z", "iopub.status.idle": "2024-01-11T18:52:46.695102Z", "shell.execute_reply": "2024-01-11T18:52:46.694497Z" }, "id": "B9nbO1E2kSUN" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SparseTensor(indices=tf.Tensor(\n", "[[0 0]\n", " [1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64)) \n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[1 0 0 0]\n", " [0 0 2 0]\n", " [0 0 0 0]], shape=(3, 4), dtype=int32)\n" ] } ], "source": [ "# Sparse tensors store values by index in a memory-efficient manner\n", "sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],\n", " values=[1, 2],\n", " dense_shape=[3, 4])\n", "print(sparse_tensor, \"\\n\")\n", "\n", "# You can convert sparse tensors to dense\n", "print(tf.sparse.to_dense(sparse_tensor))" ] } ], "metadata": { "colab": { "collapsed_sections": [ "Tce3stUlHN0L" ], "name": "tensor.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.18" } }, "nbformat": 4, "nbformat_minor": 0 }