2016-08-08 3 views
2

Mein Trainingssatz enthält zwei Arten von Dateien: Trainingsbild mit Dateiname wie "1.png" und Etikettendatei mit Namen wie "1.label.txt".Wie man TensorFlow Leser und Warteschlange benutzt, um zwei Akte gleichzeitig zu lesen?

ich einige Verwendung von Queue und Reader in Tutorials wie folgt gefunden:

filename_queue = tf.train.string_input_producer(filenames) 
result.key, value = reader.read(filename_queue) 

Da jedoch mein Trainingssatz zwei Arten von Datei enthält, eine entspricht einen. Wie kann ich den obigen Code für Warteschlangen und Leser verwenden?


EDIT

Ich denke an eine Warteschlange, die Basisnamen zu einer anderen zwei Warteschlange zuzuführen, die jeweils Bild- und Etikett ist. Code wie folgt aus:

with tf.Session() as sess: 
    base_name_queue = tf.train.string_input_producer(['image_names'], num_epochs=20) 
    base_name = base_name_queue.dequeue() 
    image_name = base_name + ".png" 
    image_name_queue = data_flow_ops.FIFOQueue(32, image_name.dtype.base_dtype) 
    image_name_queue.enqueue([image_name]) 
    x = image_name_queue.dequeue() 
    print_op = tf.Print(image_name, [image_name]) 

    qr = tf.train.QueueRunner(base_name_queue, [base_name_queue] * 4) 
    coord = tf.train.Coordinator() 
    enqueue_threads = qr.create_threads(sess, coord=coord, start=True) 

    for step in range(1000000): 
    if coord.should_stop(): 
     break 
    print(sess.run(print_op)) 

    coord.request_stop() 
    coord.join(enqueue_threads) 

aber dieser Code ausgeführt wird zu einem Fehler führen würde:

TypeError: Fetch argument of has invalid type , must be a string or Tensor. (Can not convert a FIFOQueue into a Tensor or Operation.)

und dem Fehlerpunkt auf dieser Linie:

coord.join(enqueue_threads) 

ich glaube, ich muss falsch verstehen, wie Die TensorFlow-Warteschlange funktioniert.

Antwort

6

Ich habe die Lösung für mein Problem gefunden. Ich möchte hier antworten, anstatt meine Frage zu löschen, in der Hoffnung, dass dies Leuten helfen wird, die TensorFlow neu kennen.

Die Antwort besteht aus zwei Teilen:

Teil 1:

  1. Verwendung 2 Warteschlange zwei Satz zu speichern: Wie Dateien Paar für Paar mit TensorFlow Warteschlange

Die Lösung ist einfach zu lesen von Dateien. Beachten Sie, dass die beiden Sets auf die gleiche Weise bestellt werden sollten.

  • Führen Sie eine Vorverarbeitung mit dequeue durch.
  • zwei vorverarbeiteten Tensor in einer Liste kombinieren und die Liste zu shuffle_batch
  • -Code passieren hier:

    base_names = ['file1', 'file2'] 
    base_tensor = tf.convert_to_tensor(base_names) 
    image_name_queue = tf.train.string_input_producer(
        tensor + '.png', 
        shuffle=False # Note: must set shuffle to False 
    ) 
    label_queue = tf.train.string_input_producer(
        tensor + '.lable.txt', 
        shuffle=False # Note: must set shuffle to False 
    ) 
    
    # use reader to read file 
    image_reader = tf.WholeFileReader() 
    image_key, image_raw = image_reader.read(image_name_queue) 
    image = tf.image.decode_png(image_raw) 
    label_reader = tf.WholeFileReader() 
    label_key, label_raw = label_reader.read(label_queue) 
    label = tf.image.decode_raw(label_raw) 
    
    # preprocess image 
    processed_image = tf.image.per_image_whitening(image) 
    batch = tf.train.shuffle_batch([processed_image, label], 10, 100, 100) 
    
    # print batch 
    queue_threads = queue_runner.start_queue_runners() 
    print(sess.run(batch)) 
    

    Teil 2: Queue, QueueRunner, Koordinator und Hilfsfunktionen

    Queue ist wirklich eine Warteschlange (scheint bedeutungslos). Eine Warteschlange hat zwei Methoden: enqueue und dequeue. Die Eingabe von enqueue ist Tensor (Sie können normale Daten in die Warteschlange stellen, aber intern in Tensor konvertiert werden). Der Rückgabewert von dequeue ist ein Tensor.So können Sie Pipeline von Warteschlangen wie folgt machen:

    q1 = data_flow_ops.FIFOQueue(32, tf.int) 
    q2 = data_flow_ops.FIFOQueue(32, tf.int) 
    enq1 = q1.enqueue([1,2,3,4,5]) 
    v1 = q1.dequeue() 
    enq2 = q2.enqueue(v1) 
    

    Der Vorteil der Verwendung Warteschlange in TensorFlow ist asynchron Daten geladen werden, die die Leistung verbessern und Speicherplatz sparen. Der obige Code ist nicht ausführbar, da kein Thread diese Operationen ausführt. QueueRunner soll beschreiben, wie enqueue Daten parallel sind. Der Parameter für die Initialisierung von QueueRunner ist also eine enqueue Operation (die Ausgabe von enqueue).

    Nachdem Sie alle QueueRunner s eingerichtet haben, müssen Sie alle Threads starten. Eine Möglichkeit besteht darin, sie zu starten, wenn die Schaffung ihnen:

    enqueue_threads = qr.create_threads(sess, coord=coord, start=True) 
    

    oder alle Threads beginnen, nachdem die gesamte Einrichtung Arbeiten getan:

    # add queue runner 
    queue_runner.add_queue_runner(queue_runner.QueueRunner(q, [enq])) 
    
    # start all queue runners 
    queue_threads = queue_runner.start_queue_runners() 
    

    Wenn alle Themen, Sie haben zu entscheiden, wann beenden. Koordinator ist hier, um dies zu tun. Coordinator ist wie eine gemeinsame Markierung zwischen allen laufenden Threads. Wenn einer von ihnen fertig ist oder einen Fehler meldet, wird aufgerufen, dann wird der gesamte Thread True beim Aufruf coord.should_stop() aufrufen. So das Muster Coordinator der Verwendung ist:

    coord = tf.train.Coordinator() 
    
    for step in range(1000000): 
        if coord.should_stop(): 
        break 
        print(sess.run(print_op)) 
    
    coord.request_stop() 
    coord.join(enqueue_threads) 
    
    +1

    In dem Teil, in dem Sie 'image_name_queue' und' label_queue' definieren, können Sie 'shuffle' auf' true' setzen, wenn Sie für beide den gleichen Seed verwenden, z. füge 'seed = 123' zu beiden' tf.train.string_input_producer' hinzu. – MGoksu

    +0

    @MGoksu Ja, du bist TOTALY richtig. Ich habe das gerade erst herausgefunden. Danke für Ihre Erinnerung. –

    +0

    Vielen Dank für den Hinweis auf den 'shuffle' Parameter von' tf.train.string_input_producer'. Das unbestimmte Verhalten, das ich erlebt habe, gelöst :) –

    0

    Ihr Ansatz mit zwei Warteschlangen können einige negative Folgen haben. Da eine Ihrer Warteschlangen Bilddaten (groß) und andere Textdaten (klein) enthält, besteht die Möglichkeit, dass eine der Warteschlangen hinter einer anderen zurückbleibt.

    Statt dessen würde ich Ihnen empfehlen, einen Blick auf tfrecord format zu werfen. Erstellen Sie dann eine TFrecord-Datei, die sowohl aus Ihren Daten als auch aus Ihren Labels besteht. Verwenden Sie danach nur eine Warteschlange, um Daten und Labels gleichzeitig zu erfassen.