2017-01-26 21 views
4

トレーニングデータをメモリに読み込んで、同じサイズのシャッフルバッチを使用してnumpy配列としてグラフにフィードすると、データの速度が大きく違うことに気付きました。Tensorflow shuffle_batch speed

メモリを1000回使用すると、数秒もかかりませんが、シャッフルバッチを使用するとほぼ10分かかります。私はシャッフルバッチが少し遅くなるはずですが、これは遅すぎるようです。どうしてこれなの?

賞金が追加されました。シャッフルされたミニバッチを速くする方法に関する提案はありますか?ここで

はトレーニングデータである:ここでLink to bounty_training.csv (pastebin)

は私のコードです:

shuffle_batch

import numpy as np 
import tensorflow as tf 

data = np.loadtxt('bounty_training.csv', 
    delimiter=',',skiprows=1,usecols = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) 

filename = "test.tfrecords" 

with tf.python_io.TFRecordWriter(filename) as writer: 
    for row in data: 
     features, label = row[:-1], row[-1] 
     example = tf.train.Example() 
     example.features.feature['features'].float_list.value.extend(features) 
     example.features.feature['label'].float_list.value.append(label) 
     writer.write(example.SerializeToString()) 

def read_and_decode_single_example(filename): 
    filename_queue = tf.train.string_input_producer([filename], 
                num_epochs=None) 
    reader = tf.TFRecordReader() 
    _, serialized_example = reader.read(filename_queue) 

    features = tf.parse_single_example(
     serialized_example, 
     features={ 
      'label': tf.FixedLenFeature([], np.float32), 
      'features': tf.FixedLenFeature([14], np.float32)}) 

    pdiff = features['label'] 
    avgs = features['features'] 

    return avgs, pdiff 

avgs, pdiff = read_and_decode_single_example(filename) 


n_features = 14 
batch_size = 1000 
hidden_units = 7 
lr = .001 

avgs_batch, pdiff_batch = tf.train.shuffle_batch(
    [avgs, pdiff], batch_size=batch_size, 
    capacity=5000, 
    min_after_dequeue=2000) 

X = tf.placeholder(tf.float32,[None,n_features]) 
Y = tf.placeholder(tf.float32,[None,1]) 

W = tf.Variable(tf.truncated_normal([n_features,hidden_units])) 
b = tf.Variable(tf.zeros([hidden_units])) 

Wout = tf.Variable(tf.truncated_normal([hidden_units,1])) 
bout = tf.Variable(tf.zeros([1])) 

hidden1 = tf.matmul(X,W) + b 
pred = tf.matmul(hidden1,Wout) + bout 

loss = tf.reduce_mean(tf.squared_difference(pred,Y)) 

optimizer = tf.train.AdamOptimizer(lr).minimize(loss) 

with tf.Session() as sess: 
    init = tf.global_variables_initializer() 
    sess.run(init) 
    coord = tf.train.Coordinator() 
    threads = tf.train.start_queue_runners(sess=sess, coord=coord) 

    for step in range(1000): 
     x_, y_ = sess.run([avgs_batch,pdiff_batch]) 

     _, loss_val = sess.run([optimizer,loss], 
       feed_dict={X: x_, Y: y_.reshape(batch_size,1)}) 

     if step % 100 == 0: 
      print(loss_val) 


    coord.request_stop() 
    coord.join(threads) 

全バッチを経由して実際sess.run呼び出しのために一度pdiff_batch.evalのために一度、avgs_batch.evalに一度、そして - この場合、numpyの配列

""" 
avgs and pdiff loaded into numpy arrays first... 
Same model as above 
""" 
    with tf.Session() as sess: 
     init = tf.global_variables_initializer() 
     sess.run(init) 

     for step in range(1000): 
      _, loss_value = sess.run([optimizer,loss], 
        feed_dict={X: avgs,Y: pdiff.reshape(n_instances,1)}) 

答えて

2

このトリックは、単一の例をshuffle_batchに入力するのではなく、enqueue_many = Trueを使ってn + 1次元のテンソルの例をフィードします。

TFRecordReader seems extremely slow , and multi-threads reading not working

def get_batch(batch_size): 
    reader = tf.TFRecordReader() 
    _, serialized_example = reader.read(filename_queue) 

    batch_list = [] 
    for i in range(batch_size): 
     batch_list.append(serialized_example) 

    return [batch_list] 

batch_serialized_example = tf.train.shuffle_batch(
get_batch(batch_size), batch_size=batch_size, 
    capacity=100*batch_size, 
    min_after_dequeue=batch_size*10, 
    num_threads=1, 
    enqueue_many=True) 

features = tf.parse_example(
    batch_serialized_example, 
    features={ 
     'label': tf.FixedLenFeature([], np.float32), 
     'features': tf.FixedLenFeature([14], np.float32)}) 

batch_pdiff = features['label'] 
batch_avgs = features['features'] 

... 
3

は、あなたがステップごとにセッションを3回実行しています。それは減速の大きさを説明するものではありませんが、あなたが心に留めておくべきことは間違いありません。少なくとも最初の2つの評価通話は、1つのsess.run通話に結合する必要があります。

スローダウンのほとんどは、TFRecordReaderの使用に起因すると思われます。私はテンソルフローの内部動作を理解するふりをしていませんが、私の答えはhereが役に立ちます。

概要

  • 各実施例と関連した最小限のデータ、すなわち、画像ファイル名、IDS全体ではなく画像を作成します。
  • テンソルフロー演算子に変換すると、tensorflow.python.framework.ops.convert_to_tensorとなります。
  • tf.train.slice_input_producerを使用して、単一の例のテンソルを取得します。
  • 個々の例についていくつかの前処理を行います。ファイル名からイメージをロードする。
  • これらをまとめてtf.train.batchを使用してグループ化します。
+0

私はevalは()ほんの数マイクロ秒かかることをどこかで読みました。私は読者がどのようにI/Oを処理するかと何か考えていました。トレーニングループの1回の反復を行うのにかかる時間は、私がそれを与えるバッチサイズと線形であるようです。 – Nitro

0

データを取得するためにキューを使用して、あなたはfeed_dictを使用しないでください。私は非常に有用だったこのスレッドを発見しました。代わりに、あなたのグラフは、入力データに直接依存します、それは次のようになります。

  • は、Xを削除し、
  • Yプレースホルダ直接

    hidden1 = tf.matmul(avgs_batch,W) + b 
    
  • 同様に、あなたの機能のバッチを使用し、ラベルのバッチを使用します損失を計算するときにYの代わりに(pdiff_batch)を代入します。

  • 最後に、第2のsession.runをそのまま維持して、直接損失を計算してください.feed_dictを使用しないでください

    # x_, y_ = sess.run([avgs_batch,pdiff_batch]) 
    # _, loss_val = sess.run([optimizer,loss], 
         feed_dict={X: x_, Y: y_.reshape(batch_size,1)}) 
    
    _, loss_val = sess.run([optimizer,loss]) 
    
関連する問題