Keras 嵌入与直接向输入层插入词向量

Keras 嵌入与直接向输入层插入词向量,keras,deep-learning,nlp,gensim,word2vec,Keras,Deep Learning,Nlp,Gensim,Word2vec,我使用gensim构建了一个word2vec嵌入我的语料库。 目前,我正在使用gensim模型将我的(填充的)输入句子转换为单词向量。 该向量用作模型的输入 model = Sequential() model.add(Masking(mask_value=0.0, input_shape=(MAX_SEQUENCE_LENGTH, dim))) model.add(Bidirectional( LSTM(num_lstm, dropout=0.5, recurrent_dropout=

我使用gensim构建了一个word2vec嵌入我的语料库。 目前,我正在使用gensim模型将我的(填充的)输入句子转换为单词向量。 该向量用作模型的输入

model = Sequential()
model.add(Masking(mask_value=0.0, input_shape=(MAX_SEQUENCE_LENGTH, dim)))
model.add(Bidirectional(
    LSTM(num_lstm, dropout=0.5, recurrent_dropout=0.4, return_sequences=True))
)
...
model.fit(training_sentences_vectors, training_labels, validation_data=validation_data)
在没有keras嵌入层的情况下直接使用单词向量有什么缺点吗


目前,我还通过将输入标记连接到每个词向量来向输入标记添加额外的(一个热编码)标记,这种方法有意义吗?

在当前设置中,缺点是无法将词向量设置为可训练的。您将无法为任务微调模型


我的意思是,Gensim只学会了“语言模型”。它了解您的语料库及其内容。然而,它不知道如何为您正在使用keras的任何下游任务进行优化。您的模型权重将有助于微调您的模型,但是,如果您从gensim提取嵌入,使用它们初始化keras嵌入层,然后为输入层传入索引而不是字向量,您可能会体验到性能的提高

有一种优雅的方式来满足你的需求

您的解决方案的问题在于:

  • 输入的大小很大:
    (批大小、最大序列长度、dim)
    ,可能无法放入内存
  • 您将无法根据任务训练和更新单词向量
  • 相反,您只需:
    (批大小、最大序列长度)
    。keras嵌入层允许您传入单词索引并获取向量。所以,
    42->嵌入层->[3,5.2,…,33]

    方便的是,gensim的w2v模型有一个函数
    get_keras_embedding
    ,该函数使用经过训练的权重为您创建所需的嵌入层

    gensim_model = # train it or load it
    embedding_layer = gensim_model.wv.get_keras_embedding(train_embeddings=True)
    embedding_layer.mask_zero = True  # No need for a masking layer
    
    model = Sequential()
    model.add(embedding_layer) # your embedding layer
    model.add(Bidirectional(
        LSTM(num_lstm, dropout=0.5, recurrent_dropout=0.4, return_sequences=True))
    )
    
    但是,您必须确保数据中单词的索引与word2vec模型的索引相同

    word2index = {}
    for index, word in enumerate(model.wv.index2word):
        word2index[word] = index
    
    使用上述
    word2index
    字典将输入数据转换为与gensim型号相同的索引

    例如,您的数据可能是:

    X_train = [["hello", "there"], ["General", "Kenobi"]]
    
    new_X_train = [] 
    for sent in X_train:
        temp_sent = []
        for word in sent:
            temp_sent.append(word2index[word])
        # Add the padding for each sentence. Here I am padding with 0
        temp_sent += [0] * (MAX_SEQUENCE_LENGTH - len(temp_sent))
        new_X_train.append(temp_sent)
    
    X_train = numpy.as_array(new_X_train)
    
    现在,您可以使用
    xu-train
    ,它将类似于:
    [[23,34,0,0],[21,63,0,0]]
    嵌入层将自动将索引映射到该向量,并在需要时对其进行训练


    我认为这是最好的方式,但我会深入了解gensim希望如何做到这一点,并在需要时更新此帖子。

    也许@gojomo可以发表评论