2017-03-03 1 views
0

Aus einer Liste von Wortbildern mit ihren Transkriptionen, ich versuche, spärlich Sequenz Etiketten zu erstellen und lesen (für tf.nn.ctc_loss) ein tf.train.slice_input_producer verwenden, vermeidenWie können spärliche Sequenzbezeichnungen für CTC-Verluste innerhalb von Tensorflow generiert/gelesen werden?

  1. Serialisierung abgepackte Trainingsdaten auf der Festplatte in TFRecord Format

  2. die scheinbaren Grenzen tf.py_func,

  3. jedes unnötiges oder vorzeitiges padding und

  4. Lesen des gesamten Datensatzes in den RAM.

Das Hauptproblem scheint eine Zeichenfolge in der Abfolge von Etiketten zu konvertieren für tf.nn.ctc_loss benötigt (a SparseTensor).

Zum Beispiel, mit dem Zeichensatz im (geordneten) Bereich [A-Z], würde ich die Textlabel Zeichenfolge "BAD" in die Reihenfolge Label-Klassenliste [1,0,3] konvertieren möchten.

Jedes Beispiel Bild, das ich lesen möchte, enthält den Text als Teil des Dateinamens, so ist es einfach zu extrahieren und die Konvertierung in Straight-up-Python zu tun. (Wenn es eine Möglichkeit gibt, dies innerhalb von TensorFlow-Berechnungen zu tun, habe ich sie nicht gefunden.)

Mehrere frühere Fragen haben einen Blick auf diese Probleme geworfen, aber ich konnte sie nicht erfolgreich integrieren. Zum Beispiel

Gibt es eine Möglichkeit, diese Ansätze zu integrieren?

Ein anderes Beispiel (SO Frage # 38012743) zeigt, wie ich die Umwandlung von String zu Liste verzögern kann, bis nach dem Entfernen der Dateiname für die Decodierung, aber tf.py_func, die Vorbehalte hat. (Sollte ich mir Sorgen um sie machen?)

Ich erkenne, dass "SparseTensors nicht gut mit Warteschlangen spielen" (per tf docs), so dass es möglicherweise vor dem Batching etwas Voodoo auf das Ergebnis (Serialisierung?) oder sogar nacharbeiten, wo die Berechnung stattfindet; Ich bin dafür offen.

Nach MarvMind Gliederung, hier ist ein Grundgerüst mit den Berechnungen ich will (iterieren über Zeilen mit Beispieldateinamen, extrahieren jedes Etikett Zeichenfolge und in Sequenz konvertieren), aber ich habe nicht erfolgreich festgestellt, die "Tensorflow" Weg, es zu tun .

Vielen Dank für die richtige "zwicken", eine geeignetere Strategie für meine Ziele, oder ein Hinweis, dass tf.py_func Trainingseffizienz oder etwas anderes Downstream (z. B., Laden von trainierten Modellen für den zukünftigen Gebrauch).

BEARBEITEN (+7 Stunden) Ich fand die fehlenden Ops, um die Dinge zu verpatzen. Während ich noch verifizieren muss, dass diese Verbindung mit CTC_Loss nachgelagert ist, habe ich überprüft, dass die bearbeitete Version unten die Bilder und Sparzensors richtig einreiht und einliest.

out_charset="ABCDEFGHIJKLMNOPQRSTUVWXYZ" 

def input_pipeline(data_filename): 
    filenames,seq_labels = _get_image_filenames_labels(data_filename) 
    data_queue = tf.train.slice_input_producer([filenames, seq_labels]) 
    image,label = _read_data_format(data_queue) 
    image,label = tf.train.batch([image,label],batch_size=2,dynamic_pad=True) 
    label = tf.deserialize_many_sparse(label,tf.int32) 
    return image,label 

def _get_image_filenames_labels(data_filename): 
    filenames = [] 
    labels = [] 
    with open(data_filename)) as f: 
     for line in f: 
      # Carve out the ground truth string and file path from 
      # lines formatted like: 
      # ./241/7/158_NETWORK_51375.jpg 51375 
      filename = line.split(' ',1)[0][2:] # split off "./" and number 
      # Extract label string embedded within image filename 
      # between underscores, e.g. NETWORK 
      text = os.path.basename(filename).split('_',2)[1] 
      # Transform string text to sequence of indices using charset, e.g., 
      # NETWORK -> [13, 4, 19, 22, 14, 17, 10] 
      indices = [[i] for i in range(0,len(text))] 
      values = [out_charset.index(c) for c in list(text)] 
      shape = [len(text)] 
      label = tf.SparseTensorValue(indices,values,shape) 
      label = tf.convert_to_tensor_or_sparse_tensor(label) 
      label = tf.serialize_sparse(label) # needed for batching 
      # Add data to lists for conversion 
      filenames.append(filename) 
      labels.append(label) 
    filenames = tf.convert_to_tensor(filenames) 
    labels = tf.convert_to_tensor_or_sparse_tensor(labels) 
    return filenames, labels 

def _read_data_format(data_queue): 
    label = data_queue[1] 
    raw_image = tf.read_file(data_queue[0]) 
    image = tf.image.decode_jpeg(raw_image,channels=1) 
    return image,label 

Antwort

1

Die wichtigsten Ideen scheinen wollte einen SparseTensorValue aus den Daten zu erstellen, führt es durch tf.convert_to_tensor_or_sparse_tensor und dann serialisiert es mit tf.serialize_sparse (wenn Sie die Daten zu Charge wollen). Nach dem Batch-Vorgang können Sie die Werte mit tf.deserialize_many_sparse wiederherstellen.

Hier ist der Umriss. Erstellen Sie die spärlichen Werte, konvertieren Tensor und serialisiert:

indices = [[i] for i in range(0,len(text))] 
values = [out_charset.index(c) for c in list(text)] 
shape = [len(text)] 
label = tf.SparseTensorValue(indices,values,shape) 
label = tf.convert_to_tensor_or_sparse_tensor(label) 
label = tf.serialize_sparse(label) # needed for batching 

Dann können Sie die Dosierung tun und deserialize:

image,label = tf.train.batch([image,label],dynamic_pad=True) 
label = tf.deserialize_many_sparse(label,tf.int32) 
Verwandte Themen