【问题标题】:Embedding vs inserting word vectors directly to input layer嵌入与直接将词向量插入输入层
【发布时间】:2019-05-19 02:39:17
【问题描述】:

我使用 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嵌入层的情况下直接使用词向量有什么缺点吗?

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

【问题讨论】:

    标签: keras deep-learning nlp gensim word2vec


    【解决方案1】:

    有一种优雅的方式可以满足您的需求。

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

    1. 输入的大小很大:(batch_size, MAX_SEQUENCE_LENGTH, dim),可能无法放入内存。
    2. 您将无法根据任务训练和更新词向量

    您可以只使用:(batch_size, MAX_SEQUENCE_LENGTH)。 keras 嵌入层允许您传入一个单词索引并获取一个向量。所以,42 -> Embedding Layer -> [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)
    

    现在您可以使用X_train,它会像:[[23, 34, 0, 0], [21, 63, 0, 0]] Embedding Layer 会自动将索引映射到该向量,并在需要时对其进行训练。

    我认为这是最好的方法,但我会深入研究 gensim 希望如何完成并在需要时更新这篇文章。

    【讨论】:

    • 也许@gojomo 可以评论
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-09-29
      • 2011-05-09
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 2017-08-01
      • 2020-08-19
      • 2019-10-01
      相关资源
      最近更新 更多