Построение быстрой модели GRU для прогнозирования запасов

#python #tensorflow #keras #recurrent-neural-network #gated-recurrent-unit

Вопрос:

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

У меня есть массив numpy для обучающих данных с этой формой:

 train_x.shape (1122,20,320)  
 `1122` represents the total amount timestamps I have `20` is the amount of timestamps I want to predict the future from `320` is the number of features (different stocks)  

Мой train_y.shape — (1122,) и представляет двоичную переменную с 1 и 0 . 1 это покупка 0 -это продажа.

С этой мыслью я начал пробовать свою GRU модель как:

 def GRU_model(train_x,train_y,test_x,test_y):   model = Sequential()  model.add(layers.Embedding(train_x.shape[0],50,input_length=320))  model.add(layers.GRU(50, return_sequences=True,input_shape=(train_x.shape[1],1),activation='tanh'))  model.add(layers.GRU(50, return_sequences=True,input_shape=(train_x.shape[1],1),activation='tanh'))  model.add(layers.GRU(50, return_sequences=True,input_shape=(train_x.shape[1],1),activation='tanh'))  model.add(layers.GRU(50,activation='tanh'))  model.add(Dense(units=2))  model.compile(optimizer=SGD(lr=0.01,decay=1e-7,momentum=0.9,nesterov=False),loss='mean_squared_error')    model.fit(train_x,train_y,epochs=EPOCHS,batch_size=BATCH_SIZE)   GRU_predict = model.predict(validation_x)   return model,GRU_predict    my_gru_model,my_gru_predict = GRU_model(train_x,train_y,validation_x,validation_y) ValueError: Input 0 of layer gru_42 is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: (None, 20, 320, 50)  

Очевидно, что мои входные размеры в модель неверны, но я не понимаю, как они должны вписываться, чтобы модель могла работать плавно.

Ответ №1:

Поэтому, если у вас есть 1122 образца данных, и каждый образец содержит 20 временных шагов, и каждый временной шаг содержит 320 функций, и вы хотите научить свою модель принимать двоичное решение между покупкой и продажей, попробуйте что-то вроде этого:

 import tensorflow as tf tf.random.set_seed(1)  model = tf.keras.Sequential() model.add(tf.keras.layers.GRU(50, return_sequences=True, input_shape=(20, 320), activation='tanh')) model.add(tf.keras.layers.GRU(50,activation='tanh')) model.add(tf.keras.layers.Dense(units=1, activation='sigmoid'))  model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.01,decay=1e-7,momentum=0.9,nesterov=False),loss='binary_crossentropy') print(model.summary())  train_x = tf.random.normal((1122, 20, 320)) train_y = tf.random.uniform((1122,), maxval=2, dtype=tf.int32) model.fit(train_x, train_y, epochs=5, batch_size=16)  
 Model: "sequential" _________________________________________________________________  Layer (type) Output Shape Param #  =================================================================  gru (GRU) (None, 20, 50) 55800     gru_1 (GRU) (None, 50) 15300     dense (Dense) (None, 1) 51    ================================================================= Total params: 71,151 Trainable params: 71,151 Non-trainable params: 0 _________________________________________________________________ None Epoch 1/5 71/71 [==============================] - 5s 21ms/step - loss: 0.7050 Epoch 2/5 71/71 [==============================] - 2s 22ms/step - loss: 0.6473 Epoch 3/5 71/71 [==============================] - 1s 21ms/step - loss: 0.5513 Epoch 4/5 71/71 [==============================] - 1s 21ms/step - loss: 0.3640 Epoch 5/5 71/71 [==============================] - 1s 20ms/step - loss: 0.1258 lt;keras.callbacks.History at 0x7f4eac87e610gt;  

Обратите внимание, что у вас есть один выходной узел, потому что ваша модель должна принимать двоичное решение. Это также причина, по которой вы должны использовать функцию потерь binary_crossentropy .

Что касается слоя GRU, он ожидает ввода с формой (batch_size, timesteps, features) , но размер пакета выводится во время обучения и, следовательно, в нем опущен input_shape . Поскольку для следующего GRU также требуется эта форма, вы используете параметр return_sequences=True в первом GRU, который возвращает последовательность с формой (batch_size, 20, 50) =gt; один вывод скрытого состояния gt; 50 для каждого шага времени ввода n . Также вам не нужен Embedding слой в вашем случае. Он обычно используется для отображения целочисленных последовательностей, представляющих текст, в n многомерные векторные представления.

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

1. да, это работает, не могли бы вы, пожалуйста, объяснить эту строку model.add(tf.keras.layers.GRU(50, return_sequences=True, input_shape=(20, 320), activation='tanh')) , спасибо

2. Я пробовал использовать Embedding , но это не работает, скорее всего, я ошибаюсь. 🙂

3. Обновленный ответ с пояснением внизу.