{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "SB93Ge748VQs" }, "source": [ "##### Copyright 2019 The TensorFlow Authors." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "cellView": "form", "id": "0sK8X2O9bTlz" }, "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": "HEYuO5NFwDK9" }, "source": [ "# TensorFlow グラフを調査する\n", "\n", "\n", " \n", " \n", " \n", " \n", "
TensorFlow.org で表示Google Colab で実行GitHub でソースを表示ノートブックをダウンロード
" ] }, { "cell_type": "markdown", "metadata": { "id": "56V5oun18ZdZ" }, "source": [ "## 概要\n", "\n", "TensorBoard の **Graphs ダッシュボード**は、TensorFlow モデルを調べるために使用できる強力なツールです。モデルの構造の概念的なグラフを素早く表示し、意図した設計と一致することを確認することができます。また、演算レベルのグラフも表示できるため、TensorFlow がどのようにプログラムを理解しているかを把握することができます。演算レベルグラフを調査すると、モデルの変更方法に関する洞察を得ることができます。たとえば、トレーニングの進行速度が思ったより遅い場合に、モデルを再設計することが可能となります。" ] }, { "cell_type": "markdown", "metadata": { "id": "TOSJ-4nteBYG" }, "source": [ "このチュートリアルでは、グラフの診断データを生成して TensorBoard の Graph ダッシュボードで視覚化する方法を簡単に説明します。チュートリアルでは、Fashion-MNIST データセットの簡単な Keras Sequential モデルを定義してトレーニングし、モデルグラフのログと調査の方法を学習します。また、トレーニング API を使用して、新しい `tf.function` 注釈を使って作成した関数のグラフデータを生成します。" ] }, { "cell_type": "markdown", "metadata": { "id": "zNI1-dflrAo0" }, "source": [ "## セットアップ" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "6B95Hb6YVgPZ" }, "outputs": [], "source": [ "# Load the TensorBoard notebook extension.\n", "%load_ext tensorboard" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "_wqSAZExy6xV" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TensorFlow version: 2.2.0\n" ] } ], "source": [ "from datetime import datetime\n", "from packaging import version\n", "\n", "import tensorflow as tf\n", "from tensorflow import keras\n", "\n", "print(\"TensorFlow version: \", tf.__version__)\n", "assert version.parse(tf.__version__).release[0] >= 2, \\\n", " \"This notebook requires TensorFlow 2.0 or above.\"" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "qRZlYIEcJ56Z" }, "outputs": [ { "data": { "text/plain": [ "'2.2.1'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import tensorboard\n", "tensorboard.__version__" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "Ao7fJW1Pyiza" }, "outputs": [], "source": [ "# Clear any logs from previous runs\n", "!rm -rf ./logs/ " ] }, { "cell_type": "markdown", "metadata": { "id": "e25E37vd1xEW" }, "source": [ "## Keras モデルを定義する\n", "\n", "この例では、単純な 4 つのレイヤーを使った Sequential モデルを分類器とします。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "id": "skqORzvE3Egy" }, "outputs": [], "source": [ "# Define the model.\n", "model = keras.models.Sequential([\n", " keras.layers.Flatten(input_shape=(28, 28)),\n", " keras.layers.Dense(32, activation='relu'),\n", " keras.layers.Dropout(0.2),\n", " keras.layers.Dense(10, activation='softmax')\n", "])\n", "\n", "model.compile(\n", " optimizer='adam',\n", " loss='sparse_categorical_crossentropy',\n", " metrics=['accuracy'])" ] }, { "cell_type": "markdown", "metadata": { "id": "qbjuoz9E3VC_" }, "source": [ "トレーニングデータをダウンロードして準備します。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "6TDmc41z3g38" }, "outputs": [], "source": [ "(train_images, train_labels), _ = keras.datasets.fashion_mnist.load_data()\n", "train_images = train_images / 255.0" ] }, { "cell_type": "markdown", "metadata": { "id": "8DV0xibO3bRC" }, "source": [ "## モデルをトレーニングしてデータをログする\n", "\n", "トレーニングの前に、ログディレクトリを指定して [Keras TensorBoard コールバック](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/TensorBoard)を定義します。Model.fit() にこのコールバックを渡すことで、グラフデータが TensorBoard で視覚化できるようにログされるようにします。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "TU_L_u9SqQdH" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/5\n", "938/938 [==============================] - 2s 2ms/step - loss: 0.6955 - accuracy: 0.7618\n", "Epoch 2/5\n", "938/938 [==============================] - 2s 2ms/step - loss: 0.4877 - accuracy: 0.8296\n", "Epoch 3/5\n", "938/938 [==============================] - 2s 2ms/step - loss: 0.4458 - accuracy: 0.8414\n", "Epoch 4/5\n", "938/938 [==============================] - 2s 2ms/step - loss: 0.4246 - accuracy: 0.8476\n", "Epoch 5/5\n", "938/938 [==============================] - 2s 2ms/step - loss: 0.4117 - accuracy: 0.8508\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Define the Keras TensorBoard callback.\n", "logdir=\"logs/fit/\" + datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n", "tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)\n", "\n", "# Train the model.\n", "model.fit(\n", " train_images,\n", " train_labels, \n", " batch_size=64,\n", " epochs=5, \n", " callbacks=[tensorboard_callback])" ] }, { "cell_type": "markdown", "metadata": { "id": "IRX5OIsi4TTV" }, "source": [ "## 演算レベルグラフ\n", "\n", "TensorBoard を起動し、UI が読み込まれるまで数秒ほど待ってから、上部にある「Graph」をタップして、Graphs ダッシュボードを選択します。 " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "PFgFjlPEqXb9" }, "outputs": [], "source": [ "%tensorboard --logdir logs" ] }, { "cell_type": "markdown", "metadata": { "id": "9PFgFjlPEqXb" }, "source": [ "オプションで TensorBoard.dev を使用して、ホストされた共有可能な実験を作成することもできます。 " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "b9PFgFjlPEqX" }, "outputs": [], "source": [ "!tensorboard dev upload \\\n", " --logdir logs \\\n", " --name \"Sample op-level graph\" \\\n", " --one_shot" ] }, { "cell_type": "markdown", "metadata": { "id": "EGlOqRp54ufD" }, "source": [ "デフォルトでは、TensorBoard には**演算レベルグラフ**が表示されます(左側に、「Default」タグが選択されているのがわかります)。グラフが反転していることに注意してください。データは下から上に向かって流れているため、コードと比較すると逆さまになっています。それでも、グラフが Keras モデルに緊密に一致しており、ほかの計算ノードへのエッジが追加されていることはわかるでしょう。\n", "\n", "グラフは非常に大きいことが多いですが、グラフ表示を操作することができます。\n", "\n", "- スクロールで**拡大縮小**\n", "- ドラッグで**パン**\n", "- ダブルクリックで**ノード展開**の切り替え(ノードはほかのノードのコンテナである場合があります)\n", "\n", "また、ノードをクリックしてメタデータを表示することもできます。こうすると、入力、出力、およびその他の詳細を確認することができます。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "F-2yw5qd7OpK" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "jDRynpVw53SJ" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "Oj9FSPdz6SO2" }, "source": [ "## 概念グラフ\n", "\n", "TensorBoard には、実行グラフのほかに**概念グラフ**も表示されます。これは Keras モデルのみのビューです。保存したモデルを再利用する際に構造を調査または検証する場合に役立ちます。\n", "\n", "概念グラフを表示するには、「keras」タグを選択します。折り畳まれた **Sequential** ノードが表示されますが、それをダブルクリックすると、モデルの構造を確認できます。" ] }, { "cell_type": "markdown", "metadata": { "id": "Qw9rbEcE6eZB" }, "source": [ "
\n", "" ] }, { "cell_type": "markdown", "metadata": { "id": "zVuaKBifu-qF" }, "source": [ "## tf.function のグラフ\n", "\n", "これまでの例では、Keras レイヤーを定義して Model.fit() を呼び出すことでグラフを作成するという、Keras モデルのグラフについて説明しました。\n", "\n", "`tf.function` 注釈を使用して、「[グラフの自動作成](https://www.tensorflow.org/guide/function)」、つまり Python 計算関数を高性能 TensorFlow グラフに変換しなければならない状況に遭遇することがあるかもしれません。こういった場合には、**TensorFlow Summary Trace API** を使用して、TensorBoard に視覚化するための自動グラフ作成関数をログすることができます。" ] }, { "cell_type": "markdown", "metadata": { "id": "JIuhJnQ8w-dT" }, "source": [ "Summary Trace API を使用するには、次を行います。\n", "\n", "- 関数を定義して、`tf.function` で注釈をつけます。\n", "- 関数呼び出しの直前に `tf.summary.trace_on()` を使用します。\n", "- `profiler=True` を渡して、グラフにプロファイル情報(メモリ、CPU 時間)を追加します。\n", "- サマリーファイルライターを使って、`tf.summary.trace_export()` を呼び出してログデータを保存します。\n", "\n", "その後、TensorBoard を使用すると、関数の動作を確認することができます。\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "woI67Stgv_uY" }, "outputs": [], "source": [ "# The function to be traced.\n", "@tf.function\n", "def my_func(x, y):\n", " # A simple hand-rolled layer.\n", " return tf.nn.relu(tf.matmul(x, y))\n", "\n", "# Set up logging.\n", "stamp = datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n", "logdir = 'logs/func/%s' % stamp\n", "writer = tf.summary.create_file_writer(logdir)\n", "\n", "# Sample data for your function.\n", "x = tf.random.uniform((3, 3))\n", "y = tf.random.uniform((3, 3))\n", "\n", "# Bracket the function call with\n", "# tf.summary.trace_on() and tf.summary.trace_export().\n", "tf.summary.trace_on(graph=True, profiler=True)\n", "# Call only one tf.function when tracing.\n", "z = my_func(x, y)\n", "with writer.as_default():\n", " tf.summary.trace_export(\n", " name=\"my_func_trace\",\n", " step=0,\n", " profiler_outdir=logdir)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "zCArnWzP0VuZ" }, "outputs": [], "source": [ "%tensorboard --logdir logs/func" ] }, { "cell_type": "markdown", "metadata": { "id": "WDl1PBFQ64xi" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "1pLRaf3q6Nku" }, "source": [ "これで、TensorBoard が理解する通りの関数の構造を確認できるようになりました。「Profile」ラジオボタンをクリックすると、CPU とメモリの統計データを確認できます。" ] } ], "metadata": { "colab": { "collapsed_sections": [ "SB93Ge748VQs" ], "name": "graphs.ipynb", "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 0 }