2016-08-28 2 views
12

모델을 교육하고 별도의 평가 데이터 세트를 사용하여 주기적으로 평가하는 tensorflow 그래프를 실행하려고합니다. 교육 및 평가 데이터는 모두 대기열 러너를 사용하여 구현됩니다.tensorflow : 큐 러너를 사용하여 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 

단지 하나를 사용하더라도, 두 입력 구문 분석/읽기되고있는 혼합 된 경우에 보일 것입니다 :

다음과 같은 결과를 얻었다. 이 중복 계산을 피할 수있는 방법이 있습니까? 또는 여전히 대기열 러너 설정을 활용하는 교육/평가 데이터를 전환하는 더 좋은 방법이 있습니까?

+0

내가 중지 및 스레드에 가입 한 후 다시 큐 주자을 시작했지만, 나는 그 일을 얻을 수 없습니다. 나중에 대기열이 닫힌 것 같아 – piotr

답변

4

이 부분은 link 멀티 입력인가? is_training 인수를 입력 함수에 추가하여 교육 데이터를 평가 데이터와 구별 할 수 있다고 생각합니다. 그런 다음 공유 변수를 재사용하여 평가 데이터에 대한 로그를 얻고 eval에 op를 작성할 수 있습니다. 그런 다음 그래프에서 valudation_accuracy=sess.run(eval_op)을 실행하여 평가 정확도를 얻으십시오.


업데이트 :

안녕, 내 이해에서, n을 배치 훈련을 할 경우, 평가, 기차, 같은 그래프가이 개 작전 유지할 수 평가할 필요가 구축 없음 새로운. 당신이 필요한 모든 기능을 구축 이미 한 가정, 다음 코드는이를 좋아한다 :

#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

몇 가지 실험을 마친 후 현재 최상의 솔루션은 교육 입력과 평가 데이터 작업이있는 별도의 그래프가있는 주 그래프를 만드는 것입니다. 별도의 세션을 열어 평가 데이터를 얻고이를 평가할 때 교육 그래프에 제공합니다. 매우 평범하지 않고 (평가 실행은 이상적으로 다른 세션에 제공되기 위해 오랜 시간이 걸릴 것입니다), 교육 실행에 비해 평가 실행이 거의 없다고 가정하면 원래 버전보다 바람직합니다.

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 그래프는 동일한에있는 경우, 나는 정규화 손실이 무한대로 이동 찾을 수 장치를 교육 그래프로 사용합니다. 나는 왜 이런 경우인지 설명 할 수는 없지만 교육용 그래프가 내 GPU에있는 경우 주어진 DataSupplier 장치를 명시 적으로 설정하면 작동하는 것처럼 보입니다 ...

관련 문제