只训练一些词嵌入(Keras)
Train only some word embeddings (Keras)
在我的模型中,我使用 GloVe 预训练嵌入。我希望让它们不可训练,以减少模型参数的数量并避免过度拟合。但是,我有一个特殊符号,我 想要训练其嵌入。
使用提供的嵌入层,我只能使用参数'trainable'设置所有嵌入的可训练性,方法如下:
embedding_layer = Embedding(voc_size,
emb_dim,
weights=[embedding_matrix],
input_length=MAX_LEN,
trainable=False)
是否有 Keras 级别的解决方案来仅训练嵌入的子集?
请注意:
- 没有足够的数据为所有词生成新的嵌入。
- These 答案仅与原生 TensorFlow 有关。
我还没有找到像嵌入层掩码这样好的解决方案。但这是我一直想尝试的:
- 两个嵌入层 - 一个可训练,一个不可训练
- non-trainable 一个具有 in-vocab 个词的所有 Glove 嵌入和其他词的零向量
- 可训练的只映射 OOV 词和特殊符号
- 这两层的输出相加(我是想这个像ResNet的)
- embedding下面的Conv/LSTM/etc不变
这将为您提供一个为这些嵌入分配少量自由参数的解决方案。
找到一些很好的解决方法,灵感来自 Keith 的两个嵌入层。
主要思想:
分配具有最高 ID 的特殊标记(和 OOV)。生成仅包含特殊标记的 'sentence',其他地方用 0 填充。然后将 non-trainable 嵌入应用于 'normal' 句子,并将可训练嵌入应用于特殊标记。最后,添加两者。
对我来说很好。
# 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])
在我的模型中,我使用 GloVe 预训练嵌入。我希望让它们不可训练,以减少模型参数的数量并避免过度拟合。但是,我有一个特殊符号,我 想要训练其嵌入。
使用提供的嵌入层,我只能使用参数'trainable'设置所有嵌入的可训练性,方法如下:
embedding_layer = Embedding(voc_size,
emb_dim,
weights=[embedding_matrix],
input_length=MAX_LEN,
trainable=False)
是否有 Keras 级别的解决方案来仅训练嵌入的子集?
请注意:
- 没有足够的数据为所有词生成新的嵌入。
- These 答案仅与原生 TensorFlow 有关。
我还没有找到像嵌入层掩码这样好的解决方案。但这是我一直想尝试的:
- 两个嵌入层 - 一个可训练,一个不可训练
- non-trainable 一个具有 in-vocab 个词的所有 Glove 嵌入和其他词的零向量
- 可训练的只映射 OOV 词和特殊符号
- 这两层的输出相加(我是想这个像ResNet的)
- embedding下面的Conv/LSTM/etc不变
这将为您提供一个为这些嵌入分配少量自由参数的解决方案。
找到一些很好的解决方法,灵感来自 Keith 的两个嵌入层。
主要思想:
分配具有最高 ID 的特殊标记(和 OOV)。生成仅包含特殊标记的 'sentence',其他地方用 0 填充。然后将 non-trainable 嵌入应用于 'normal' 句子,并将可训练嵌入应用于特殊标记。最后,添加两者。
对我来说很好。
# 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])