#python #keras #deep-learning #lstm #autoencoder
#python #keras #глубокое обучение #lstm #автоэнкодер
Вопрос:
Я определил и обучил модель автоэнкодера следующим образом:
input_enc = Input(batch_shape=(batch_size, seq_len, n_features), name='encoder_input')
first_enc = LSTM(32, activation='tanh', dropout=0.1, recurrent_dropout=0.1, return_sequences=True, stateful=True, name='encoder_first_layer')(input_enc)
if output_dropout:
first_enc = Dropout(0.2)(first_enc)
encoded, hidden_state, cell_state = LSTM(14, activation='tanh', dropout=0.1, recurrent_dropout=0.1, return_sequences=False, return_state=True , stateful=True, name='encoded')(first_enc)
decoder_input = RepeatVector(28, name='repeatVector')(encoded)
first_dec = LSTM(32, return_sequences=True, name='decoder_first_layer')(decoder_input)
out_decoder = LSTM(1, return_sequences=True, name='decoder_output_layer')(first_dec)
autoencoder_model = Model(input_enc, out_decoder)
encoder_model = Model(inputs=input_enc, outputs=[encoded, hidden_state, cell_state])
Форма ввода в модель автоэнкодера является (n_samples, seq_len=28, n_features=1)
и batch_size = 138
После попытки автоэнкодера я загружаю часть кодера и использую ее в качестве входных данных для другой модели.
input_layer = Input(batch_shape=(batch_size, seq_len, n_features), name='ae_prediction_input')
encoder_first_layer = encoder.layers[1](input_layer)
encoded_layer, h_state, c_state = encoder.layers[2](encoder_first_layer)
first_layer = Dense(24, input_dim=28, activation=activation, name="first_dense_layer")(h_state)
if dropout:
first_layer = Dropout(0.2, name="first_dropout_layer")(first_layer)
second_layer = Dense(12, activation=activation, name="second_dense_layer")(first_layer)
if dropout:
second_layer = Dropout(0.2, name="snd_dropout_layer")(second_layer)
out = Dense(1, name='output_layer')(second_layer)
new_model = Model(input_layer, out)
new.compile(loss='mean_squared_error', optimizer=rmsprop_optimizer)
history = new_model.fit(train_data, train_y, epochs=5, callbacks=[earlyStopping], batch_size=batch_size
, validation_data=(validation_data, validation_y), shuffle=False)
Сначала я пытался использовать входной слой кодировщика, но выдает мне эту ошибку: ValueError: Layer encoder_first_layer was called with an input that isn't a symbolic tensor. Received type: <class 'eras.engine.input_layer.InputLayer'>.Full input: [<keras.engine.input_layer.InputLayer object at 0x13b97ced0>]. All inputs to the layer should be tensors.
Поэтому вместо этого я создаю новый входной слой и поверх этого добавляю первый слой LSTM предварительно обученного режима кодировщика. Когда я пытаюсь подогнать new_model
, запускается первая эпоха, и в конце первой эпохи я получаю следующую ошибку:
tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'encoder_input' with dtype float and shape [138,28,1]
[[{{node encoder_input}} = Placeholder[dtype=DT_FLOAT, shape=[138,28,1], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
В чем проблема? Почему запускаются первые эпохи, и после этого он запоминает, что входной уровень кодировщика не получает значения?
ОБНОВЛЕНИЕ: похоже, проблема связана с данными проверки. В конце прошлой эпохи Keras проверяет данные проверки и запускает их. Вот где это выдает эту ошибку.
Комментарии:
1. Не могли бы вы, пожалуйста, предоставить полный пример кода. Под полным я имею в виду, как вы запускаете этот график (например, как вы используете model. fit или model.train_on_batch)?
2. Одна из причин, о которой я могу думать, заключается в том, что, особенно учитывая, что ошибка появляется в конце первой эпохи, поскольку вы специально указываете
batch_shape
, ваш последний пакет входных данных, вероятно, содержит меньше данных (т. Е. Менее 138 записей), что может вызвать наблюдаемое вами исключение. Вы можете попробовать 2 вещи: 1. Вместоbatch_shape
использованияshape
там, где вам не нужно определять размер пакета 2. Если у вас большой объем данных, просто игнорируйте последний пакет данных.3. @thushv89 Спасибо за ваш комментарий.
batch_size=138
разделяет данные обучения и проверки.training.shape=(49956,28,1), validation.shape=(16422,28,1), test.shape=(8004,28,1)
. Я пытался удалитьvalidation_data=(validation_data, validation_y)
изfit()
, он работает и обучает модель без ошибок! Но затем он не запускаетсяnew_model.evaluate(train_data, train_y, verbose=0, batch_size=batch_size)
с той же ошибкой, что и раньше.4. @thushv89 Он жалуется на подачу данных на первый уровень предварительно обученного кодировщика,
encoder_input
который я не загрузил для созданияnew_model
. Вместо этого я использую новыйInput()
слой. Это неправильно?5. Хм, другая причина, о которой я могу думать, заключается в том, что способ создания модели прогнозирования (т. Е.
new_model
) Должен измениться. Вместо полученияmodel.layers[x]
попробуйте создать новый слой, например,LSTM(....)
, а затем использоватьmodel.layers[x].get_weights()
и использовать это дляset_weights
нового слоя в модели прогнозирования.
Ответ №1:
Благодаря ответу @thushv89 я исправил код следующим образом:
encoder = load_model(encoder_path)
input_enc = Input(batch_shape=(batch_size, seq_len, n_features), name='ae_prediction_input')
first_enc = LSTM(encoder.layers[1].units, activation=activation, dropout=encoder.layers[1].dropout, recurrent_dropout=encoder.layers[1].recurrent_dropout, return_sequences=True, stateful=encoder.layers[1].stateful)(input_enc)
encoded, hidden_state, cell_state = LSTM(encoder.layers[2].units, activation=activation, dropout=encoder.layers[2].dropout, recurrent_dropout=encoder.layers[2].recurrent_dropout , return_sequences=False, stateful=encoder.layers[2].stateful)(first_enc)
first_dense = Dense(24, input_dim=28, activation=activation,name="first_dense_layer")(h_state)
if dropout:
first_dense = Dropout(0.2, name="first_dropout_layer")(first_dense)
second_layer = Dense(12, activation=activation, name="second_dense_layer")(first_dense)
if dropout:
second_layer = Dropout(0.2, name="snd_dropout_layer")(second_layer)
out = Dense(1, name='output_layer')(second_layer)
model = Model(input_enc, out)
model.layers[1].set_weights(encoder.layers[1].get_weights())
model.layers[2].set_weights(encoder.layers[2].get_weights())