我正在训练一个LSTM来预测事件的发生。对于每一天,我有一个像[1,0,1]这样的向量来表示第一个和第三个事件发生了,而第二个事件没有发生。
我想把这个问题扩展到多人,其中每个人都有一个不同的agent_id
。这意味着我需要以某种方式将agent_id
作为特征呈现我的模型。虽然我不确定这是否是最好的方法,但我将向量的第一个条目设置为agent_id
,因此它看起来像[123456,1,0,1]。
现在LSTM模型所做的是为每个事件输出它在第二天发生的概率。因此,我看到的输入/输出将是:[agent_id,事件1今天发生了吗?事件2今天发生了吗?事件3今天发生了吗?)→LSTM→[事件1明天发生的概率,事件2明天发生的概率,事件3明天发生的概率]
现在输入的长度比输出的长。据我所知,从这个帖子https://stats.stackexchange.com/questions/305863/how-to-train-lstm-model-on-multiple-time-series-data的答案来看,我需要一个可以改变输入大小的嵌入层,这样LSTM就能给我想要的输出。
对于这个,我尝试做以下操作:
from keras.models import Sequential
from keras.layers import *
xin = Input(batch_shape=(batch_size, window_length), dtype='int32')
xemb = Embedding(x_traindict[123456].shape[2], x_traindict[123456].shape[2]-1)(xin) #from what I give in to what I want to get out # 3dim (batch,time,feat)
seq = LSTM(x_traindict[123456].shape[2]-1, return_sequences=True)(xemb)
mlp = TimeDistributed(Dense(y_traindict[123456].shape[1], activation='softmax'))(seq)
model = tf.keras.Model(inputs=xin, outputs=mlp)
model.compile(optimizer='Adam', loss='categorical_crossentropy')
print(f"batch size is {batch_size}, window_length = {window_length}, x_train.shape is {x_traindict[123456].shape} and y_train.shape is {y_traindictalt[123456].shape}")
model.summary()
model.fit(x_traindict[123456], y_traindict[123456], epochs=20)
------------------------------------------------------------------------------------------------
batch size is 358, window_length = 7, x_train.shape is (358, 7, 149) and y_train.shape is (358, 148)
Model: "model_7"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_12 (InputLayer) [(358, 7)] 0
embedding_14 (Embedding) (358, 7, 148) 22052
lstm_16 (LSTM) (358, 7, 148) 175824
time_distributed_11 (TimeDi (358, 7, 149) 22201
stributed)
=================================================================
Total params: 220,077
Trainable params: 220,077
Non-trainable params: 0
_________________________________________________________________
我的想法是嵌入将从x_train中获取输入,包括agent_id
,并将学习将其编码为y_train大小的输入,其中不包括agent_id
。然后LSTM将学习处理从嵌入中接收到的信息,以正确预测y_train。但是,上面的代码给了我以下错误:
ValueError: Exception encountered when calling layer "model_7" (type Functional).
Input 0 of layer "lstm_16" is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: (None, 7, 149, 148)
我不明白这个错误。
我想问的是:
- 我的想法有意义吗?通过直接使用事件实现
agent_id
, LSTM能否学习不同agent的时间序列预测? - 我如何修复我的代码中的错误?如果有帮助,我基本上填写了这个帖子的第一个答案的模板:https://github.com/keras-team/keras/issues/2654
编辑:
- 我已经尝试将xin更改为
xin = Input(batch_shape=(window_length,), dtype='int32')
,但现在得到一个值错误在我说seq =…:Input 0 of layer "lstm_26" is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: (7, 133).
- 我也尝试将xin更改为
xin = Input(batch_shape=(window_length,number_of_transactions+1), dtype='int32')
,但这会产生ValueError: Input 0 of layer "model_11" is incompatible with the layer: expected shape=(None, 134), found shape=(None, 7, 134)
注意:我今天必须拿一个新的样品。134取代了上面的149个事件
-
是的,我认为这个想法是有效的。通过将agent-id作为序列中的第一个元素,RNN将在随后用于预测事件概率的状态中编码该信息。需要注意的一件事是,模型将尝试仅给定第一个序列元素(agent-id)来生成预测。
-
我认为你的问题是你在输入调用中包含了批大小,但批大小是隐含的,不需要定义,所以
xin = Input(batch_shape=(batch_size, window_length), dtype='int32')
应该变成xin = Input(batch_shape=(window_length), dtype='int32')