如何让Keras的LSTM层接受两个输入?

我正在处理最大长度为50的填充序列。我有两种类型的序列数据:

1) 一个整数序列seq1,范围在1到100之间,对应于事件类型(例如[3,6,3,1,45,45….3])

2) 一个整数序列seq2,表示从seq1中的最后一个事件开始的时间,单位为分钟。因此,根据定义,最后一个元素为零。例如[100, 96, 96, 45, 44, 12,… 0]。seq1和seq2的长度相同,都是50。

我试图主要在事件/seq1数据上运行LSTM,但让时间/seq2强烈影响LSTM内部的遗忘门。这样做的原因是我希望LSTM倾向于对较旧的事件进行更严厉的惩罚,并且更有可能忘记它们。我考虑将遗忘权重乘以时间/seq2序列当前值的倒数。或者可能是(1/seq2_element + 1),以处理零分钟的情况。

我在Keras代码(LSTMCell类)中看到了需要更改的地方:

f = self.recurrent_activation(x_f + K.dot(h_tm1_f,self.recurrent_kernel_f))

所以我需要修改Keras的LSTM代码以接受多个输入。作为初步测试,在LSTMCell类中,我将call函数更改为如下形式:

 def call(self, inputs, states, training=None):        time_input = inputs[1]        inputs = inputs[0]

这样它就可以处理以列表形式给出的两个输入。

当我尝试使用函数式API运行模型时:

# 输入1:事件类型序列# 将事件整数序列通过嵌入层转换为浮点向量,然后通过LSTMMain_input = Input(shape =(max_seq_length,), dtype = 'int32', name = 'main_input')x = Embedding(output_dim = embedding_length, input_dim = num_unique_event_symbols, input_length = max_seq_length, mask_zero=True)(main_input)## 输入2:时间向量 auxiliary_input = Input(shape=(max_seq_length,1), dtype='float32', name='aux_input')m = Masking(mask_value = 99999999.0)(auxiliary_input)lstm_out = LSTM(32)(x, time_vector = m)# 来自第一个输入的辅助损失auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)# 此处可以有任意数量的密集隐藏层x = Dense(64, activation='relu')(lstm_out)# 主输出节点main_output = Dense(1, activation='sigmoid', name='main_output')(x)## 编译并拟合模型model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'], loss_weights=[1., 0.2])print(model.summary())np.random.seed(21)model.fit([train_X1, train_X2], [train_Y, train_Y], epochs=1, batch_size=200)

然而,我得到了以下错误:

An `initial_state` was passed that is not compatible with `cell.state_size`. Received `state_spec`=[InputSpec(shape=(None, 50, 1), ndim=3)]; however `cell.state_size` is (32, 32)

有什么建议吗?


回答:

你不能将输入列表传递给Keras中的默认循环层。输入规范是固定的,并且循环代码的实现也是基于单一张量输入的,这一点在文档中也有说明,即它不会神奇地迭代两个相同时间步的输入并将其传递给单元。这部分是因为迭代是如何优化的,以及如果网络是展开的等所做的假设。

如果你喜欢两个输入,你可以将constants文档)传递给单元,这样张量将保持不变。这主要是为了将来实现注意力模型。所以一个输入将迭代时间步,而另一个不会。如果你真的希望两个输入像Python中的zip()一样被迭代,你将不得不实现一个自定义层。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注