【问题标题】:Training on sequences of sentences using Keras使用 Keras 训练句子序列
【发布时间】:2018-12-22 05:59:02
【问题描述】:

我正在开展一个项目,我必须在神经网络中使用数字和文本数据的组合来预测系统下一小时的可用性。我没有尝试使用单独的神经网络并在最后(对我来说)做一些奇怪/不清楚的事情来产生所需的输出,而是决定使用 Keras 的合并层和两个网络(一个用于数字数据,一个用于文本)。这个想法是我为模型提供了前 6 个小时的一系列性能指标,格式为 (batch_size, 6hrs, num_features)。除了我为处理数字数据的网络提供的输入之外,我还为第二个网络提供了另一个大小序列(batch_size、max_alerts_per_sequence、max_sentence 长度)。

时间范围内的任何数字数据序列都可以有可变数量的事件(文本数据)与之关联。为简单起见,我只允许最多 50 个事件伴随一系列性能数据。每个事件都由单词散列编码并填充。我尝试使用扁平层将输入形状从 (50, 30) 减少到 (1500),以便模型可以在这些“序列”中的 每个 事件上进行训练(澄清:我通过为每个性能数据序列建模 50 个句子,每个句子包含 30 个编码元素)。

我的问题是:由于我需要 NN 来查看给定性能指标序列的所有事件,我如何才能使 NN 用于句子序列上的基于文本的数据训练?

我的模特:

#LSTM Module for performance metrics
input = Input(shape=(shape[1], shape[2]))
lstm1 = Bidirectional(LSTM(units=lstm_layer_count, activation='tanh', return_sequences=True, input_shape=shape))(input)
dropout1 = Dropout(rate=0.2)(lstm1)
lstm2 = Bidirectional(LSTM(units=lstm_layer_count, activation='tanh', return_sequences=False))(dropout1)
dropout2 = Dropout(rate=0.2)(lstm2)

#LSTM Module for text based data
tInput = Input(shape=(50, 30))
flatten = Flatten()(tInput)
embed = Embedding(input_dim=vocabsize + 1, output_dim= 50 * 30, input_length=30*50)(flatten)
magic = Bidirectional(LSTM(100))(embed)
tOut = Dense(1, activation='relu')(magic)

#Merge the layers
concat = Concatenate()([dropout2, tOut])
output = Dense(units=1, activation='sigmoid')(concat)

nn = keras.models.Model(inputs=[input, tInput], outputs = output)

opt = keras.optimizers.SGD(lr=0.1, momentum=0.8, nesterov=True, decay=0.001)
nn.compile(optimizer=opt, loss='mse', metrics=['accuracy', coeff_determination])

【问题讨论】:

  • 我没有详细理解您的问题。也许您可以改写一下?我正在使用类似的东西。我也有文本数据和数字数据。在我的情况下,我有 n 个句子,其中每个句子(嵌入空间中的单词序列)都通过其“自己的”LSTM,但权重是共享的。最后,我将所有 LSTM 输出放入一维卷积中,然后与数值数据相连接。
  • 您似乎很好理解了这个问题,但我还是会尝试改写它!给定每个数字数据点实例包含多个句子的数字和文本数据(编码为长度为 30 的词向量),我如何训练一个利用这两种数据类型的模型?根据您的建议:我会尝试这种方法。但是,如果您正在为 N 个句子训练 N 个 LSTM,那么即使您仍然共享权重,训练和预测的速度是不是太慢了?
  • 是的,这会非常慢,如果每个句子都有一个 LSTM,在我的情况下,我们并不是在谈论句子,它更像是消息。但是通过一些调整它可以工作。 this 是否描述了您的问题?
  • 是的,该链接肯定能捕捉到我想要做的事情。然而,这个实现似乎只处理数字数据序列和单个消息,而不是消息序列。换句话说,而不是从:“猫发出咕噜声”-> [1, 2, 3] -> 模型。我需要从:“猫发出咕噜声” -> [1,2,3] “狗吠” -> [1, 4, 5] “海豚游泳” -> [1, 6, 7] -> [1,2,3; 1,4,5; 1,6,7] -> 模型

标签: python machine-learning neural-network keras


【解决方案1】:

据我了解,您有一个最多 50 个事件的序列,您希望对其进行预测。这些事件附加了文本数据,可以将其视为另一个词嵌入序列。 Here 是一篇关于类似架构的文章。

我会提出一个解决方案,其中涉及文本部分的 LSTM,以及“真实”序列部分的一维卷积。每个 LSTM 层都与数字数据连接。这涉及 50 个 LSTM 层,即使您使用共享权重,训练也可能很耗时。也可以只对文本部分使用卷积层,这样更快,但不能对长期依赖关系进行建模。 (我有经验,这些长期依赖在文本挖掘中通常并不重要)。

文本 -> LSTM 或 1DConv -> 与数字数据连接 -> 1DConv -> 输出 这是一些示例代码,它显示了如何使用分片权重

numeric_input = Input(shape=(x_numeric_train.values.shape[1],), name='numeric_input')
nlp_seq = Input(shape=(number_of_messages ,seq_length,), name='nlp_input'+str(i))

# shared layers
emb = TimeDistributed(Embedding(input_dim=num_features, output_dim=embedding_size,
                input_length=seq_length, mask_zero=True,
                input_shape=(seq_length, )))(nlp_seq)    
x = TimeDistributed(Bidirectional(LSTM(32, dropout=0.3, recurrent_dropout=0.3, kernel_regularizer=regularizers.l2(0.01))))(emb)      

c1 = Conv1D(filter_size, kernel1, padding='valid', activation='relu', strides=1, kernel_regularizer=regularizers.l2(kernel_reg))(x)
p1 = GlobalMaxPooling1D()(c1)
c2 = Conv1D(filter_size, kernel2, padding='valid', activation='relu', strides=1, kernel_regularizer=regularizers.l2(kernel_reg))(x)
p2 = GlobalMaxPooling1D()(c2)
c3 = Conv1D(filter_size, kernel3, padding='valid', activation='relu', strides=1, kernel_regularizer=regularizers.l2(kernel_reg))(x)
p3 = GlobalMaxPooling1D()(c3)

x = concatenate([p1, p2, p3, numeric_input])    
x = Dense(1, activation='sigmoid')(x)        
model = Model(inputs=[nlp_seq, meta_input] , outputs=[x])
model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])    

和培训:

model.fit([x_train, x_numeric_train], y_train)
# where x_train is a a array of num_samples * num_messages * seq_length

像这样的复杂模型需要大量数据才能收敛。对于较少的数据,可以通过将事件聚合为只有一个序列来实现更简单的解决方案。例如,所有事件的文本数据可以被视为一个单独的文本(带有分隔符),而不是多个文本,而数值数据可以被求和、平均甚至组合成一个固定长度的列表。但这取决于您的数据。

由于我正在做类似的事情,我稍后会用代码更新这些答案。

【讨论】:

  • 感谢@Digital-Thinking 的帮助。 TimeDistributed 会做同样的事情吗?根据我对文档的理解,TimeDistributed 层将目标层应用于输入的每个切片。对我来说,这意味着模型会自动为序列中的每个警报创建一个 LSTM 层,它完成与上述代码中的 for 循环相同的事情。
  • 很好的提示!我认为 TimeDistributed 也可以,但是您输入的数据必须采用正确的格式。我明天会更新答案
猜你喜欢
  • 2017-07-07
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-25
  • 2018-01-30
  • 2020-03-06
相关资源
最近更新 更多