Path: blob/master/site/ja/guide/intro_to_modules.ipynb
25115 views
Copyright 2020 The TensorFlow Authors.
モジュール、レイヤー、モデルの概要
TensorFlow で機械学習を実行するには、モデルを定義、保存、復元する必要があります。
モデルは、抽象的に次のように定義できます。
テンソルで何かを計算する関数(フォワードパス)
トレーニングに応じて更新できる何らかの変数
このガイドでは、Keras 内で TensorFlow モデルがどのように定義されているか、そして、TensorFlow が変数とモデルを収集する方法、および、モデルを保存および復元する方法を説明します。
注意:今すぐ Keras を使用するのであれば、一連の Keras ガイドをご覧ください。
セットアップ
TensorFlow モジュール
ほとんどのモデルはレイヤーで構成されています。レイヤーは、再利用およびトレーニング可能な変数を持つ既知の数学的構造を持つ関数です。TensorFlow では、Keras や Sonnet といった、レイヤーとモデルの高位実装の多くは、同じ基本クラスの tf.Module
に基づいて構築されています。
モジュールの構築
スカラーテンソルで動作する非常に単純な tf.Module
の例を次に示します。
モジュールと(その延長としての)レイヤーは、「オブジェクト」のディープラーニング用語です。これらには、内部状態と、その状態を使用するメソッドがあります。
__ call__
は Python コーラブルのように動作する以外何も特別なことではないため、任意の関数を使用してモデルを呼び出すことができます。
ファインチューニング中のレイヤーと変数を凍結するなど、様々な理由で、変数をトレーニング対象とするかどうかを設定することができます。
注意: tf.Module
は tf.keras.layers.Layer
と tf.keras.Model
の基本クラスであるため、ここに説明されているすべての内容は Keras にも当てはまります。過去の互換性の理由から、Keras レイヤーはモジュールから変数を収集しないため、モデルはモジュールのみ、または Keras レイヤーのみを使用する必要があります。ただし、以下に示す変数の検査方法はどちらの場合も同じです。
tf.Module
をサブクラス化することにより、このオブジェクトのプロパティに割り当てられた tf.Variable
または tf.Module
インスタンスが自動的に収集されます。これにより、変数の保存や読み込みのほか、tf.Module
のコレクションを作成することができます。
これは、モジュールで構成された 2 層線形レイヤーモデルの例です。
最初の高密度(線形)レイヤーは以下のとおりです。
2 つのレイヤーインスタンスを作成して適用する完全なモデルは以下のとおりです。
tf.Module
インスタンスは、それに割り当てられた tf.Variable
または tf.Module
インスタンスを再帰的に自動収集します。これにより、単一のモデルインスタンスで tf.Module
のコレクションを管理し、モデル全体を保存して読み込むことができます。
変数の作成を延期する
ここで、レイヤーへの入力サイズと出力サイズの両方を定義する必要があることに気付いたかもしれません。これは、w
変数が既知の形状を持ち、割り当てることができるようにするためです。
モジュールが特定の入力形状で最初に呼び出されるまで変数の作成を延期することにより、入力サイズを事前に指定する必要がありません。
この柔軟性のため、多くの場合、TensorFlow レイヤーは、出力の形状(tf.keras.layers.Dense
)などを指定するだけで済みます。入出力サイズの両方を指定する必要はありません。
チェックポイントは、データ自体とメタデータのインデックスファイルの 2 種類のファイルで構成されます。インデックスファイルは、実際に保存されているものとチェックポイントの番号を追跡し、チェックポイントデータには変数値とその属性ルックアップパスが含まれています。
チェックポイントの内部を調べると、変数のコレクション全体が保存されており、変数を含む Python オブジェクト別に並べ替えられていることを確認できます。
分散(マルチマシン)トレーニング中にシャーディングされる可能性があるため、番号が付けられています(「00000-of-00001」など)。ただし、この例の場合、シャードは 1 つしかありません。
モデルを再度読み込むと、Python オブジェクトの値が上書きされます。
注意: チェックポイントは長いトレーニングワークフローでは重要であり、tf.checkpoint.CheckpointManager
はヘルパークラスとして、チェックポイント管理を大幅に簡単にすることができます。詳細については、トレーニングチェックポイントガイドをご覧ください。
関数の保存
TensorFlow は、TensorFlow Serving と TensorFlow Lite で見たように、元の Python オブジェクトなしでモデルを実行できます。また、TensorFlow Hub からトレーニング済みのモデルをダウンロードした場合でも同じです。
TensorFlow は、Pythonで説明されている計算の実行方法を認識する必要がありますが、元のコードは必要ありません。認識させるには、グラフを作成することができます。これについてはグラフと関数の入門ガイドをご覧ください。
このグラフには、関数を実装する演算が含まれています。
@tf.function
デコレータを追加して、このコードをグラフとして実行する必要があることを示すことにより、上記のモデルでグラフを定義できます。
作成したモジュールは、前と全く同じように動作します。関数に渡される一意のシグネチャごとにグラフが作成されます。詳細については、グラフと関数の基礎ガイドをご覧ください。
TensorBoard のサマリー内でグラフをトレースすると、グラフを視覚化できます。
TensorBoard を起動して、トレースの結果を確認します。
SavedModel
の作成
トレーニングが完了したモデルを共有するには、SavedModel
の使用が推奨されます。SavedModel
には関数のコレクションと重みのコレクションの両方が含まれています。
次のようにして、トレーニングしたモデルを保存することができます。
saved_model.pb
ファイルは、関数型の tf.Graph
を記述するプロトコルバッファです。
モデルとレイヤーは、それを作成したクラスのインスタンスを実際に作成しなくても、この表現から読み込めます。これは、大規模なサービスやエッジデバイスでのサービスなど、Python インタープリタがない(または使用しない)場合や、元の Python コードが利用できないか実用的でない場合に有用です。
モデルを新しいオブジェクトとして読み込みます。
保存したモデルを読み込んで作成された new_model
は、クラスを認識しない内部の TensorFlow ユーザーオブジェクトです。SequentialModule
ではありません。
この新しいモデルは、すでに定義されている入力シグネチャで機能します。このように復元されたモデルにシグネチャを追加することはできません。
したがって、SavedModel
を使用すると、tf.Module
を使用して TensorFlow の重みとグラフを保存し、それらを再度読み込むことができます。
Keras モデルとレイヤー
ここまでは、Keras に触れずに説明してきましたが、tf.Module
の上に独自の高位 API を構築することは可能です。
このセクションでは、Keras が tf.Module
をどのように使用するかを説明します。Keras モデルの完全なユーザーガイドは、Keras ガイドをご覧ください。
Keras レイヤーとモデルには、次のような多くの追加機能があります。
オプションの損失
メトリクスのサポート
トレーニングと推論の使用を区別する、オプションの
training
引数の組み込みサポートブラックボックス関数だけでなく、Python オブジェクトの保存と復元
Python でモデルのクローンを作成するための構成を正確に保存する
get_config
とfrom_config
メソッド
これらの機能によって、カスタム GAN や Variational AutoEncoder(VAE)など、サブクラス化を通じてはるかに複雑なモデルを使用できます。これらについては、カスタムレイヤーとモデルの完全ガイドをお読みください。
Keras モデルにも、トレーニング、評価、読み込み、保存、さらに複数のマシンでのトレーニングを簡単に行えるようにする追加機能が備わっています。
Keras レイヤー
tf.keras.layers.Layer
はすべての Keras レイヤーの基本クラスであり、tf.Module
から継承します。
親を交換してから、__call__
を call
に変更するだけで、モジュールを Keras レイヤーに変換できます。
Keras レイヤーには独自の __call__
があり、次のセクションで説明する手順を実行してから、call()
を呼び出します。動作には違いはありません。
build
ステップ
前述のように、多くの場合都合よく、入力形状が確定するまで変数の作成を延期できます。
Keras レイヤーには追加のライフサイクルステップがあり、レイヤーをより柔軟に定義することができます。このステップは、build()
関数で定義されます。
build
は 1 回だけ呼び出され、入力形状で呼び出されます。通常、変数(重み)を作成するために使用されます。
上記の MyDense
レイヤーを、入力のサイズに柔軟に合わせられるように書き換えることができます。
この時点では、モデルは構築されていないため、変数も存在しません。
関数を呼び出すと、適切なサイズの変数が割り当てられます。
build
は 1 回しか呼び出されないため、入力形状がレイヤーの変数と互換性がない場合、入力は拒否されます。
Keras モデル
モデルはネストされた Keras レイヤーとして定義できます。
ただし、Keras は tf.keras.Model
と呼ばれるフル機能のモデルクラスも提供します。Keras モデルは tf.keras.layers.Layer
を継承しているため、 Keras レイヤーと同じ方法で使用し、ネストすることができます。Keras モデルには、トレーニング、評価、読み込み、保存、および複数のマシンでのトレーニングを容易にする追加機能があります。
上記の SequentialModule
をほぼ同じコードで定義できます。先ほどと同じように、__call__
をcall()
に変換して、親を変更します。
追跡変数やサブモジュールなど、すべて同じ機能を利用できます。
注意: Keras レイヤーまたはモデル内にネストされた生の tf.Module
は、トレーニングまたは保存のために変数を収集しません。代わりに、Keras レイヤーを Keras レイヤーの内側にネストします。
非常に Python 的なアプローチとして、tf.keras.Model
をオーバーライドして TensorFlow モデルを構築することができます。ほかのフレームワークからモデルを移行する場合、これは非常に簡単な方法です。
モデルが既存のレイヤーと入力の単純な集合として構築されている場合は、モデルの再構築とアーキテクチャに関する追加機能を備えた Functional API を使用すると手間とスペースを節約できます。
以下は、Functional API を使用した同じモデルです。
ここでの主な違いは、入力形状が関数構築プロセスの一部として事前に指定されることです。この場合、input_shape
引数を完全に指定する必要がないため、一部の次元を None
のままにしておくことができます。
注意:サブクラス化されたモデルでは、input_shape
や InputLayer
を指定する必要はありません。これらの引数とレイヤーは無視されます。
Keras モデルの保存
Keras モデルには、独自の特殊な zip アーカイブ保存形式があり、.keras
拡張子を使用します。tf.keras.Model.save
を呼び出す際は、以下の例のように .keras
拡張子をファイル名に追加します。
このように簡単に、読み込み直すことができます。
Keras zip アーカイブ(.keras
ファイル)は、メトリクス、損失、およびオプティマイザの状態も保存します。
再構築されたこのモデルを使用すると、同じデータで呼び出されたときと同じ結果が得られます。
Keras モデルにチェックポイントを設定する
Keras モデルでにはチェックポイントも設定可能で、 tf.Module
と同じように見えます。
機能サポートのためにカスタムレイヤーで使用できる構成メソッドなど、Keras モデルの保存とシリアル化についてのその他の詳細情報は、保存とシリアル化のガイドをご覧ください。