首页 文章

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

提问于
浏览
7

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

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

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

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

请注意:

  • 没有足够的数据为所有单词生成新的嵌入 .

  • These答案仅与原生TensorFlow有关 .

2 回答

  • 4

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

    Main idea:

    分配具有最高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])
    
  • 7

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

    • 两个嵌入层 - 一个可训练,一个不可训练

    • 不可训练的人具有词汇词汇的所有Glove嵌入和其他人的零向量

    • 可训练的只能映射OOV字和特殊符号

    • 添加了这两个图层的输出(我想的就像ResNet一样)

    • 嵌入下面的Conv / LSTM / etc保持不变

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

相关问题