You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keras模型中替换Embedding层并保留其余架构与权重

问题背景

我用Gensim的Word2Vec库搭建了一个针对推特数据的情感分析Keras序列神经网络。先在大规模推特文本语料上训练Word2Vec生成嵌入词典,再把它用到Keras的Embedding层里,整个流程能正常运行。

为了在随机数据集上多次运行模型以获得更鲁棒的结果,我想在其他数据上预训练模型,保存模型的架构和权重,但要适配新数据集重新构建Embedding层。

核心问题

如何加载带有架构与权重的预训练Keras模型,并用新数据集生成的新Embedding层/嵌入矩阵替换原有层?


原模型构建代码

from tensorflow import keras
from keras.preprocessing.text import Tokenizer
from keras.utils import pad_sequences
from keras.models import Sequential
from keras import layers

maxlen= 100
EMBEDDING_DIM = 100
embedding_layer = layers.Embedding(len(word_index) + 1,
                                EMBEDDING_DIM,
                                weights=[embedding_matrix],
                                input_length=maxlen,
                                trainable=True)
model = Sequential()
model.add(embedding_layer)
model.add(layers.Flatten())
model.add(layers.Dense(10, activation='relu'))
model.add(layers.Dense(3, activation='softmax'))
model.compile(optimizer='adam',
                  loss='categorical_crossentropy',
              metrics=['accuracy'])

尝试的加载方式(出现问题)

pretrained_model = keras.models.load_model("my_model")
weights = pretrained_model.get_weights()
model.set_weights(weights)

运行后遇到各层权重数量不匹配的问题,尽管两个模型构建方式一致,仅Embedding层存在差异,且词汇表大小一致,不确定是模型保存加载函数导致的不匹配,还是Word2Vec嵌入词典的问题。

嵌入矩阵构建代码

model = Word2Vec(sentences=texts, max_final_vocab=1000)

tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts(df.iloc[:,7])
tokenized = tokenizer.texts_to_sequences(df.iloc[:,7])
word_index = tokenizer.word_index

EMBEDDING_DIM = 100
embedding_matrix = np.zeros((len(word_index) + 1, EMBEDDING_DIM))
for word, i in word_index.items():
  embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
      embedding_matrix[i] = embedding_vector

解决方案

问题出在直接用set_weights()会替换所有层的权重,而新模型的Embedding层参数维度(或映射逻辑)和预训练模型不匹配。正确做法是仅替换除Embedding层外的其他层权重,步骤如下:

  1. 加载预训练模型
pretrained_model = keras.models.load_model("my_model")
  1. 构建适配新数据集的新模型
    按照原模型结构,用新数据集生成的word_index和embedding_matrix创建新的Embedding层,搭建完整模型(和原模型结构一致,仅Embedding层参数不同)。

  2. 提取预训练模型中除Embedding层外的权重
    预训练模型的层顺序是:Embedding → Flatten → Dense(10) → Dense(3),跳过第0层(Embedding层)提取后续层的权重:

# 提取预训练模型中第1层及之后的权重
non_embedding_weights = pretrained_model.get_weights()[1:]
  1. 将权重设置到新模型对应层
    新模型结构和预训练模型一致,同样跳过第0层,设置权重:
# 给新模型的第1层及之后设置预训练权重
new_model.set_weights(non_embedding_weights)
  1. 验证与编译
    确认权重设置成功后,重新编译模型(可沿用原配置或按需调整):
new_model.compile(optimizer='adam',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

额外注意事项

  • 确保新模型和预训练模型的非Embedding层结构完全一致:比如Dense层的神经元数量、激活函数,Flatten层的位置等,否则权重维度仍会不匹配。
  • 若新数据集词汇表大小和预训练时不同,Embedding层输入维度变化,必须只替换后续层权重,不能全量替换。
  • 若想让Embedding层在新数据上继续训练,保持trainable=True;若要固定嵌入向量,设置trainable=False。

内容的提问来源于stack exchange,提问作者Klara Lundgren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:26