Path: blob/master/site/ja/guide/sparse_tensor_guide.ipynb
25115 views
Copyright 2020 The TensorFlow Authors.
スパーステンソルの使用
多くのゼロ値を含むテンソルを使用する場合、それらをスペース効率と時間効率の高い方法で格納することが重要です。スパーステンソルは、多くのゼロ値を含むテンソルの効率的な格納と処理を可能にします。スパーステンソルは、TF-IDF などのエンコードスキームで、NLP アプリケーションでのデータ前処理の一部として広く使用されています。また、コンピュータビジョンアプリケーションで多くの暗いピクセルを含む画像を前処理するために使用されています。
TensorFlow のスパーステンソル
TensorFlow は、tf.sparse.SparseTensor
オブジェクトを通じてスパーステンソルを表します。現在、TensorFlow のスパーステンソルは、COO 形式 (座標形式) を使用してエンコードされています。 このエンコード形式は、埋め込みなどの超疎行列用に最適化されています。
スパーステンソルの COO エンコーディングは、次で構成されます。
values
: すべての非ゼロ値を含む形状[N]
の 1 次元テンソル。indices
: 非ゼロ値のインデックスを含む、[N, rank]
の形状を持つ 2 次元テンソル。dense_shape
: テンソルの形状を指定する、形状[rank]
を持つ 1 次元テンソル。
tf.sparse.SparseTensor
のコンテキストにおける非ゼロ値は、明示的にエンコードされていない値です。COO 疎行列の values
にゼロ値を明示的に含めることは可能ですが、スパース テンソルで非ゼロ値を参照する場合、これらの「明示的なゼロ」は通常含まれません。
注意: tf.sparse.SparseTensor
では、インデックス/値が特定の順序である必要はありませんが、いくつかの演算は行優先の順序であると想定しています。tf.sparse.reorder
を使用して、標準の行優先順で並べ替えられたスパーステンソルのコピーを作成します。
tf.sparse.SparseTensor
の構築
values
、indices
、および dense_shape
を直接指定して、スパーステンソルを構築します。
print()
関数を使用してスパーステンソルを出力すると、3 つの成分テンソルの内容が表示されます。
非ゼロの values
が対応する indices
と整列している場合、スパーステンソルの内容が理解しやすくなります。非ゼロ値がそれぞれの行に表示されるようにスパーステンソルを出力するヘルパー関数を定義します。
また、tf.sparse.from_dense
を使用して密テンソルからスパーステンソルを構築し、tf.sparse.to_dense
を使用してそれらを密テンソルに戻すこともできます。
スパーステンソルの操作
tf.sparse
パッケージのユーティリティを使用して、スパーステンソルを操作します。密なテンソルに使用できる tf.math.add
のような算術演算は、スパーステンソルでは機能しません。
tf.sparse.add
を使用して、同じ形状のスパーステンソルを追加します。
tf.sparse.sparse_dense_matmul
を使用して、スパーステンソルと密行列を乗算します。
tf.sparse.concat
を使用してスパーステンソルをまとめ、tf.sparse.slice
を使用してそれらをスライスします。
TensorFlow 2.4 以降を使用している場合は、スパーステンソルのゼロ以外の値に対する要素ごとの演算に tf.sparse.map_values
を使用します。
ゼロ以外の値のみが変更されたことに注意してください。ゼロ値はゼロのままです。
同様に、TensorFlow の以前のバージョンでは、以下の設計パターンに従います。
他の TensorFlow API で tf.sparse.SparseTensor
を使用する
スパーステンソルは、これらの TensorFlow API で透過的に動作します。
tf.keras
tf.data
tf.Train.Example
protobuftf.function
tf.while_loop
tf.cond
tf.identity
tf.cast
tf.print
tf.saved_model
tf.io.serialize_sparse
tf.io.serialize_many_sparse
tf.io.deserialize_many_sparse
tf.math.abs
tf.math.negative
tf.math.sign
tf.math.square
tf.math.sqrt
tf.math.erf
tf.math.tanh
tf.math.bessel_i0e
tf.math.bessel_i1e
上記の API のいくつかの例を以下に示します。
tf.keras
tf.keras
API のサブセットは、コストが高いキャストや変換演算なしでスパーステンソルをサポートします。Keras API を使用すると、スパーステンソルを入力として Keras モデルに渡すことができます。tf.keras.Input
または tf.keras.layers.InputLayer
を呼び出すときには sparse=True
を設定します。 Keras レイヤー間でスパーステンソルを渡し、Keras モデルがそれらを出力として返すようにすることもできます。モデルの tf.keras.layers.Dense
レイヤーでスパーステンソルを使用すると、密テンソルが出力されます。
以下の例は、スパース入力をサポートするレイヤーのみを使用する場合に、スパーステンソルを入力として Keras モデルに渡す方法を示しています。
tf.data
tf.data は、単純で再利用可能な部分から複雑な入力パイプラインを構築できる API です。主なデータ構造は tf.data.Dataset
で、一連の要素を表し、その各要素には 1 つ以上の成分が含まれます。
スパーステンソルを使用したデータセットの構築
tf.data.Dataset.from_tensor_slices
など、tf.Tensor
または NumPy 配列からデータセットを構築するために使用されるメソッドを使用して、スパーステンソルからデータセットを構築します。この演算は、データのスパース性を保持します。
スパーステンソルを使用したデータセットのバッチ処理とバッチ処理解除
スパーステンソルを使用してデータセットをバッチ処理 (連続する要素を 1 つの要素に結合) およびバッチ処理解除できます。バッチ処理には Dataset.batch
メソッド、バッチ処理解除には Dataset.unbatch
メソッドを使用します。
また、tf.data.experimental.dense_to_sparse_batch
を使用して、さまざまな形状のデータセット要素をスパーステンソルにバッチ処理することもできます。
スパーステンソルを使用したデータセットの変換
Dataset.map
を使用して、データセット内のスパーステンソルを変換および作成します。
tf.train.Example
tf.train.Example
は、TensorFlow データの標準の protobuf エンコーディングです。tf.train.Example
でスパーステンソルを使用すると、次のことができます。
tf.io.VarLenFeature
を使用して、可変長データをtf.sparse.SparseTensor
に読み込みますが、代わりにtf.io.RaggedFeature
の使用を検討する必要があります。tf.io.SparseFeature
を使用して任意のスパースデータをtf.sparse.SparseTensor
に読み込みます。これは 3 つの個別の特徴キーを使用してindices
、values
、およびdense_shape
を格納します。
tf.function
tf.function
は、Python 関数向けに TensorFlow グラフを事前計算するデコレータで、TensorFlow コードのパフォーマンスを大幅に向上できます。スパーステンソルは、tf.function
と concrete functions の両方で透過的に動作します。
欠損値とゼロ値の区別
tf.sparse.SparseTensor
のほとんどの演算は、欠損値と明示的なゼロ値を同じように扱います。これは設計によるもので、tf.sparse.SparseTensor
は密なテンソルのように振る舞います。
ただし、ゼロ値と欠損値を区別することが役立つ場合がいくつかあります。特に、トレーニングデータ内の欠落/不明なデータをエンコードする場合に便利です。たとえば、スコアのテンソル (-Inf から +Inf までの任意の浮動小数点値を持つことができる) があり、スコアが欠落しているユースケースを考えてみます。このテンソルは、明示的なゼロが既知のゼロスコアであるスパーステンソルを使用してエンコードできますが、暗黙的なゼロ値は実際には欠損データを表し、ゼロではありません。
注意: これは一般的に、tf.sparse.SparseTensor
の意図した使用法ではないので、既知/未知の値の位置を識別する別のマスクテンソルを使用するなど、これをエンコードするための他の手法も検討してみてください。ただし、ほとんどのスパース演算は明示的ゼロ値と暗黙的ゼロ値を同じように扱うため、このアプローチを使用するときは注意してください。
tf.sparse.reduce_max
のような一部の演算は、欠損値をゼロであるかのように扱わないことに注意してください。たとえば、以下のコードブロックを実行すると、期待される出力は 0
になります。ただし、この例外のため、出力は -3
になります。
対照的に、密テンソルに tf.math.reduce_max
を適用すると、出力は予想どおり 0 になります。
その他の資料とリソース
テンソルについての詳細は、テンソルガイドを参照してください。
不均一なデータを扱うテンソルの一種である不規則テンソルの使用方法については、不規則テンソルガイドを参照してください。
tf.Example
データデコーダでスパーステンソルを使用する TensorFlow Model Garden のオブジェクト検出モデルをご確認ください。