web-dev-qa-db-ja.com

tf.data.Dataset.map()とtf.data.Dataset.apply()の違い

最近のバージョン1.4へのアップグレードにより、Tensorflowはライブラリコアに_tf.data_を含めました。 バージョン1.4リリースノート で説明されている「主要な新機能」の1つは tf.data.Dataset.apply() です。これは「カスタム変換関数を適用する方法」です。これは既存の tf.data.Dataset.map() とどう違うのですか?

17
GPhilo

違いは、mapDatasetのすべての要素に対して個別に1つの関数を実行するのに対し、applyDataset全体に対して1つの関数を一度に実行することです(といった - group_by_window ドキュメントに例として示されています)。

applyの引数は、Datasetの引数が1つの要素を取り、1つの要素を返す関数である場合、Datasetを取り、mapを返す関数です。変換された要素。

22
Sunreef

サンリーフの答え は絶対に正しい。まだ疑問に思っているかもしれませんwhy私たちが導入した Dataset.apply() 、そして私はいくつかの背景を提供すると思いました。

_tf.data_ APIには、一連のcore変換(Dataset.map()Dataset.filter()など)があります。一般に、変更される可能性が低い広範囲のデータセットで有用であり、_tf.data.Dataset_オブジェクトのメソッドとして実装されます。特に、それらはTensorFlowの他のコアAPIと同じ 後方互換性保証 の対象となります。

ただし、コアアプローチは少し制限的です。また、新しい変換をコアに追加する前に実験し、他のライブラリ開発者が独自の再利用可能な変換を作成できるようにする自由も必要です。したがって、TensorFlow 1.4では、_tf.contrib.data_に存在するcustom変換のセットを分割しました。カスタム変換には、非常に特殊な機能を持つもの( tf.contrib.data.sloppy_interleave() など)と、APIがまだ流動的であるもの( tf.contrib.data.group_by_window()など) )。当初、これらのカスタム変換はDatasetからDatasetへの関数として実装しましたが、これはパイプラインの構文フローに不幸な影響を及ぼしました。例えば:

_dataset = tf.data.TFRecordDataset(...).map(...)

# Method chaining breaks when we apply a custom transformation.
dataset = custom_transformation(dataset, x, y, z)

dataset = dataset.shuffle(...).repeat(...).batch(...)
_

これは一般的なパターンのようであるため、単一のパイプラインでコア変換とカスタム変換をチェーンする方法としてDataset.apply()を追加しました。

_dataset = (tf.data.TFRecordDataset(...)
           .map(...)
           .apply(custom_transformation(x, y, z))
           .shuffle(...)
           .repeat(...)
           .batch(...))
_

それは物事の壮大なスキームのマイナーな機能ですが、願わくば_tf.data_プログラムを読みやすくし、ライブラリを拡張しやすくするのに役立ちます。

15
mrry

コメントするのに十分な評判はありませんが、彼の投稿に対する@sunreefのコメントに反して、データセット内の複数の要素に実際にマップを適用できることを指摘したかっただけです。

ドキュメントによると、マップは引数として取ります

map_func:テンソルのネストされた構造(self.output_shapesおよびself.output_typesで定義された形状と型を持つ)を、別のネストされたテンソルの構造にマッピングする関数。

output_shapesはデータセットによって定義され、バッチなどのAPI関数を使用して変更できます。したがって、たとえば、dataset.batchと.mapのみを使用してバッチ正規化を行うことができます。

_dataset = dataset ...
dataset.batch(batch_size)
dataset.map(normalize_fn)
_

apply()の主なユーティリティは、本当にデータセット全体にわたって変換を行いたい場合です。

3
zephyrus