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?
Serialisierung abgepackte Trainingsdaten auf der Festplatte in
TFRecord
Formatdie scheinbaren Grenzen
tf.py_func
,jedes unnötiges oder vorzeitiges padding und
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
Tensorflow read images with labels zeigt einen einfachen Rahmen mit diskreten, kategorisch Etiketten, , die ich mit als Modell begonnen haben.
How to load sparse data with TensorFlow? erklärt schön einen Ansatz für spärliche Daten geladen werden, sondern übernimmt Vorverpackung
tf.train.Example
s.
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