如何使用Roberta计算最后4个隐藏层的加权和以获取词嵌入?
RoBERTa最后4层隐藏层加权和获取Token Embedding的代码验证
首先,你这段代码的核心逻辑是正确的——它确实提取了RoBERTa最后4个隐藏层,并计算了它们的等权重加权和(直接求和等价于每个层权重为1的加权和)。不过有几个细节可以优化,同时需要明确论文方法的对应关系:
代码细节说明
- 隐藏层提取:
output.hidden_states返回包含所有隐藏层的列表,第0层是embedding层,最后一层是模型最终输出层。你用[-4, -3, -2, -1]提取倒数4层的方式是对的。 - 堆叠与求和:
torch.stack([states[i] for i in [-4, -3, -2, -1]])把4个形状为[batch_size, seq_len, hidden_size]的张量堆叠成[4, batch_size, seq_len, hidden_size],再通过.sum(0)对层维度求和,得到每个token的等权重加权和embedding,这一步逻辑没问题。 .squeeze()的注意事项:如果batch_size为1,.squeeze()会去掉batch维度;但如果batch_size大于1(比如示例中的2),.squeeze()不会改变形状,因为没有维度为1的轴。如果需要统一处理,可根据需求决定是否保留batch维度,或用token_emb = token_emb.squeeze(0)仅在batch_size=1时去掉该维度。
与论文方法的对应
你参考的论文表格里的方法(比如最后N层拼接/加权和)完全适用于RoBERTa,因为RoBERTa是BERT的改进版,隐藏层输出结构和BERT一致。如果要实现带可学习权重的加权和(而非等权重),可以加入可学习参数,示例如下:
from transformers import RobertaTokenizer, RobertaModel import torch import torch.nn as nn tokenizer = RobertaTokenizer.from_pretrained('roberta-base') model = RobertaModel.from_pretrained('roberta-base') caption = ['this is a yellow bird', 'example caption'] tokens = tokenizer(caption, return_tensors='pt', padding=True) input_ids = tokens['input_ids'] attention_mask = tokens['attention_mask'] output = model(input_ids, attention_mask, output_hidden_states=True) states = output.hidden_states # 定义可学习权重参数,初始化为均匀分布 layer_weights = nn.Parameter(torch.ones(4) / 4) # 提取最后4层并加权求和 last_four_layers = torch.stack([states[i] for i in [-4, -3, -2, -1]]) token_emb = torch.einsum('l,lbsh->bsh', layer_weights, last_four_layers)
额外注意事项
- 若需要句子级embedding,通常会在token_emb基础上结合
</s>(RoBERTa的句末token)的embedding,或对有效token做平均/池化;你的代码是获取token级embedding,逻辑匹配需求。 - 训练时如果使用可学习权重,要将这些参数加入优化器的参数列表中。
内容的提问来源于stack exchange,提问作者user23232264
相关产品推荐
相关产品推荐

