Обучение многовариантной задаче многосерийной регрессии с сохранением состояния LSTM в Keras

#python #machine-learning #keras #lstm #recurrent-neural-network

#python #машинное обучение #keras #lstm #рекуррентная нейронная сеть

Вопрос:

У меня есть временные ряды P процессов, каждый из которых имеет различную длину, но все они имеют 5 переменных (измерений). Я пытаюсь предсказать предполагаемое время жизни тестового процесса. Я подхожу к этой проблеме с сохранением состояния LSTM в Keras. Но я не уверен, что мой процесс обучения правильный.

Я делю каждую последовательность на пакеты длины 30 . Таким образом, каждая последовательность имеет форму, (s_i, 30, 5) где s_i отличается для каждой из P последовательностей ( s_i = len(P_i)//30 ). Я добавляю все последовательности в свои обучающие данные, которые имеют форму, (N, 30, 5) где N = s_1 s_2 ... s_p .

Модель:

 # design network
model = Sequential()
model.add(LSTM(32, batch_input_shape=(1, train_X[0].shape[1], train_X[0].shape[2]), stateful=True, return_sequences=True))
model.add(LSTM(16, return_sequences=False))
model.add(Dense(1, activation="linear"))
model.compile(loss='mse', optimizer=Adam(lr=0.0005), metrics=['mse'])
  

model.summary() Выглядит так

 _________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm_1 (LSTM)                (1, 30, 32)               4864      
_________________________________________________________________
lstm_2 (LSTM)                (1, 16)                   3136      
_________________________________________________________________
dense_1 (Dense)              (1, 1)                    17        
=================================================================
  

Циклы обучения:

 for epoch in range(epochs):
    mean_tr_acc = []
    mean_tr_loss = []
        
    for seq in range(train_X.shape[0]): #24
            
        # train on whole sequence batch by batch
        for batch in range(train_X[seq].shape[0]): #68
            b_loss, b_acc = model.train_on_batch(np.expand_dims(train_X[seq][batch], axis=0), train_Y[seq][batch][-1])    
                
            mean_tr_acc.append(b_acc)
            mean_tr_loss.append(b_loss)
                
        #reset lstm internal states after training of each complete sequence
        model.reset_states()
  

Редактировать:

Проблема с графиком потерь заключалась в том, что я делил значения в своих пользовательских потерях, делая их слишком маленькими. Если я удалю деление и построю график потерь логарифмически, это выглядит нормально.

Новая проблема:

Как только обучение завершено, я пытаюсь предсказать. Я показываю своей модели 30 временных выборок нового процесса; таким образом, форма ввода такая же, как batch_input_shape во время обучения, т. Е. (1, 30, 5) . Прогноз, который я получаю для разных пакетов одной и той же последовательности, все одинаковы.

Я почти уверен, что делаю что-то не так в процессе обучения. Если бы кто-нибудь мог мне помочь, был бы благодарен. Спасибо.

Редактировать 2:

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

Потеря за 25 эпох выглядит следующим образом: loss_25epochs

Комментарии:

1. Каков результат модели? является ли это логической оценкой того, что процесс будет продолжаться?

2. Нет, выводом является a float , который является расчетным оставшимся временем процесса.

3. Какова ваша функция custom_loss()?

4. @Anakin ок, отлично! поскольку у вас не так много данных, будет сложно проверить, связана ли это проблема со структурой сети или с самими данными. Я бы посоветовал попробовать получить больше очков или упростить структуру, чтобы она не перегружалась.

5. Обычно, когда результаты одинаковы, это потому, что ваши данные не нормализованы. Я предлагаю вам сосредоточить свои данные вокруг 0 с помощью простого обычного преобразования (т. Е. (среднее значение данных)/ std ). Попробуйте преобразовать его таким образом перед обучением и тестированием.

Ответ №1:

Обычно, когда результаты одинаковы, это потому, что ваши данные не нормализованы. Я предлагаю вам центрировать свои данные с помощью mean = 0 и std = 1 с помощью простого обычного преобразования (т. Е. (среднее значение данных)/ std ). Попробуйте преобразовать его таким образом перед обучением и тестированием. Различия в том, как данные нормализуются между наборами обучения и тестирования, также могут вызывать проблемы, которые могут быть причиной вашего несоответствия в обучении и потере теста. Всегда используйте один и тот же метод нормализации для всех ваших данных.