只训练一些单词嵌入(Keras)

时间:2018-02-27 13:02:47

标签: python nlp keras word-embedding

在我的模型中,我使用GloVe预训练嵌入。我希望保持它们不可训练,以减少模型参数的数量并避免过度拟合。但是,我有一个特殊的符号,其嵌入我想要训练。

使用提供的嵌入层,我只能使用参数'trainable'以下列方式设置所有嵌入的可训练性:

embedding_layer = Embedding(voc_size,
                        emb_dim,
                        weights=[embedding_matrix],
                        input_length=MAX_LEN,
                        trainable=False)

是否有Keras级解决方案仅培训嵌入的子集?

请注意:

  1. 没有足够的数据为所有单词生成新的嵌入。
  2. These答案仅与原生TensorFlow相关。

2 个答案:

答案 0 :(得分:8)

找到了一些很好的解决方法,灵感来自Keith的两个嵌入层。

主要想法:

分配具有最高ID的特殊标记(和OOV)。生成一个只包含特殊标记的“句子”,在其他地方填充0。然后将不可训练的嵌入应用于“正常”句子,并将可训练嵌入应用于特殊标记。最后,添加两者。

对我来说很好。

    # Normal embs - '+2' for empty token and OOV token
    embedding_matrix = np.zeros((vocab_len + 2, emb_dim))
    # Special embs
    special_embedding_matrix = np.zeros((special_tokens_len + 2, emb_dim))

    # Here we may apply pre-trained embeddings to embedding_matrix

    embedding_layer = Embedding(vocab_len + 2,
                        emb_dim,
                        mask_zero = True,
                        weights = [embedding_matrix],
                        input_length = MAX_SENT_LEN,
                        trainable = False)

    special_embedding_layer = Embedding(special_tokens_len + 2,
                            emb_dim,
                            mask_zero = True,
                            weights = [special_embedding_matrix],
                            input_length = MAX_SENT_LEN,
                            trainable = True)

    valid_words = vocab_len - special_tokens_len

    sentence_input = Input(shape=(MAX_SENT_LEN,), dtype='int32')

    # Create a vector of special tokens, e.g: [0,0,1,0,3,0,0]
    special_tokens_input = Lambda(lambda x: x - valid_words)(sentence_input)
    special_tokens_input = Activation('relu')(special_tokens_input)

    # Apply both 'normal' embeddings and special token embeddings
    embedded_sequences = embedding_layer(sentence_input)
    embedded_special = special_embedding_layer(special_tokens_input)

    # Add the matrices
    embedded_sequences = Add()([embedded_sequences, embedded_special])

答案 1 :(得分:5)

我还没有找到一个很好的解决方案,就像嵌入层的掩码一样。但这就是我尝试的意思:

  • 两个嵌入层 - 一个可训练,一个不
  • 不可训练的人员拥有所有Glove嵌入词汇词汇和其他人的零载体
  • 可训练的只映射OOV字和特殊符号
  • 添加了这两个图层的输出(我想这就像ResNet一样)
  • 嵌入下方的Conv / LSTM /等未更改

这将为您提供一个解决方案,将少量免费参数分配给这些嵌入。