2016-08-28 10 views
12

テンソルフローグラフを実行してモデルをトレーニングし、別の評価データセットを使用して定期的に評価しようとしています。訓練と評価の両方のデータは、キューランナーを使用して実装されます。テンソルフロー:キューランナーを使用した効率的なeval/trainデータの供給

私の現在の解決策は、両方の入力を同じグラフに作成し、プレースホルダに依存するtf.condを使用することです。私の問題は、次のコードで強調表示されています:私もimage_summaryラインtensorflow/models/image/cifar10/cifar10_inputs.py133をコメントアウトしなければならなかった

import tensorflow as tf 
from tensorflow.models.image.cifar10 import cifar10 
from time import time 


def get_train_inputs(is_training): 
    return cifar10.inputs(False) 


def get_eval_inputs(is_training): 
    return cifar10.inputs(True) 


def get_mixed_inputs(is_training): 
    train_inputs = get_train_inputs(None) 
    eval_inputs = get_eval_inputs(None) 

    return tf.cond(is_training, lambda: train_inputs, lambda: eval_inputs) 


def time_inputs(inputs_fn, n_runs=10): 
    graph = tf.Graph() 
    with graph.as_default(): 
     is_training = tf.placeholder(dtype=tf.bool, shape=(), 
            name='is_training') 
     images, labels = inputs_fn(is_training) 

    with tf.Session(graph=graph) as sess: 
     coordinator = tf.train.Coordinator() 
     threads = tf.train.start_queue_runners(sess=sess, coord=coordinator) 
     t = time() 
     for i in range(n_runs): 
      im, l = sess.run([images, labels], feed_dict={is_training: True}) 
     dt = time() - t 
     coordinator.request_stop() 
     coordinator.join(threads) 

    return dt/n_runs 

print('Train inputs: %.3f' % time_inputs(get_train_inputs)) 
print('Eval inputs: %.3f' % time_inputs(get_eval_inputs)) 
print('Mixed inputs: %.3f' % time_inputs(get_mixed_inputs)) 

これは、以下の結果が得られた:

Train inputs: 0.055 
Eval inputs: 0.050 
Mixed inputs: 0.105 

には1つだけが使用されていても、両方の入力が解析され/読み出されている混合場合に思われます。この冗長な計算を避ける方法はありますか?キュー・ランナーの設定を引き続き活用するトレーニング/評価データをよりうまく切り替える方法はありますか?

+0

を私は、スレッドを停止して接合した後、再びキューランナーを開始しようとしましたが、私はそれを動作させることはできません。後でキューが閉じられるようだ。 – piotr

答えて

4

最後にこの部分のlinkはマルチ入力ですか? is_training引数を入力関数に追加して、トレーニングデータと評価データを区別できると思います。 次に、共有変数を再利用してevalデータのロギングを取得し、evalのopを構築することができます。 次に、グラフでvaludation_accuracy=sess.run(eval_op)を実行して、精度を取得します。


更新:

こんにちは、あなたは、n個のバッチのために訓練評価、電車にしたい評価された場合私の理解から、あなたが同じグラフにそこ2つのOPSを保つことができ、構築する必要はありません新しいもの はすでに、コードは次のようにする必要があり、必要なすべての機能を構築していると仮定します

#the following two steps will add train and eval input queue to the graph 
train_inputs,train_labels = inputs(is_train=True) 
eval_inputs,eval_labels = inputs(is_train=False) 

with tf.variable_scope("inference") as scope: 
    train_logits = inference(train_inputs) 
    scope.reuse_variables() 
    eval_logits = inference(eval_inputs) 

loss = loss(train_logits,train_labels) 
eval_accuracy = accuracy(eval_logits,eval_labels) 

#...add train op here,start queue runner and train it ... 
+0

私は、これが分かれていることは分かっているから(共有変数ではあるが)別のグラフを作成することが関係していた。あなたがトレーニングのチャンクをして、一度評価すればうまくいきますが、n回のバッチを勉強したい場合は、評価し、訓練し、評価してください...毎回新しいグラフを作成するのは高価になります。私はまだキューから入力バッチを生成するために責任がある別個の小さなグラフから 'feed_dict'を使用するために私の面倒な解決法を好むと思います... – DomJack

+0

更新されたバージョンはすべてのボックスをチックします:)。遅く更新して申し訳ありません。 – DomJack

2

いくつかの実験の後で、私の現在の最良の解決策は、訓練入力を特徴とする主要なグラフと、評価データ操作だけの別のグラフとを有することである。別のセッションを開いて評価データを取得し、これを評価したいときにトレーニンググラフに入力します。非常に控えめな(評価のランは理想的には、1セッションだけ別のセッションに頼まなければならないほど長くかかりますが)評価ランがトレーニングランに比べて稀であると仮定すると、これは元のバージョンよりも好ましいと思われます...

import tensorflow as tf 
from tensorflow.models.image.cifar10 import cifar10 
from time import time 


class DataSupplier: 
    def __init__(self, tensor_fn): 
     graph = tf.Graph() 
     with graph.as_default(): 
      with graph.device('/cpu:0'): 
       self.tensor = tensor_fn() 
     self.sess = tf.Session(graph=graph) 
     self.coord = tf.train.Coordinator() 
     self.threads = tf.train.start_queue_runners(sess=self.sess, 
                coord=self.coord) 

    def get_tensor_val(self): 
     return self.sess.run(self.tensor) 

    def clean_up(self): 
     self.coord.request_stop() 
     self.coord.join(self.threads) 


eval_batcher = DataSupplier(lambda: cifar10.inputs(True)) 

graph = tf.Graph() 
with graph.as_default(): 
    images, labels = cifar10.inputs(False) 

    out_images = tf.identity(images) 
    out_labels = tf.identity(labels) 

n_runs = 100 

with tf.Session(graph=graph) as sess: 
    coord = tf.train.Coordinator() 
    threads = tf.train.start_queue_runners(sess, coord) 
    for i in range(n_runs): 
     sess.run([out_images, out_labels]) 
    t = time() 
    for i in range(n_runs): 
     sess.run([out_images, out_labels]) 
    dt = (time() - t)/n_runs 
    print('Train time: %.3f' % dt) 
    t = time() 
    for i in range(n_runs): 
     eval_images, eval_labels = eval_batcher.get_tensor_val() 
     sess.run([out_images, out_labels], 
       feed_dict={images: eval_images, labels: eval_labels}) 
    dt = (time() - t)/n_runs 
    print('Eval time: %.3f' % dt) 
    coord.request_stop() 
    coord.join(threads) 

eval_batcher.clean_up() 

結果:

Train time: 0.050 
Eval time: 0.064 

更新:tf.contrib.layersと正則と訓練の問題で、このアプローチを使用するときDataSupplierグラフが同じである場合、私は正則損失が無限大に行く見つけますデバイスをトレーニンググラフとして使用します。私は私の人生の理由について説明することはできませんが、明示的にDataSupplierのデバイスをCPUに設定することはできません(トレーニンググラフが私のGPUにあるとします)...

関連する問題