如何在 Keras 中使用附加功能和词嵌入?

Posted

技术标签:

【中文标题】如何在 Keras 中使用附加功能和词嵌入?【英文标题】:How to use additional features along with word embeddings in Keras ? 【发布时间】:2018-08-16 23:23:29 【问题描述】:

我正在使用 Keras 在数据集上训练 LSTM 模型,如下所示。变量“描述”是一个文本字段,“年龄”和“性别”是分类和连续字段。

Age, Gender, Description
22, M, "purchased a phone"
35, F, "shopping for kids"

我正在使用词嵌入将文本字段转换为词向量,然后将其输入到 keras 模型中。代码如下:

model = Sequential()
model.add(Embedding(word_index, 300, weights=[embedding_matrix], input_length=70, trainable=False))

model.add(LSTM(300, dropout=0.3, recurrent_dropout=0.3))
model.add(Dropout(0.6))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics['accuracy'])

此模型运行成功,但我也想输入“年龄”和“性别”变量作为特征。代码中还需要哪些更改才能使用这些功能?

【问题讨论】:

您能告诉我您是如何输入包含AgeGender 的文件的吗? 【参考方案1】:

您想添加更多的输入层,这是顺序模型无法实现的,您必须使用功能模型

from keras.models import Model

它允许您有多个输入和间接连接。

embed = Embedding(word_index, 300, weights=[embedding_matrix], input_length=70, trainable=False)
lstm = LSTM(300, dropout=0.3, recurrent_dropout=0.3)(embed)
agei = Input(shape=(1,))
conc = Concatenate()(lstm, agei)
drop = Dropout(0.6)(conc)
dens = Dense(1)(drop)
acti = Activation('sigmoid')(dens)

model = Model([embed, agei], acti)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics['accuracy'])

您不能在 LSTM 层之前进行连接,因为它没有意义,而且在嵌入层之后您将拥有 3D 张量,并且输入是 2D 张量。

【讨论】:

ageiagegender 的输入,对吧?如果是这样,我如何使用包含年龄和性别信息的input.csv @userxxx 嘿,你能分享你的完整代码吗?我想使用带有词嵌入的附加功能。 您可以在此处找到包含实际数据集的完整示例:stackabuse.com/…【参考方案2】:

我写了关于how to do this in keras。它基本上是一个功能性多输入模型,它像这样连接两个特征向量:

nlp_input = Input(shape=(seq_length,), name='nlp_input')
meta_input = Input(shape=(10,), name='meta_input')
emb = Embedding(output_dim=embedding_size, input_dim=100, input_length=seq_length)(nlp_input)
nlp_out = Bidirectional(LSTM(128))(emb)
x = concatenate([nlp_out, meta_input])
x = Dense(classifier_neurons, activation='relu')(x)
x = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[nlp_input , meta_input], outputs=[x])

【讨论】:

感谢您提供的重要信息。我正在为我的用例遵循您的代码并获得InvalidArgumentError: input 1 should contain 3 elements, but got 2[[node training/Adam/gradients/concatenate_1/concat_grad/ConcatOffset]]。你知道为什么吗?我在这里和 Github 上检查了几个小时,但到目前为止没有运气。 @ixeption 阅读您的文章。如果您有两个文本列,例如 [title, article] - 在多分类问题中怎么办。 [同意,不同意,讨论,无关]。你是否为每一个创建嵌入,然后将其传递给一个 LSTM?我从上面了解到,连接是没有意义的。在 LSTM 之前,但是如何将两个不同的嵌入传递给 LSTM?是不是像 LSTM()([embed1, embed2]) 一样简单 @StackPancakes 我会为两个 nlp 输入使用相同的嵌入和 LSTM,并将 LSTM 的输出连接在一起。您可以使用 TimeDistributed Layer,您的维度为 2。我对 Chats 做了类似的事情。【参考方案3】:

考虑有一个单独的前馈网络来接收这些特征并输出一些 n 维向量。

time_independent = Input(shape=(num_features,))
dense_1 = Dense(200, activation='tanh')(time_independent)
dense_2 = Dense(300, activation='tanh')(dense_1)

首先,请使用 keras 的functional API 来做这样的事情。

然后,您可以将其作为 LSTM 的隐藏状态传入,也可以将其与每个词嵌入连接起来,以便 lstm 在每个时间步都能看到它。在后一种情况下,您可能希望大幅降低网络的维数。

如果您需要示例,请告诉我。

【讨论】:

举个例子会很有帮助 @modesitt 你能举一个完整的例子吗?我需要使用带有词嵌入的附加功能。我的附加功能存储在input.csv 文件中,它有 3 列。

以上是关于如何在 Keras 中使用附加功能和词嵌入?的主要内容,如果未能解决你的问题,请参考以下文章

除了文档相似度的 Doc2Vec 嵌入之外,还可以使用哪些附加功能?

上下文嵌入和词嵌入有啥区别

如何在 keras LSTM 中使用自定义嵌入?

Keras:如何在损失函数中使用层的权重?

如何使用带有词嵌入的 Keras LSTM 来预测词 id

如何在 Keras 中为循环神经网络 (RNN) 使用嵌入层