Как изменить форму X_train и y_train для LSTM keras

#python #tensorflow #keras #lstm

#питон #тензорный поток #keras #lstm

Вопрос:

У меня есть следующее:

 X_train.shape
(2730, 10)

y_train.shape
(2730)
 

Я хочу обучить модель LSTM с помощью keras, но я не уверен, как изменить входные данные.

Я добавил этот слой LSTM

 time_steps = 30
input_dim = 10 # number of features
...
self.model.add(LSTM(self.hidden_dim, input_shape=(time_steps, self.input_dim), return_sequences=True))
...
 

input_shape не соответствует моему вводу. Как мне изменить форму моего X_train? Должен ли я также изменить форму y_train?

Ответ №1:

Как мне изменить форму моего X_train?

Самым простым вариантом было бы добавить timesteps измерение к вашим данным, чтобы сделать его совместимым с LSTM :

 import tensorflow as tf

samples = 5
features = 10
data = tf.random.normal((samples, features))
time_series_data = tf.expand_dims(data, axis=1) # add timesteps dimension
tf.print('Data -->', tf.shape(data), 'Time series data', tf.shape(time_series_data))
# Data --> [5 10] Time series data [5 1 10]
 

Однако вы хотите использовать 30 timesteps для каждого элемента, ведущего к форме (samples, 30, 10) . Итак, вы можете использовать слой RepeatVector как часть вашей модели или tf.repeat. Вот пример со RepeatVector слоем:

 model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10, input_shape=(features,)))
model.add(tf.keras.layers.RepeatVector(30))
model.add(tf.keras.layers.LSTM(32))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
model.build((1, 10))
tf.print(model.summary())
 
 Model: "sequential_01"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_24 (Dense)            (None, 10)                110       
                                                                 
 repeat_vector_1 (RepeatVect  (None, 30, 10)           0         
 or)                                                             
                                                                 
 lstm_3 (LSTM)               (None, 32)                5504      
                                                                 
 dense_25 (Dense)            (None, 1)                 33        
                                                                 
=================================================================
Total params: 5,647
Trainable params: 5,647
Non-trainable params: 0
_________________________________________________________________
None
 

Вы также можете сначала сопоставить 10 объектов с 300-мерным выводом, а затем изменить форму вывода, чтобы он соответствовал LSTM :

 model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(300, input_shape=(features,)))
model.add(tf.keras.layers.Reshape((30, 10)))
model.add(tf.keras.layers.LSTM(32))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
 
 Model: "sequential_02"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_26 (Dense)            (None, 300)               3300      
                                                                 
 reshape (Reshape)           (None, 30, 10)            0         
                                                                 
 lstm_4 (LSTM)               (None, 32)                5504      
                                                                 
 dense_27 (Dense)            (None, 1)                 33        
                                                                 
=================================================================
Total params: 8,837
Trainable params: 8,837
Non-trainable params: 0
_________________________________________________________________
None
 

На вопрос:

Должен ли я также изменить форму y_train?

Это зависит от того, что вы хотите. Если у вас есть только простая задача классификации, как я предполагал в примерах, то вам не нужно изменять y_train.

Обновление 1: вы также можете изменить свои данные следующим образом. В результате получается тензор с 91 образцом, где каждый образец имеет 30 временных шагов, и каждый временной шаг связан с 10 объектами.

 import tensorflow as tf

timesteps = 2730
features = 10
data = tf.random.normal((timesteps, features))
data = tf.reshape(data, (91, 30, features))
print(data.shape)
# (91, 30, 10)
 

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

1. Соответствует ли 32 единицам, которые вы ввели для model.add(tf.keras. layers.LSTM(32)) имеют определенное значение или могут быть произвольно заменены?

2. Никакого конкретного значения, просто выходное пространство LSTM. Определите это так, как вы хотите.

3. Спасибо. Только одна вещь не ясна в RepeatVector() . Если он просто «повторяет» входные данные n раз, как он отражает последовательный характер временных рядов? Я что-то упускаю из виду? Я думал, что временные шаги (30) должны быть не просто повторением ввода 30 раз, а 30 фактическими шагами во временном ряду.

4. Да, вы правы! Но дело в том, что ваши данные, как они есть, не имеют последовательного характера. Вот почему я сделал те предложения, которые я сделал. Хотя я бы рекомендовал использовать первый вариант.

5. Данные, которые я использую, на самом деле представляют собой временные ряды