как сделать вывод с помощью модели многослойного кодера-декодера в керасе? - PullRequest
0 голосов
/ 01 февраля 2019

Я разработал модель последовательности для последовательности для прогнозирования временных рядов, внимательно следя за публикацией в блоге здесь: https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html.

Я попытался расширить модель до многослойной модели, используя следующий код:

encoder_inputs = Input(shape=(None, train_data.shape[2]), name='encoder_mask')
# Allows handling of variable length inputs by applying a binary mask to the specified mask_value.
masker = Masking(mask_value=mask_value)
masker(encoder_inputs)

# Define an input series and encode it with an LSTM.
if len(hidden_layers) == 1:
    encoder_inputs = Input(shape=(None, train_data.shape[2]), name='encoder')
    encoder = CuDNNLSTM(latent_dim, return_state=True)
    encoder_outputs, state_h, state_c = encoder(encoder_inputs)
else:
    units = hidden_layers[0]
    encoder_inputs = Input(shape=(None, train_data.shape[2]), name='encoder')
    encoder = CuDNNLSTM(units=units, return_sequences=True)(encoder_inputs)
    for units in hidden_layers[1:-1]:
        encoder = CuDNNLSTM(units, return_sequences=True)(encoder)
    units = hidden_layers[-1]
    encoder_outputs, state_h, state_c = CuDNNLSTM(units, return_state=True)(encoder)

# We discard `encoder_outputs` and only keep the final states. These represent the "context"
# vector that we use as the basis for decoding.
encoder_states = [state_h, state_c]

# We set up our decoder using `encoder_states` as initial state.
# We return full output sequences and return internal states as well.
# We don't use the return states in the training model, but we will use them in inference.
decoder_layers = []
if len(hidden_layers) == 1:
    # Set up the decoder, using `encoder_states` as initial state.
    # This is where teacher forcing inputs are fed in.
    decoder_inputs = Input(shape=(None, 1), name='decoder')
    decoder_lstm = CuDNNLSTM(hidden_layers[-1], return_sequences=True, return_state=True, name='decoder_first')
    decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
else:
    units = hidden_layers[-1]
    decoder_inputs = Input(shape=(None, 1), name='decoder')
    decoder_first = CuDNNLSTM(units, return_sequences=True, name='decoder_first')
    decoder = decoder_first(decoder_inputs, initial_state=encoder_states)

    for units in hidden_layers[::-1][1:-1]:
        decoder_hidden = CuDNNLSTM(units, return_sequences=True)
        decoder_layers.append(decoder_hidden)
        decoder = decoder_hidden(decoder)

    units = hidden_layers[0]
    decoder_last = CuDNNLSTM(units, return_sequences=True, return_state=True, name='decoder_last')
    decoder_outputs, _, _ = decoder_last(decoder)

decoder_dense = Dense(units=1, activation='linear')  # 1 continuous output at each timestep
decoder_outputs = decoder_dense(decoder_outputs)

Я не уверен, как приступить к созданию новой модели для вывода, чтобы у меня была другая длина предсказания из моих входных последовательностей.Сначала я попытался просто ввести последовательность в первый слой декодера, как в примере с сообщением в блоге.Однако это не сработало, так как не возвращает состояния, последний слой делает.Затем я попытался поместить входные данные в последний слой декодера, и это не сработало, потому что ожидалось 3D-форма вместо 2D-формы.Затем я нашел этот пост Многослойная модель Seq2Seq с LSTM в Keras , которая дала мне идею, что на самом деле мне нужно пропустить последовательность через все слои декодера вручную (поэтому я добавляю их в список, я незнать, является ли это правильным (лучшим) подходом или нет.), как показано здесь:

# from our previous model - mapping encoder sequence to state vectors
encoder_model = Model(encoder_inputs, encoder_states)

# A modified version of the decoding stage that takes in predicted target inputs
# and encoded state vectors, returning predicted target outputs and decoder state vectors.
# We need to hang onto these state vectors to run the next step of the inference loop.
decoder_state_input_h = Input(shape=(units,))
decoder_state_input_c = Input(shape=(units,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]

#decoder_outputs = decoder_first(decoder_inputs, initial_state=decoder_states_inputs)

decoder_outputs = decoder_first(decoder_inputs, initial_state=encoder_states)
decoder_outputs = decoder_layers[0](decoder_outputs)        
decoder_outputs, state_h, state_c = decoder_last(decoder_outputs)

decoder_states = [state_h, state_c]

decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)

Однако, выполнив это и запустив указанный выше фрагмент кода, я теперь получаю следующую ошибку:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-18-77cda21e84ad> in <module>
     19 
     20 decoder_outputs = decoder_dense(decoder_outputs)
---> 21 decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
     22 
     23 train_mean = train_dict['train_mean']

/lib/python3.6/site-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name + '` call to the ' +
     90                               'Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

/lib/python3.6/site-packages/keras/engine/network.py in __init__(self, *args, **kwargs)
     91                 'inputs' in kwargs and 'outputs' in kwargs):
     92             # Graph network
---> 93             self._init_graph_network(*args, **kwargs)
     94         else:
     95             # Subclassed network

/lib/python3.6/site-packages/keras/engine/network.py in _init_graph_network(self, inputs, outputs, name)
    229         # Keep track of the network's nodes and layers.
    230         nodes, nodes_by_depth, layers, layers_by_depth = _map_graph_network(
--> 231             self.inputs, self.outputs)
    232         self._network_nodes = nodes
    233         self._nodes_by_depth = nodes_by_depth

/lib/python3.6/site-packages/keras/engine/network.py in _map_graph_network(inputs, outputs)
   1441                                          'The following previous layers '
   1442                                          'were accessed without issue: ' +
-> 1443                                          str(layers_with_complete_input))
   1444                 for x in node.output_tensors:
   1445                     computable_tensors.append(x)

ValueError: Graph disconnected: cannot obtain value for tensor Tensor("encoder:0", shape=(?, ?, 10), dtype=float32) at layer "encoder". The following previous layers were accessed without issue: []

Так что, очевидно, я делаю что-то не так.Когда у меня один слой кодировщика и декодера, все работает как положено.Когда я пытаюсь создать много слоев декодера, у меня возникают проблемы.Я не совсем понимаю, как настроить многослойный декодер для вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...