Path: blob/master/site/ja/guide/keras/preprocessing_layers.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
前処理レイヤーを使用する
Keras 前処理レイヤー
Keras 前処理レイヤー API を使用すると、開発者は Keras ネイティブの入力処理パイプラインを構築できます。これらの入力処理パイプラインは、Keras 以外のワークフローで独立した前処理コードとして使用し、Keras モデルと直接組み合わせて、Keras SavedModel の一部としてエクスポートできます。
Keras 前処理レイヤーを使用すると、真にエンドツーエンドのモデル(生の画像または生の構造化データを入力として受け入れるモデルや特徴の正規化または特徴値のインデックス作成を独自に処理するモデル)を構築およびエクスポートできます。
利用可能な前処理
テキストの前処理
tf.keras.layers.TextVectorization
: 生の文字列を、Embedding
レイヤーまたはDense
レイヤーで読み取ることができるエンコードされた表現に変換します。
数値特徴量の前処理
tf.keras.layers.Normalization
: 入力した特徴量を特徴量ごとに正規化します。tf.keras.layers.Discretization
: 連続数値の特徴量を整数カテゴリカル特徴量に変換します。
カテゴリカル特徴量の前処理
tf.keras.layers.CategoryEncoding
: 整数のカテゴリカル特徴量をワンホット、マルチホット、またはカウントデンス表現に変換します。tf.keras.layers.Hashing
: カテゴリカル特徴量ハッシュ (ハッシュトリック) を実行します。tf.keras.layers.StringLookup
: 文字列のカテゴリカル値を、Embedding
レイヤーやDense
レイヤーで読み取れるエンコードされた表現に変換します。tf.keras.layers.IntegerLookup
: 整数のカテゴリ値を、Embedding
レイヤーまたはDense
レイヤーで読み取ることができるエンコードされた表現に変換します。
画像の前処理
これらのレイヤーは、画像モデルの入力を標準化するためのものです。
tf.keras.layers.Resizing
: 画像のバッチのサイズをターゲットサイズに変更します。tf.keras.layers.Rescaling
: 画像のバッチの値を再スケーリングおよびオフセットします(たとえば、[0, 255]
範囲の入力から[0, 1]
範囲の入力に移動します。)tf.keras.layers.CenterCrop
: 画像のバッチの中央の切り抜きを返します。
画像データ増強(デバイス上)
これらのレイヤーは、ランダムな増強変換を画像のバッチに適用します。これらはトレーニング中にのみアクティブになります。
tf.keras.layers.RandomCrop
tf.keras.layers.RandomFlip
tf.keras.layers.RandomTranslation
tf.keras.layers.RandomRotation
tf.keras.layers.RandomZoom
tf.keras.layers.RandomHeight
tf.keras.layers.RandomWidth
tf.keras.layers.RandomContrast
adapt()
メソッド
一部の前処理レイヤーには、トレーニングデータのサンプルに基づいて計算できる内部状態があります。ステートフル前処理レイヤーのリストは次のとおりです。
TextVectorization
: 文字列トークンと整数インデックス間のマッピングを保持します。StringLookup
とIntegerLookup
: 入力値と整数インデックスの間のマッピングを保持します。Normalization
: 特徴量の平均と標準偏差を保持します。Discretization
: 値バケットの境界に関する情報を保持します。
これらのレイヤーはトレーニング不可であることに注意してください。これらの状態はトレーニング中に設定されません。事前に計算された定数から初期化するか、データに「適応」させることにより、トレーニングの前に設定する必要があります。
adapt()
メソッドを使用して、トレーニングデータに前処理レイヤーを公開することにより、前処理レイヤーの状態を設定します。
adapt()
メソッドは、Numpy 配列またはtf.data.Dataset
オブジェクトのいずれかを取ります。StringLookup
およびTextVectorization
の場合、文字列のリストを渡すこともできます。
さらに、適応可能なレイヤーは、コンストラクタ引数または重みの割り当てを介して状態を直接設定するオプションを常に公開します。意図した状態値がレイヤー構築時にわかっている場合、またはadapt()
呼び出しの外で計算される場合は、レイヤーの内部計算に依存せずに設定できます。例えば、TextVectorization
、StringLookup
、または、IntegerLookup
レイヤーの外部語彙ファイルがすでに存在する場合、レイヤーのコンストラクタ引数で語彙ファイルへのパスを渡すことにより、それらをルックアップテーブルに直接読み込めます。
以下の例では、事前に計算された語彙を使用してStringLookup
レイヤーをインスタンス化します。
モデルの前またはモデル内のデータの前処理
前処理レイヤーを使用する方法は 2 つあります。
オプション 1: 次のように、それらをモデルの一部にします。
このオプションを使用すると、モデルの残りの実行と同期してデバイス上で前処理が行われるため、GPU アクセラレーションの恩恵を受けることができます。GPU でトレーニングしている場合、これはNormalization
レイヤー、およびすべての画像前処理レイヤーとデータ増強レイヤーに最適なオプションです。
オプション 2: これをtf.data.Dataset
に適用して、次のように前処理されたデータのバッチを生成するデータセットを取得します。
このオプションを使用すると、前処理は CPU で非同期に行われ、モデルに入れる前にバッファリングされます。
これは、TextVectorization
およびすべての構造化データ前処理レイヤーに最適なオプションです。CPU でトレーニングしていて、画像前処理レイヤーを使用している場合にも、これは良いオプションです。
TPU で実行する場合は、常に前処理レイヤーを tf.data
パイプラインに配置する必要があります (Normalization
と Rescaling
は、TPU で正常に実行され、最初のレイヤーが画像モデルとして一般的に使用されます)。
推論時にモデル内で前処理を行うことの利点
オプション 2 を選択した場合でも、後で前処理レイヤーを含む推論のみのエンドツーエンドモデルをエクスポートしたい場合があります。これを行う主な利点は、モデルを移植可能にすることと、**トレーニング/サービングスキュー**を減らせることです。
すべてのデータ前処理がモデルの一部である場合、他のユーザーは、各特徴がどのようにエンコードおよび正規化されるかを知らなくても、モデルを読み込んで使用できます。推論モデルは生の画像または生の構造化データを処理できるようになり、モデルのユーザーは画像のピクセル値が[-1, +1]
、または、[0, 1]
に正規化されていても、テキストに使用されるトークン化スキーム、カテゴリカルフィーチャに使用されるインデックススキームの詳細を認識する必要はありません。これは、モデルを TensorFlow.js などの別のランタイムにエクスポートする場合に特に有用です。JavaScript で前処理パイプラインを再実装する必要はありません。
最初に前処理レイヤーをtf.data
パイプラインに配置した場合、前処理をパッケージ化する推論モデルをエクスポートできます。前処理レイヤーとトレーニングモデルをチェーンする新しいモデルをインスタンス化するだけです。
クイックレシピ
画像データ増強(デバイス上)
画像データ増強レイヤーはトレーニング中にのみアクティブになることに注意してください(Dropout
レイヤーと同様)。
画像分類を最初から行うの例で同様の設定が実際に行われていることを確認できます。
数値的特徴の正規化
ワンホットエンコーディングによる文字列カテゴリカルフィーチャのエンコーディング
ここで、インデックス 0 は、語彙外の値 (adapt()
中に表示されなかった値) 用に予約されていることに注意してください。
構造化データ分類を最初から行うの例で、StringLookup
の動作を確認できます。
ワンホットエンコーディングによる整数カテゴリカルフィーチャのエンコーディング
インデックス 0 は欠落している値 (値 0 として指定する必要があります) 用に予約されており、インデックス 1 は語彙外の値 (adapt()
中に表示されなかった値) 用に予約されていることに注意してください) 。これは、IntegerLookup
のmask_token
と oov_token
コンストラクター引数を使用して構成できます
構造化データ分類を最初から行うの例で、IntegerLookup
の動作を確認できます。
整数のカテゴリカルフィーチャにハッシュトリックを適用する
多くの異なる値(10 の 3 乗以上の桁)をとることができるカテゴリカルフィーチャがあり、各値がデータに数回しか表示されない場合、特徴値にインデックスを付けてワンホットエンコードすることは非現実的で効果的ではありません。このような場合は、代わりに、固定サイズのベクトルに値をハッシュする「ハッシュトリック」を適用することをお勧めします。これにより、特徴スペースのサイズが管理しやすくなり、明示的なインデックス作成が不要になります。
トークンインデックスのシーケンスとしてテキストをエンコードする
以下は、Embedded
レイヤーに渡されるテキストを前処理する方法です。
テキスト分類を最初から行うの例では、Embedded
モードと組み合わされてTextVectorization
レイヤーが動作する方法を確認できます。
このようなモデルをトレーニングする場合、最高のパフォーマンスを得るには、入力パイプラインの一部としてTextVectorization
レイヤーを使用する必要があることに注意してください(上記のテキスト分類の例で示すように)。
マルチホットエンコーディングを使用した ngram の密な行列としてのテキストのエンコーディング
これは、Dense
レイヤーに渡されるテキストを前処理する方法です。
TF-IDF 重み付けを使用した ngramの 密な行列としてのテキストのエンコード
これは、テキストをDense
レイヤーに渡す前に前処理する別の方法です。
重要な点
ルックアップレイヤーの語彙が非常に多い場合
TextVectorization
、StringLookup
レイヤー、または IntegerLookup
レイヤーで非常に多くの語彙がある場合があります。通常、500MB を超える語彙は「非常に多い」と見なされます。
このような場合、最高のパフォーマンスを得るには、adapt()
の使用を避ける必要があります。代わりに、事前に語彙を計算し (これには、Apache Beam または TF Transform を使用できます)、ファイルに保存します。次に、ファイルパスを vocabulary
引数として渡すことにより、構築時に語彙をレイヤーに読み込みます。
TPU ポッドまたは ParameterServerStrategy
でルックアップレイヤーを使用する
TPU ポッドや複数のマシンで ParameterServerStrategy
によってトレーニングする際に、TextVectorization
、StringLookup
、または IntegerLookup
レイヤーを使用すると、パフォーマンスが劣化する未解決の問題があります。これは、TensorFLおw2.7 で修正される予定です。