Керас разрывает последовательность во время вывода - PullRequest
0 голосов
/ 20 марта 2019

Я тренирую модель с-к-с-ке с Керасом.Модель обучения использует bi-LSTM для кодирования и 2x bi-LSTM для декодирования.Это работает как талисман во время обучения модели.

При загрузке обученной модели во время вывода вывод представляет собой обычный мусор данных.Мне интересно, что я делаю не так.У меня есть версия той же модели, которая довольно хорошо работает при выводе только с одним би-декодером (вместо двух).Я совершенно уверен, что понял принцип.Я также видел примеры Keras для seq-2-seq;Я что-то упустил, но не могу понять, что.Кто-нибудь видит очевидный недостаток, как я использую / инициализирую слои?

Я запутался, потому что логический вывод работает для меньшей модели, но не для более крупной.Вызов метода предиката () во время обучения модели ясно показывает, что более сложная модель в основном работает и дает действительные результаты.

Это мой код вывода схемы модели.Кто-нибудь видит что-то неправильное / неправильное (для работы с двумя слоями декодера)?

######################
###  ENCODER MODEL  ##
######################
encoder_inputs = model.input[0]   # input_1
fwd_encoder_lstm  = model.layers[2]
fwd_enc_out, fwd_enc_hid, fwd_enc_cell = fwd_encoder_lstm(encoder_inputs)
bwd_encoder_lstm  = model.layers[3]
bwd_enc_out, bwd_enc_hid, bwd_enc_cell = bwd_encoder_lstm(encoder_inputs)

encoding_results = Concatenate()([fwd_enc_out, bwd_enc_out])
encoder_model = Model(inputs=encoder_inputs, 
                      outputs=[encoding_results, fwd_enc_hid, fwd_enc_cell, bwd_enc_hid, bwd_enc_cell])

######################
###  DECODER MODEL  ##
######################
decoder_inputs = model.input[1]   # input_2
encoded_seq = Input(shape=(None, latent_dim*2), name='input__encoder_out')
in_fwd_hidden_1 = Input(shape=(latent_dim,), name='input__fwd_hidden_init_1')
in_fwd_cell_1 = Input(shape=(latent_dim,), name='input__fwd_cell_init_1')
in_bwd_hidden_1 = Input(shape=(latent_dim,), name='input__bwd_hidden_init_1')
in_bwd_cell_1 = Input(shape=(latent_dim,), name='input__bwd_cell_init_1')

fwd_init = [in_fwd_hidden_1, in_fwd_cell_1]
bwd_init = [in_bwd_hidden_1, in_bwd_cell_1]

# decoder lstm is initialized with encoder hidden/cell state
fwd_decoder_lstm = model.layers[4]
fwd_dec_out_1, fwd_dec_hid_1, fwd_dec_cell_1 = fwd_decoder_lstm(decoder_inputs, 
                                                                initial_state=fwd_init)
bwd_decoder_lstm = model.layers[5]
bwd_dec_out_1, bwd_dec_hid_1, bwd_dec_cell_1 = bwd_decoder_lstm(decoder_inputs, 
                                                                initial_state=bwd_init)

# attention is computed from the encoder outputs and the decoder outputs
decoder_one_output = Concatenate()([fwd_dec_out_1, bwd_dec_out_1])

fwd_decoder_lstm = model.layers[7]
fwd_dec_out_2, fwd_dec_hid_2, fwd_dec_cell_2 = fwd_decoder_lstm(decoder_one_output, 
                                                                initial_state=fwd_init)
bwd_decoder_lstm = model.layers[8]
bwd_dec_out_2, bwd_dec_hid_2, bwd_dec_cell_2 = bwd_decoder_lstm(decoder_one_output,
                                                                initial_state=bwd_init)

decoded_seq = Concatenate()([fwd_dec_out_2, bwd_dec_out_2])
attention = Dot([2,2])([decoded_seq, encoded_seq])
attention = Activation('softmax')(attention)
context = Dot([2,1])([attention, encoded_seq])
dec_combined = Concatenate()([context, decoded_seq])

timeDistributedLayer = model.layers[15]
final_prediction = timeDistributedLayer(dec_combined)

encoder_parameters = [encoded_seq, in_fwd_hidden_1, in_fwd_cell_1, in_bwd_hidden_1, in_bwd_cell_1]
decoder_parameters = [fwd_dec_hid_1, fwd_dec_cell_1, bwd_dec_hid_1, bwd_dec_cell_1]

decoder_model = Model(
    inputs=[decoder_inputs] + encoder_parameters,
    outputs=[final_prediction] + decoder_parameters)

Здесь цикл вывода, в котором я передаю состояния из предыдущего шага, а также начальные значения для следующего:

def decode_sequence(input_seq):
    # Encode the input as state vectors.
    encoded_seq, fwd_hid, fwd_cell, bwd_hid, bwd_cell = encoder_model.predict(input_seq)
    states_value = [encoded_seq, fwd_hid, fwd_cell, bwd_hid, bwd_cell]

    # Generate empty target sequence of length 1.
    target_seq = np.zeros((1, 1, num_decoder_tokens))
    # Populate the first character of target sequence with the start character.
    target_seq[0, 0, target_token_index[BOS]] = 1.

    # Sampling loop for a batch of sequences
    # (to simplify, here we assume a batch of size 1).
    stop_condition = False
    decoded_sentence = ''
    while not stop_condition:
        output_tokens, next_fwd_hid, next_fwd_cell, next_bwd_hid, next_bwd_cell = decoder_model.predict([target_seq] + states_value)

        # Sample a token
        sampled_token_index = np.argmax(output_tokens[0, -1, :])
        sampled_char = reverse_target_char_index[sampled_token_index]
        decoded_sentence += sampled_char

        # Exit condition: either hit max length
        # or find stop character.
        if (sampled_char == EOS or len(decoded_sentence) > MAX_LEN):
            stop_condition = True

        # Update the target sequence (of length 1).
        target_seq = np.zeros((1, 1, num_decoder_tokens))
        target_seq[0, 0, sampled_token_index] = 1.

        # Update states
        states_value = [encoded_seq, 
                       next_fwd_hid, next_fwd_cell, 
                       next_bwd_hid, next_bwd_cell]

    # decoded sequence without EOS
    return decoded_sentence
...