私はTFの新機能、つまりData APIを使用しようとしていますが、prefetchがどのように機能するかわかりません。以下のコードで
_def dataset_input_fn(...)
dataset = tf.data.TFRecordDataset(filenames, compression_type="ZLIB")
dataset = dataset.map(lambda x:parser(...))
dataset = dataset.map(lambda x,y: image_augmentation(...)
, num_parallel_calls=num_threads
)
dataset = dataset.shuffle(buffer_size)
dataset = dataset.batch(batch_size)
dataset = dataset.repeat(num_epochs)
iterator = dataset.make_one_shot_iterator()
_
上記の各行の間で重要ですか?dataset=dataset.prefetch(batch_size)
を入れますか?または、データセットが_output_buffer_size
_から来ている場合は、_tf.contrib.data
_を使用するすべての操作の後である必要がありますか?
github に関する議論で、mrryによるコメントを見つけました。
TF 1.4には、map()の直後だけでなく、パイプラインの任意のポイントでプリフェッチを簡単に追加できるようにするDataset.prefetch()メソッドがあることに注意してください。 (現在のナイトリービルドをダウンロードして試してください。)
そして
たとえば、Dataset.prefetch()はバックグラウンドスレッドを開始して、tf.FIFOQueueのように動作する順序付けられたバッファーを設定します。そのため、ダウンストリームパイプラインステージはブロックする必要がありません。ただし、prefetch()の実装は、tf.FIFOQueueほど多くの異なる同時操作をサポートする必要がないため、はるかに単純です。
つまり、プリフェッチはどのコマンドでも実行でき、前のコマンドで機能します。これまでのところ、最後にだけ置くことで最大のパフォーマンス向上に気付きました。
Dataset.map、Dataset.prefetchおよびDataset.shuffleのbuffer_sizeの意味 でもう1つの議論があります。mryはプリフェッチとバッファについてもう少し説明します。
UPDATE 2018/10/01:
バージョン1.7.0から、データセットAPI(contrib内)にはprefetch_to_device
。この変換はパイプラインの最後でなければならず、TF 2.0が到着するとcontrib
がなくなることに注意してください。複数のGPUでプリフェッチを動作させるには、MultiDeviceIterator
を使用してください(例: #1361 ) multi_device_iterator_ops.py を参照してください。
https://www.tensorflow.org/versions/master/api_docs/python/tf/contrib/data/prefetch_to_device