2016-08-28 34 views
12

Tôi đang cố gắng chạy biểu đồ tensorflow để đào tạo một mô hình và định kỳ đánh giá bằng cách sử dụng một tập dữ liệu đánh giá riêng biệt. Cả dữ liệu đào tạo và đánh giá đều được triển khai bằng cách sử dụng trình chạy hàng đợi.tensorflow: cho ăn hiệu quả dữ liệu eval/train bằng cách sử dụng hàng đợi runners

Giải pháp hiện tại của tôi là tạo cả hai yếu tố đầu vào trong cùng một biểu đồ và sử dụng tf.cond tùy thuộc vào trình giữ chỗ is_training. Vấn đề của tôi được đánh dấu bằng đoạn mã sau:

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)) 

Tôi cũng đã phải nhận xét ra các image_summary dòng 133 của tensorflow/models/image/cifar10/cifar10_inputs.py.

Việc này mang lại kết quả như sau:

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

Có vẻ như trong trường hợp hỗn hợp cả hai đầu vào đang được đọc/phân tích, mặc dù chỉ có 1 được sử dụng. Có cách nào để tránh tính toán dư thừa này không? Hoặc có cách nào tốt hơn để chuyển đổi giữa dữ liệu đào tạo/đánh giá mà vẫn thúc đẩy thiết lập xếp hàng đợi không?

+0

tôi đã cố gắng để bắt đầu vận động viên xếp hàng một lần nữa sau khi ngừng và tham gia các đề tài, nhưng tôi không thể nhận được rằng để làm việc. Dường như hàng đợi được đóng lại sau – piotr

Trả lời

4

Bạn đã đọc của phần này link về nhiều đầu vào? Tôi nghĩ bạn có thể thêm đối số is_training vào hàm đầu vào của mình để phân biệt dữ liệu đào tạo với dữ liệu eval. Sau đó, bạn có thể sử dụng lại các biến chia sẻ để có được nhật ký cho dữ liệu eval và xây dựng một op cho eval. Sau đó, trong biểu đồ của bạn, hãy chạy valudation_accuracy=sess.run(eval_op) để có được độ chính xác của eval.


Cập nhật:

Hi, từ hiểu biết của tôi, nếu bạn muốn để đào tạo cho n lô, đánh giá, đào tạo, đánh giá, bạn có thể giữ có hai ops trong cùng biểu đồ, không cần phải xây dựng một cái mới. Giả sử bạn đã xây dựng tất cả các chức năng cần thiết, sau đó mã nên như thế này:

#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

Từ những gì tôi hiểu điều này liên quan đến việc xây dựng các biểu đồ riêng biệt (mặc dù với các biến được chia sẻ). Nó hoạt động tốt nếu bạn làm một đoạn đào tạo, sau đó đánh giá một lần, nhưng nếu bạn muốn đào tạo cho n đợt, đánh giá, đào tạo, đánh giá, ...nó trở nên đắt tiền để xây dựng một đồ thị mới mỗi lần. Tôi nghĩ rằng tôi vẫn thích giải pháp không thích hợp của tôi ở đây để sử dụng 'feed_dict' từ một biểu đồ nhỏ hơn, riêng biệt chịu trách nhiệm chỉ cho việc tạo lô đầu vào từ hàng đợi ... – DomJack

+0

Phiên bản cập nhật sẽ đánh dấu tất cả các hộp :). Xin lỗi vì đã cập nhật muộn. – DomJack

2

Sau một số thử nghiệm, giải pháp tốt nhất hiện tại của tôi là có biểu đồ chính với các đầu vào đào tạo và biểu đồ riêng biệt chỉ với các hoạt động dữ liệu đánh giá. Tôi mở một phiên riêng để lấy dữ liệu đánh giá và cung cấp dữ liệu này cho biểu đồ đào tạo khi tôi muốn đánh giá. Khả năng đánh giá cao (và chạy đánh giá mất nhiều thời gian hơn lý tưởng vì chúng phải ot của một phiên duy nhất để được cấp cho một phiên khác), nhưng giả sử chạy thử rất hiếm so với chạy đào tạo, điều này có vẻ thích hợp hơn với phiên bản gốc ...

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() 

Kết quả:

Train time: 0.050 
Eval time: 0.064 

cập nhật: khi sử dụng phương pháp này trong vấn đề đào tạo với tf.contrib.layers và quy tắc, tôi tìm thấy những thiệt hại theo quy tắc đi đến vô cùng nếu đồ thị DataSupplier là trên cùng một thiết bị làm biểu đồ đào tạo. Tôi không thể cho cuộc sống của tôi giải thích tại sao đây là trường hợp, nhưng rõ ràng thiết lập các thiết bị của DataSupplier cho CPU (cho đồ thị đào tạo là trên GPU của tôi) có vẻ ...

Các vấn đề liên quan