让keras LSTM层接受两个输入?

时间:2018-05-09 17:35:46

标签: tensorflow machine-learning deep-learning keras lstm

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

1)与事件类型相对应的整数(1-100)的序列seq1(例如[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类中,我将调用函数更改为如下所示:

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

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

当我尝试使用Functional API运行模型时:

# Input 1: event type sequences
# Take the event integer sequences, run them through an embedding layer to get float vectors, then run through LSTM
main_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)

## Input 2: time vectors 
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 loss here from first input
auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)

# An abitrary number of dense, hidden layers here
x = Dense(64, activation='relu')(lstm_out)

# The main output node
main_output = Dense(1, activation='sigmoid', name='main_output')(x)

## Compile and fit the model
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)

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

您无法将输入列表传递给Keras中的默认循环图层。 input_spec是固定的,并且循环代码是基于documentation中指出的单张量输入实现的,即它没有神奇地迭代相同时间步长的2个输入并将其传递给细胞。部分原因在于如何优化迭代并在网络展开时做出假设等。

如果您喜欢2个输入,则可以将constantsdoc)传递给将按原样传递张量的单元格。这主要是为了在未来实施关注模型。因此,1个输入将迭代时间步长而另一个则不会。如果您真的喜欢在python中像zip()那样迭代2个输入,则必须实现自定义层。