Il mio modello NMT ha 2 livelli, 512 unità nascoste. Mi alleno con una lunghezza massima della frase = 50, dimensione batch = 32 e vedo velocità simile tra feed_dict e queue, circa 2400-2500 parole target al secondo (io uso questa metrica per la velocità basata su questo paper).
Trovo feed_dict molto intuitivo e facile da usare. La coda è difficile. Utilizzando la coda, è necessario:
1/Converti i tuoi dati in tfrecords. Devo davvero google un po 'per capire come convertire i miei dati seq2seq in tfrecords perché i documenti non sono molto utili.
2/Decodifica i tuoi dati da tfrecords. Troverai le funzioni utilizzate per generare i tfrecords e decodificarli in modo non intuitivo. Per esempio, se ognuno dei miei esempi di allenamento ha 3 sequenze (solo 3 liste di interi) src_input, trg_input, trg_target
e voglio registrare anche la lunghezza dello src_input
(alcuni dei suoi elementi potrebbero essere IMBOTTITURE, quindi non contare), ecco come per generare tfrecord da ogni esempio:
def _make_example(src_input, src_seq_length, trg_input, trg_seq_length, trg_target, target_weight):
context = tf.train.Features(
feature={
'src_seq_length': int64_feature(src_seq_length)
})
feature_lists = tf.train.FeatureLists(
feature_list={
'src_input': int64_featurelist(src_input),
'trg_input': int64_featurelist(trg_input),
'trg_target': int64_featurelist(trg_target)
})
return tf.train.SequenceExample(context=context, feature_lists=feature_lists)
Ed ecco come decodificarlo:
def _read_and_decode(filename_queue):
reader = tf.TFRecordReader(options=self.tfrecord_option)
_, serialized_ex = reader.read(filename_queue)
context_features = {
'src_seq_length': tf.FixedLenFeature([], dtype=tf.int64)
}
sequence_features = {
'src_input': tf.FixedLenSequenceFeature([], dtype=tf.int64),
'trg_input': tf.FixedLenSequenceFeature([], dtype=tf.int64),
'trg_target': tf.FixedLenSequenceFeature([], dtype=tf.int64)
}
context, sequences = tf.parse_single_sequence_example(
serialized_ex,
context_features=context_features,
sequence_features=sequence_features)
src_seq_length = tf.cast(context['src_seq_length'], tf.int32)
src_input = tf.cast(sequences['src_input'], tf.int32)
trg_input = tf.cast(sequences['trg_input'], tf.int32)
trg_target = tf.cast(sequences['trg_target'], tf.int32)
return src_input, src_seq_length, trg_input, trg_target
E per generare ogni caratteristica tfrecord/featurelist:
def int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def int64_featurelist(l):
feature = [tf.train.Feature(int64_list=tf.train.Int64List(value=[x])) for x in l]
return tf.train.FeatureList(feature=feature)

3/Train/dev setup. Credo che sia una pratica comune allenare periodicamente il tuo modello per un po 'di tempo, quindi valutare il set di sviluppo, quindi ripetere. Non so come farlo con le code. Con feed_dict, devi solo creare due grafici con parametri condivisi nella stessa sessione, uno per il treno e uno per lo sviluppo. Quando valutate il set di sviluppo, date semplicemente i dati di sviluppo al grafico dev, il gioco è fatto.Ma per la coda, l'output dalla coda è parte del grafico stesso. Per eseguire la coda, è necessario avviare il gestore della coda, creare un coordinatore, utilizzare questo coordinatore per gestire la coda. Quando è finito, la coda è vicina !!!. Al momento, non ho idea di come scrivere al meglio il mio codice per conformare il setup di treno/dev con le code, tranne aprire una nuova sessione, creare un nuovo grafico per dev ogni volta che valuto. Lo stesso problema è stato sollevato here, e puoi google per domande simili su Stackoverflow.
Tuttavia, un sacco di gente ha detto che la coda è più veloce di feed_dict. La mia ipotesi è che la coda è utile se ti alleni in modo distribuito. Ma per quanto mi riguarda, mi alleno spesso su solo 1 GPU e finora non sono affatto entusiasta della coda. Beh, solo la mia ipotesi.
prima parte di quella esercitazione dà un po 'di indicazioni su quando utilizzare le code: https://indico.io/blog/tensorflow-data-inputs-part1-placeholders-protobufs-queues/ –