Для поэтапной передачи входных данных вам нужны повторяющиеся слои с stateful=True
.
Сверточный слой наверняка помешает вам достичь того, что вы хотите. Либо вы удаляете его, либо вы передаете входные данные группами по 15 шагов (где 15 - размер вашего ядра для свертки).
Вам нужно будет согласовать эти 15 шагов с шагом 4 и, возможно, потребуется заполнение. Если я могу предложить, чтобы избежать математических трудностей, вы можете использовать kernel_size=16
, stride=4
и input_steps = 5512
, это кратное 4
, которое является вашим значением шага. (Это позволит избежать заполнения и упростит вычисления), и ваши выходные шаги будут 1375 идеально круглыми.
Тогда ваша модель будет выглядеть так:
inputs = Input(batch_shape=(batch_size,None, 101)) #where you will always use input shapes of (batch_size, 16, 101)
out = Conv1D(196, 16, strides=4)(inputs)
...
...
out = GRU(..., stateful=True)(out)
...
out = GRU(..., stateful=True)(out)
...
...
model = Model(inputs, out)
Необходимо иметь фиксированный размер партии с моделью stateful=True
. Это может быть 1, но для оптимизации скорости обработки, если у вас есть несколько последовательностей для параллельной обработки (и независимо друг от друга), используйте больший размер пакета.
Для пошаговой обработки, Прежде всего, вам нужно сбросить состояния (всякий раз, когда вы используете модель stateful=True
, вам необходимо сохранять сброс состояний каждый раз, когда вы собираетесь передавать новую последовательность или новую серию параллельных последовательностей).
Итак:
#will start a new batch containing a number of sequences equal to batch_size:
model.reset_states()
#received 16 steps from batch_size sequences:
steps = an_array_shaped((batch_size, 16, 101))
#for training
model.train_on_batch(steps, something_for_y_shaped((batch_size, 1, 1)), ...)
#I don't recommend to train like this because of the batch normalizations
#If you can train the entire length at once, do it.
#never forget: for full length training, you would need model.reset_states() every batch.
#for predicting:
predictions = model.predict_on_batch(steps, ...)
#received 4 new steps from X sequences:
steps = np.concatenate([steps[:,4:], new_steps], axis=1)
#these new steps belong to the "same" batch_size sequences! Don't call reset states!
#repeat one of the above for training or predicting
new_predictions = model.predict_on_batch(steps, ...)
predictions = np.concatenate([predictions, new_predictions], axis=1)
#keep repeating this loop until you reach the last step
Finally, when you reached the last step, for safety, call `model.reset_states()` again, everything that you input will be "new" sequences, not new "steps" or the previous sequences.
------------
# Training hint
If you are able to train with the full sequences (not step by step), use a `stateful=False` model, train normally with `model.fit(...)`, later you recreate the model exactly, but using `stateful=True`, copy the weights with `new_model.set_weights(old_model.get_weights())`, and use the new model for predicting like above.