2017-12-05 7 views
1

Dataset-APIを使用して同じタスクを実行する場合、キューを使用するよりも10-100倍遅くなるようです。Tensorflowデータセットがキューと比較して非常に遅い

これは私がデータセットをどうしようとしていますものです:

キューと
dataset = tf.data.TFRecordDataset(filenames).repeat() 
dataset = dataset.batch(100) 
dataset = dataset.map(_parse_function) 
dataset = dataset.prefetch(1000) 
d = dataset.make_one_shot_iterator() 

%timeit -n 200 sess.run(d.get_next()) 

と、この:

filename_queue = tf.train.string_input_producer(filenames, capacity=1) 

reader = tf.TFRecordReader() 
_, serialized_example = reader.read_up_to(filename_queue, 100) 

features = _parse_function(serialized_example) 

coord = tf.train.Coordinator() 
threads = tf.train.start_queue_runners(sess=sess, coord=coord) 
tf.train.start_queue_runners() 

%timeit -n 200 sess.run(features) 

観察された結果:

データセット: 23.6 ms ± 8.73 ms per loop (mean ± std. dev. of 7 runs, 200 loops each)

キュー: 481 µs ± 91.7 µs per loop (mean ± std. dev. of 7 runs, 200 loops each)

これはどうしてですか?データセットをより速く動作させる方法


再現する1.4とPython 3.5

全コードtensorflow使用:

import tensorflow as tf 
import numpy as np 
import glob 
import os 


def _int64_feature(value): 
    return tf.train.Feature(int64_list=tf.train.Int64List(value=value)) 


def create_data(i): 
    tfrecords_filename = '_temp/dstest/tt%d.tfr' % i 

    writer = tf.python_io.TFRecordWriter(tfrecords_filename) 

    for j in range(1000): 
     f = tf.train.Features(feature={ 
      'x': _int64_feature([j]), 
      "y": _int64_feature(np.random.randint(5, 100, size=np.random.randint(6))) 
     }) 

     example = tf.train.Example(features=f) 
     writer.write(example.SerializeToString()) 

    writer.close() 
    return tfrecords_filename 


def _parse_function(example_proto): 
    features = { 
     "x": tf.FixedLenFeature((), tf.int64), 
     "y": tf.FixedLenSequenceFeature((), tf.int64, allow_missing=True) 
    } 
    parsed_features = tf.parse_example(example_proto, features) 
    return parsed_features 


os.makedirs("_temp/dstest", exist_ok=True) 
sess = tf.InteractiveSession() 

filenames = [create_data(i) for i in range(5)] 

#### DATASET 
dataset = tf.data.TFRecordDataset(filenames).repeat() 
dataset = dataset.batch(100) 
dataset = dataset.map(_parse_function) 
dataset = dataset.prefetch(1000) 
d = dataset.make_one_shot_iterator() 

%timeit -n 200 sess.run(d.get_next()) 

#### QUEUE 
filename_queue = tf.train.string_input_producer(filenames, capacity=1) 

reader = tf.TFRecordReader() 
_, serialized_example = reader.read_up_to(filename_queue, 100) 

features = _parse_function(serialized_example) 

coord = tf.train.Coordinator() 
threads = tf.train.start_queue_runners(sess=sess, coord=coord) 
tf.train.start_queue_runners() 

%timeit -n 200 sess.run(features) 

coord.request_stop() 
coord.join(threads) 

答えて

0

ああ、私はそれを考え出しました。私はd.get_next()に何回も電話するつもりはない。

私はそれがために変更する場合:

d = dataset.make_one_shot_iterator().get_next() 
%timeit -n 200 sess.run(d) 

その後、スピードもプリフェッチせずに、キューのバージョンに似ています。

そして、の結果は常に異なっています。

関連する問題