我想得到基于变压器的模型的句子嵌入(伯特,Roberta,Albert,Electra.)
我计划这样做,这意味着在第二层的隐藏状态上进行池化,就像bert as service所做的那样。
因此,我的问题是,当我指的是池时,应该包括与焊盘令牌、日志服务令牌或9个月令牌相关的嵌入吗?
例如,我的序列是300个令牌,并被填充到512个令牌中。
输出大小为512 (令牌)* 768 (嵌入)。
那么,我应该平均前300个令牌的嵌入量还是整个512个令牌的嵌入量?
为什么最后212个令牌的嵌入不是零?
发布于 2022-01-19 05:02:45
问题1.您决定如何将填充池层添加到behave.This中,这就是为什么py火炬的avg池(例如,nn.AvgPool2d)有一个可选的参数count_include_pad=True:默认情况下(True) Avg池将首先填充输入,然后对所有元素进行相同的处理。另一方面,如果设置count_include_pad=False,池层将忽略填充元素和结果
当你有太多的填充标记,他们参加梯度计算作为训练的一部分和权重更新,他们获得了一些权重。显然,这些权重的计算是浪费时间的,应该避免。
建议1:确保每个表都有相似的大小句子,以避免大量填充栏。
发布于 2022-09-15 18:30:51
通常,填充被排除在平均池之外。
一种通过平均池导出句子嵌入的方法,排除填充标记,可以从句子变压器中提取。在他们的池源代码中,您可以看到他们使用注意掩码来排除填充标记。下面是他们使用Huggingface (取自这里)所做工作的简化实现:
from transformers import AutoTokenizer, AutoModelForMaskedLM
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0] #First element of model_output contains all token embeddings
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
sum_embeddings = torch.sum(token_embeddings * input_mask_expanded, 1)
sum_mask = torch.clamp(input_mask_expanded.sum(1), min=1e-9)
return sum_embeddings / sum_mask
tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base")
model = AutoModelForMaskedLM.from_pretrained("xlm-roberta-base")
encoded_input = tokenizer("hello", return_tensors='pt')
model_output = model(**encoded_input)
mean_pooling(model_output, encoded_input['attention_mask'])由于input_mask_expanded是PAD令牌的0,因此在计算sum_embeddings = torch.sum(token_embeddings * input_mask_expanded, 1)时,结果的平均值不包括这些令牌。本文讨论了SBERT存储库上的这里的一个具体示例。
https://datascience.stackexchange.com/questions/107212
复制相似问题