我正在尝试实现Keras中this paper中描述的字符级嵌入类型。字符嵌入是使用双向LSTM计算的。
为了重新创建这个,我首先创建了一个矩阵,为每个单词包含构成单词的字符的索引:
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任务。
答案 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,然后再查看"反向工程师"它的工作方式来回答你的问题。通常情况下,以正确的方式格式化数据,其中工作示例模型可以创建奇迹,因为您可以仔细研究其使用的数据格式。