如何在 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'])
此模型运行成功,但我也想输入“年龄”和“性别”变量作为特征。代码中还需要哪些更改才能使用这些功能?
【问题讨论】:
您能告诉我您是如何输入包含Age
和Gender
的文件的吗?
【参考方案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 张量。
【讨论】:
agei
是age
和gender
的输入,对吧?如果是这样,我如何使用包含年龄和性别信息的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 中使用附加功能和词嵌入?的主要内容,如果未能解决你的问题,请参考以下文章