{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "iPpI7RaYoZuE" }, "source": [ "##### Copyright 2018 The TensorFlow Authors." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2022-12-15T02:52:40.639892Z", "iopub.status.busy": "2022-12-15T02:52:40.639181Z", "iopub.status.idle": "2022-12-15T02:52:40.643941Z", "shell.execute_reply": "2022-12-15T02:52:40.643312Z" }, "id": "hro2InpHobKk" }, "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": "U9i2Dsh-ziXr" }, "source": [ "# テンソルと演算" ] }, { "cell_type": "markdown", "metadata": { "id": "Hndw-YcxoOJK" }, "source": [ "\n", " \n", " \n", " \n", " \n", "
TensorFlow.org で表示\n", " Google Colab で実行\n", " GitHub でソースを表示ノートブックをダウンロード
" ] }, { "cell_type": "markdown", "metadata": { "id": "6sILUVbHoSgH" }, "source": [ "これは、下記の手法を示す TensorFlow の入門チュートリアルです。\n", "\n", "- 必要なパッケージのインポート\n", "- テンソルの作成と使用\n", "- GPU アクセラレーションの使用\n", "- `tf.data.Dataset` を使用してデータパイプラインを構築する" ] }, { "cell_type": "markdown", "metadata": { "id": "z1JcS5iBXMRO" }, "source": [ "## TensorFlowのインポート\n", "\n", "始めるにはまず、`tensorflow` モジュールをインポートします。TensorFlow 2 の時点では、Eager execution はデフォルトでオンになっています。Eager execution では、TensorFlow のフロントエンドがよりインタラクティブになります。これについては、後で詳しく説明します。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:40.648313Z", "iopub.status.busy": "2022-12-15T02:52:40.647770Z", "iopub.status.idle": "2022-12-15T02:52:42.938845Z", "shell.execute_reply": "2022-12-15T02:52:42.938047Z" }, "id": "vjBPmYjLdFmk" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2022-12-15 02:52:41.764436: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n", "2022-12-15 02:52:41.764552: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n", "2022-12-15 02:52:41.764564: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n" ] } ], "source": [ "import tensorflow as tf" ] }, { "cell_type": "markdown", "metadata": { "id": "H9UySOPLXdaw" }, "source": [ "## テンソル\n", "\n", "テンソルは多次元の配列です。NumPy の `ndarray` オブジェクトと同様に、`tf.Tensor` オブジェクトにはデータ型と形状があります。また、`tf.Tensor` はアクセラレータのメモリ(GPU など)に留まることができます。TensorFlow には、`tf.Tensor` を消費して生成する演算(`tf.math.add`、`tf.linalg.matmul`、`tf.linalg.inv` など)が多数含まれたライブラリが用意されています。これらの演算によって、以下のように、組み込み Python 型が自動的に変換されます。\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "cellView": "code", "execution": { "iopub.execute_input": "2022-12-15T02:52:42.943312Z", "iopub.status.busy": "2022-12-15T02:52:42.942848Z", "iopub.status.idle": "2022-12-15T02:52:46.739001Z", "shell.execute_reply": "2022-12-15T02:52:46.738238Z" }, "id": "ngUe237Wt48W" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(3, shape=(), dtype=int32)\n", "tf.Tensor([4 6], shape=(2,), dtype=int32)\n", "tf.Tensor(25, shape=(), dtype=int32)\n", "tf.Tensor(6, shape=(), dtype=int32)\n", "tf.Tensor(13, shape=(), dtype=int32)\n" ] } ], "source": [ "print(tf.math.add(1, 2))\n", "print(tf.math.add([1, 2], [3, 4]))\n", "print(tf.math.square(5))\n", "print(tf.math.reduce_sum([1, 2, 3]))\n", "\n", "# Operator overloading is also supported\n", "print(tf.math.square(2) + tf.math.square(3))" ] }, { "cell_type": "markdown", "metadata": { "id": "IDY4WsYRhP81" }, "source": [ "それぞれの`tf.Tensor`には、形状とデータ型があります。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:46.742855Z", "iopub.status.busy": "2022-12-15T02:52:46.742578Z", "iopub.status.idle": "2022-12-15T02:52:46.748450Z", "shell.execute_reply": "2022-12-15T02:52:46.747726Z" }, "id": "srYWH1MdJNG7" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([[2 3]], shape=(1, 2), dtype=int32)\n", "(1, 2)\n", "\n" ] } ], "source": [ "x = tf.linalg.matmul([[1]], [[2, 3]])\n", "print(x)\n", "print(x.shape)\n", "print(x.dtype)" ] }, { "cell_type": "markdown", "metadata": { "id": "eBPw8e8vrsom" }, "source": [ "NumPy 配列と `tf.Tensor` の間のもっとも明確な違いは\n", "\n", "1. テンソルは( GPU や TPU などの)アクセラレータメモリを使用できる\n", "2. テンソルは変更不可" ] }, { "cell_type": "markdown", "metadata": { "id": "Dwi1tdW3JBw6" }, "source": [ "### NumPy との互換性\n", "\n", "TensorFlow `tf.Tensor` と NumPy `ndarray` の変換は簡単です。\n", "\n", "- TensorFlow の演算により NumPy の ndarray は自動的にテンソルに変換される\n", "- NumPy の演算によりテンソルは自動的に NumPy の ndarray に変換される\n", "\n", "テンソルは `.numpy()` メソッドを使って明示的に NumPy の ndarray に変換されます。NumPy のndarray と `tf.Tensor` はその下敷きとなるメモリ上の表現が、できるかぎり共通化されているので、通常この変換のコストは小さいです。しかし、NumPy 配列はホスト側のメモリに置かれる一方、`tf.Tensor` はGPU のメモリに置かれる可能性もあるため、下層の表現をいつも共通化できるとは限りません。また、変換にはGPU からホスト側メモリへのコピーも関わってきます。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:46.752544Z", "iopub.status.busy": "2022-12-15T02:52:46.751912Z", "iopub.status.idle": "2022-12-15T02:52:46.761056Z", "shell.execute_reply": "2022-12-15T02:52:46.760310Z" }, "id": "lCUWzso6mbqR" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TensorFlow operations convert numpy arrays to Tensors automatically\n", "tf.Tensor(\n", "[[42. 42. 42.]\n", " [42. 42. 42.]\n", " [42. 42. 42.]], shape=(3, 3), dtype=float64)\n", "And NumPy operations convert Tensors to NumPy arrays automatically\n", "[[43. 43. 43.]\n", " [43. 43. 43.]\n", " [43. 43. 43.]]\n", "The .numpy() method explicitly converts a Tensor to a numpy array\n", "[[42. 42. 42.]\n", " [42. 42. 42.]\n", " [42. 42. 42.]]\n" ] } ], "source": [ "import numpy as np\n", "\n", "ndarray = np.ones([3, 3])\n", "\n", "print(\"TensorFlow operations convert numpy arrays to Tensors automatically\")\n", "tensor = tf.math.multiply(ndarray, 42)\n", "print(tensor)\n", "\n", "\n", "print(\"And NumPy operations convert Tensors to NumPy arrays automatically\")\n", "print(np.add(tensor, 1))\n", "\n", "print(\"The .numpy() method explicitly converts a Tensor to a numpy array\")\n", "print(tensor.numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "PBNP8yTRfu_X" }, "source": [ "## GPU による高速化\n", "\n", "多くの TensorFlow 演算の計算速度は、GPU を使って高速化されています。TensorFlow はアノテーションを使用せずに、GPU または CPU を演算に使用するかどうかを決定し、必要であれば CPU と GPU メモリ間でテンソルをコピーします。演算によって生成されたテンソルは、通常、演算が実行されたデバイスのメモリによってバックアップされます。以下に例を示します。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "cellView": "code", "execution": { "iopub.execute_input": "2022-12-15T02:52:46.764758Z", "iopub.status.busy": "2022-12-15T02:52:46.764037Z", "iopub.status.idle": "2022-12-15T02:52:46.770352Z", "shell.execute_reply": "2022-12-15T02:52:46.769705Z" }, "id": "3Twf_Rw-gQFM" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Is there a GPU available: \n", "[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:2', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:3', device_type='GPU')]\n", "Is the Tensor on GPU #0: \n", "True\n" ] } ], "source": [ "x = tf.random.uniform([3, 3])\n", "\n", "print(\"Is there a GPU available: \"),\n", "print(tf.config.list_physical_devices(\"GPU\"))\n", "\n", "print(\"Is the Tensor on GPU #0: \"),\n", "print(x.device.endswith('GPU:0'))" ] }, { "cell_type": "markdown", "metadata": { "id": "vpgYzgVXW2Ud" }, "source": [ "### デバイス名\n", "\n", "`Tensor.device` プロパティにより、そのテンソルの内容を保持しているデバイスの完全な名前文字列を得ることができます。この名前には、プログラムを実行中のホストのネットワークアドレスや、ホスト上のデバイスについての詳細がエンコードされています。この情報は、TensorFlow プログラムの分散実行に必要なものです。テンソルがホスト上の `N` 番目のGPUにある場合、文字列の最後は `GPU:` となります。" ] }, { "cell_type": "markdown", "metadata": { "id": "ZWZQCimzuqyP" }, "source": [ "### 明示的なデバイスの配置\n", "\n", "TensorFlow における「*配置*」とは、個々の演算を実行するデバイスの割り当てを指します。前述のとおり、明示的に指定されていない場合、TensorFlow は演算を実行するデバイスを自動的に決定し、必要であれば、そのデバイスにテンソルをコピーします。\n", "\n", "ただし、TensorFlow 演算は、`tf.device` コンテキストマネージャーを使用して、特定のデバイスに明示的に配置することが可能です。以下に例を示します。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:46.774170Z", "iopub.status.busy": "2022-12-15T02:52:46.773584Z", "iopub.status.idle": "2022-12-15T02:52:47.176749Z", "shell.execute_reply": "2022-12-15T02:52:47.175954Z" }, "id": "RjkNZTuauy-Q" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "On CPU:\n", "10 loops: 49.58ms\n", "On GPU:\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "10 loops: 343.95ms\n" ] } ], "source": [ "import time\n", "\n", "def time_matmul(x):\n", " start = time.time()\n", " for loop in range(10):\n", " tf.linalg.matmul(x, x)\n", "\n", " result = time.time()-start\n", "\n", " print(\"10 loops: {:0.2f}ms\".format(1000*result))\n", "\n", "# Force execution on CPU\n", "print(\"On CPU:\")\n", "with tf.device(\"CPU:0\"):\n", " x = tf.random.uniform([1000, 1000])\n", " assert x.device.endswith(\"CPU:0\")\n", " time_matmul(x)\n", "\n", "# Force execution on GPU #0 if available\n", "if tf.config.list_physical_devices(\"GPU\"):\n", " print(\"On GPU:\")\n", " with tf.device(\"GPU:0\"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.\n", " x = tf.random.uniform([1000, 1000])\n", " assert x.device.endswith(\"GPU:0\")\n", " time_matmul(x)" ] }, { "cell_type": "markdown", "metadata": { "id": "o1K4dlhhHtQj" }, "source": [ "## データセット\n", "\n", "このセクションでは、`tf.data.Dataset` API を使用して、モデルにデータを提供するためのパイプラインを構築しています。`tf.data.Dataset` は、パフォーマンスの高い複雑な入力パイプラインを、モデルのトレーニングまたは評価ループを提供する単純で再利用可能なピースから構築するために使用されます。(詳細については、[tf.data: TensorFlow 入力パイプラインを構築する](../../guide/data.ipynb)ガイドをご覧ください。)" ] }, { "cell_type": "markdown", "metadata": { "id": "zI0fmOynH-Ne" }, "source": [ "### ソース`Dataset`の作成\n", "\n", "*ソース* Dataset を作成するには、`tf.data.Dataset.from_tensors` や `tf.data.Dataset.from_tensor_slices` などのファクトリー関数を使用して、またはファイルから読み取る `tf.data.TextLineDataset` や `tf.data.TFRecordDataset` などのオブジェクトを使用します。詳細については、[tf.data: TensorFlow 入力パイプラインを構築する](../../guide/data.ipynb)ガイドの「*入力データを読み取る*」セクションをご覧ください。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:47.180798Z", "iopub.status.busy": "2022-12-15T02:52:47.180203Z", "iopub.status.idle": "2022-12-15T02:52:47.202960Z", "shell.execute_reply": "2022-12-15T02:52:47.202226Z" }, "id": "F04fVOHQIBiG" }, "outputs": [], "source": [ "ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])\n", "\n", "# Create a CSV file\n", "import tempfile\n", "_, filename = tempfile.mkstemp()\n", "\n", "with open(filename, 'w') as f:\n", " f.write(\"\"\"Line 1\n", "Line 2\n", "Line 3\n", " \"\"\")\n", "\n", "ds_file = tf.data.TextLineDataset(filename)" ] }, { "cell_type": "markdown", "metadata": { "id": "vbxIhC-5IPdf" }, "source": [ "### 変換の適用\n", "\n", "`tf.data.Dataset.map`、`tf.data.Dataset.batch`、`tf.data.Dataset.shuffle` などの変換関数を使用して、データセットのレコードに変換を適用します。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:47.207403Z", "iopub.status.busy": "2022-12-15T02:52:47.206657Z", "iopub.status.idle": "2022-12-15T02:52:47.225053Z", "shell.execute_reply": "2022-12-15T02:52:47.224287Z" }, "id": "uXSDZWE-ISsd" }, "outputs": [], "source": [ "ds_tensors = ds_tensors.map(tf.math.square).shuffle(2).batch(2)\n", "\n", "ds_file = ds_file.batch(2)" ] }, { "cell_type": "markdown", "metadata": { "id": "A8X1GNfoIZKJ" }, "source": [ "### イテレート\n", "\n", "`tf.data.Dataset` オブジェクトは、中のレコードを繰り返し利用するためのイテレーションをサポートします。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2022-12-15T02:52:47.229622Z", "iopub.status.busy": "2022-12-15T02:52:47.229013Z", "iopub.status.idle": "2022-12-15T02:52:47.270630Z", "shell.execute_reply": "2022-12-15T02:52:47.269845Z" }, "id": "ws-WKRk5Ic6-" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Elements of ds_tensors:\n", "tf.Tensor([1 9], shape=(2,), dtype=int32)\n", "tf.Tensor([ 4 16], shape=(2,), dtype=int32)\n", "tf.Tensor([25 36], shape=(2,), dtype=int32)\n", "\n", "Elements in ds_file:\n", "tf.Tensor([b'Line 1' b'Line 2'], shape=(2,), dtype=string)\n", "tf.Tensor([b'Line 3' b' '], shape=(2,), dtype=string)\n" ] } ], "source": [ "print('Elements of ds_tensors:')\n", "for x in ds_tensors:\n", " print(x)\n", "\n", "print('\\nElements in ds_file:')\n", "for x in ds_file:\n", " print(x)" ] } ], "metadata": { "accelerator": "GPU", "colab": { "collapsed_sections": [], "name": "basics.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.16" } }, "nbformat": 4, "nbformat_minor": 0 }