2017-09-03 1 views
2

Ich habe meinen eigenen Code mit Bezug auf this wunderbare Tutorial geschrieben und ich bin nicht in der Lage, Ergebnisse zu erhalten, wenn die Aufmerksamkeit mit Strahlsuche nach meinem Verständnis in der Klasse AttentionModel die _build_decoder_cell Funktion erstellt separaten Decoder Zelle und Aufmerksamkeit Wrapper für Inferenz-Modus, dies unter der Annahme, (was ich denke, ist falsch und kann nicht einen Weg, um es finden),Umsetzung von Aufmerksamkeit mit Strahlsuche in Tensorflow

with tf.name_scope("Decoder"): 

mem_units = 2*dim 
dec_cell = tf.contrib.rnn.BasicLSTMCell(2*dim) 
beam_cel = tf.contrib.rnn.BasicLSTMCell(2*dim) 
beam_width = 3 
out_layer = Dense(output_vocab_size) 

with tf.name_scope("Training"): 
    attn_mech = tf.contrib.seq2seq.BahdanauAttention(num_units = mem_units, memory = enc_rnn_out, normalize=True) 
    attn_cell = tf.contrib.seq2seq.AttentionWrapper(cell = dec_cell,attention_mechanism = attn_mech) 

    batch_size = tf.shape(enc_rnn_out)[0] 
    initial_state = attn_cell.zero_state(batch_size = batch_size , dtype=tf.float32) 
    initial_state = initial_state.clone(cell_state = enc_rnn_state) 

    helper = tf.contrib.seq2seq.TrainingHelper(inputs = emb_x_y , sequence_length = seq_len) 
    decoder = tf.contrib.seq2seq.BasicDecoder(cell = attn_cell, helper = helper, initial_state = initial_state ,output_layer=out_layer) 
    outputs, final_state, final_sequence_lengths= tf.contrib.seq2seq.dynamic_decode(decoder=decoder,impute_finished=True) 

    training_logits = tf.identity(outputs.rnn_output) 
    training_pred = tf.identity(outputs.sample_id) 

with tf.name_scope("Inference"): 

    enc_rnn_out_beam = tf.contrib.seq2seq.tile_batch(enc_rnn_out , beam_width) 
    seq_len_beam  = tf.contrib.seq2seq.tile_batch(seq_len  , beam_width) 
    enc_rnn_state_beam = tf.contrib.seq2seq.tile_batch(enc_rnn_state , beam_width) 

    batch_size_beam  = tf.shape(enc_rnn_out_beam)[0] # now batch size is beam_width times 

    # start tokens mean be the original batch size so divide 
    start_tokens = tf.tile(tf.constant([27], dtype=tf.int32), [ batch_size_beam//beam_width ]) 
    end_token = 0 

    attn_mech_beam = tf.contrib.seq2seq.BahdanauAttention(num_units = mem_units, memory = enc_rnn_out_beam, normalize=True) 
    cell_beam = tf.contrib.seq2seq.AttentionWrapper(cell=beam_cel,attention_mechanism=attn_mech_beam,attention_layer_size=mem_units) 

    initial_state_beam = cell_beam.zero_state(batch_size=batch_size_beam,dtype=tf.float32).clone(cell_state=enc_rnn_state_beam) 

    my_decoder = tf.contrib.seq2seq.BeamSearchDecoder(cell = cell_beam, 
                 embedding = emb_out, 
                 start_tokens = start_tokens, 
                 end_token = end_token, 
                 initial_state = initial_state_beam, 
                 beam_width = beam_width 
                 ,output_layer=out_layer) 

    beam_output, t1 , t2 = tf.contrib.seq2seq.dynamic_decode( my_decoder, 
                   maximum_iterations=maxlen) 

    beam_logits = tf.no_op() 
    beam_sample_id = beam_output.predicted_ids 

wenn ich Strahl nenne _sample_id nach dem Training bin ich nicht immer korrektes Ergebnis.

meine Vermutung ist, dass wir die gleiche Aufmerksamkeit Wrapper verwenden sollen, aber das ist nicht möglich, da wir Kachelsequenz für Strahlsuche verwendet werden müssen.

Alle Einsichten/Vorschläge würden sehr geschätzt werden.

i erstellt haben auch ein Problem für diese in ihrem Haupt-Repository Issue-93

Antwort

1

Ich bin nicht sicher, was meinst du mit „Ich bin nicht fähig Ergebnisse zu erhalten“, aber ich gehe davon aus, dass Ihr Modell ist nicht Nutzen Sie die während des Trainings erlernten Fähigkeiten.

Wenn dies der Fall ist, dann müssen Sie zuerst wissen, dass alles über variable Teilen ist, das erste, was Sie tun müssen, ist, dass Sie die verschiedenen Variablenbereiche zwischen dem Training und Schlussfolgerung und stattdessen Sie loswerden müssen einige Sache wie

entfernen Sie die

with tf.name_scope("Training"): 

und Gebrauch verwenden:

with tf.variable_scope("myScope"): 

und entfernen Sie die

with tf.name_scope("Inference"): 

und verwenden stattdessen

auch zu Beginn des und nach with tf.variable_scope("myScope")

enc_rnn_out = tf.contrib.seq2seq.tile_batch(enc_rnn_out , 1) 
seq_len  = tf.contrib.seq2seq.tile_batch(seq_len  , 1) 
enc_rnn_state = tf.contrib.seq2seq.tile_batch(enc_rnn_state , 1) 

Dadurch wird sichergestellt, dass Ihre Folgerung Variablen und Trainingsvariablen haben die gleiche Signatur und werden geteilt ,

Ich habe das getestet, als ich dem gleichen Tuto folgte Rial, das Sie erwähnt haben, mein Modell trainiert noch, während ich diesen Beitrag schreibe, aber ich kann sehen, dass die Genauigkeit zunimmt, während wir sprechen, was anzeigt, dass die Lösung auch für Sie arbeiten sollte.

danke

+0

Ja, ich war nicht in der Lage, die während des Trainings erlernten Gewichte für meinen Ansatz zu verwenden. tf.name_scope() hat nicht den Parameter "Wiederverwendung" in Version 1.3, Sie müssen tf.variable_scope() bedeuten. Ich löste diesen Ansatz, indem ich zwei separate Graphen für Training und Inferenz erstellte, nachdem @dnnavn auf mich in der [github issue] (https://github.com/tensorflow/nmt/issues/93) hingewiesen hatte, wo er dies behauptete ist nur durch separate Graphen möglich, ich muss das ausprobieren. In der Zwischenzeit, wenn Sie es erfolgreich versucht haben, kommentieren Sie bitte. Danke –

+0

ja, tf.variable_scope statt tf.name_scope –

+0

Hallo Wieder, ich kann sehen, dass Sie diese Antwort als richtig markiert haben, haben Sie eine Änderung erhalten, um es auf Ihre Daten zu testen? –