与Keras的字符嵌入

时间:2018-01-15 08:31:45

标签: python nlp keras lstm word-embedding

我正在尝试实现Keras中this paper中描述的字符级嵌入类型。字符嵌入是使用双向LSTM计算的。

enter image description here

为了重新创建这个,我首先创建了一个矩阵,为每个单词包含构成单词的字符的索引:

char2ind = {char: index for index, char in enumerate(chars)}
max_word_len = max([len(word) for sentence in sentences for word in sentence])
X_char = []
for sentence in X:
    for word in sentence:
        word_chars = []
        for character in word:
            word_chars.append(char2ind[character])

        X_char.append(word_chars)
X_char = sequence.pad_sequences(X_char, maxlen = max_word_len)

然后我定义了一个BiLSTM模型,其中包含字符矩阵的嵌入层。我假设input_dimension必须等于字符数。我希望我的字符嵌入大小为64,所以我将BiLSTM的隐藏大小设置为32:

char_lstm = Sequential()
char_lstm.add(Embedding(len(char2ind) + 1, 64))    
char_lstm.add(Bidirectional(LSTM(hidden_size, return_sequences=True)))

这就是我感到困惑的地方。如何从模型中检索嵌入?我猜我必须编译模型并使其适合然后检索权重以获得嵌入,但我应该使用哪些参数来适应它?

其他详情:

这是针对NER任务的,因此技术上数据集可以是单词 - 标签格式的任何内容,尽管我特别使用此处提供的WikiGold ConLL语料库:https://github.com/pritishuplavikar/Resume-NER/blob/master/wikigold.conll.txt 网络的预期输出是标签(I-MISC,O,I-PER ......)

我希望数据集足够大,可以直接从中训练字符嵌入。所有单词都用其构成字符的索引编码,字母大小约为200个字符。单词被填充/剪切为20个字符。数据集中有大约30 000个不同的单词。

我希望能够根据不同单词的信息为每个角色学习嵌入。然后,就像在论文中一样,我将字符嵌入与单词的手套嵌入连接起来,然后进入具有最终CRF层的Bi-LSTM网络。

我还希望能够保存嵌入,以便我可以将它们重用于其他类似的NLP任务。

1 个答案:

答案 0 :(得分:1)

一般而言,Keras建立模型的方法(即使看似复杂的模型)也很简单。例如,您想要构建的模型类似于(注意这是针对二进制分类问题):

model = Sequential()
model.add(Embedding(max_features, out_dims, input_length=maxlen))
model.add(Bidirectional(LSTM(32)))
model.add(Dropout(0.1))
model.add(Dense(1, activation='sigmoid'))
model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])

这与普通的香草NN没有什么不同,除了将嵌入和双向层置于密集层之外。这是令Keras惊艳的事情之一。

通常,查找一个与您尝试的工作大致相同的工作示例(Keras有负载)会很有帮助。在这种情况下,您可以先查看this model,然后再查看"反向工程师"它的工作方式来回答你的问题。通常情况下,以正确的方式格式化数据,其中工作示例模型可以创建奇迹,因为您可以仔细研究其使用的数据格式。