bert处理超过512的长文本(强制改变位置编码position_embeddings )

最近在做 NER 任务的时候,需要处理最长为 1024 个字符的文本,BERT 模型最长的位置编码是 512 个字符,超过512的部分没有位置编码可以用了

处理措施:

  1. 将bert的位置编码认为修改成(1*1024),前512维使用原始的 (1*512)初始化,后512维随机初始化
  2. 将bert的位置编码认为修改成(1*1024),前512维使用原始的 (1*512)初始化,后512维依旧使用原始的(1*512)进行初始化
  3. 苏剑林:层次分解位置编码,让BERT可以处理超长文本 - 科学空间|Scientific Spaces
  4. 使用longformer
  5. 对文本进行切割

下面介绍如何强制改变位置编码

采用1,2所表述的方式,强制改变位置编码,由512 扩展到 1024,具需要在 modeling_bert.py 的 BertEmbeddings class中,新声明一个 (1*1024)的position_embedding,并且将forward 函数中的 position_embedding替换成新声明的这个位置编码。
在load 完模型之后,会警告说,新的位置编码并不在原始的模型参数中,所以是随机初始化的,这里注意,原始的位置编码还是要保留的,用于将原始的位置编码加载进来。当模型加载结束后,我们将原始的 位置编码和新的位置编码单独取出,并用原始的位置编码替换掉新位置编码的部分参数(前 512 维)。
1024 中后一半的位置编码同样使用 原始的 512 维进行初始化,这样就相当于将两个 512 的位置编码拼接到了一起。

用transformer库 具体操作

1,修改 /home/wws/miniconda3/envs/ner/lib/python3.7/site-packages/transformers/models/bert/modeling_bert.py (大概在 172行)
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)

在下面添加一个

self.position_embeddings_test = nn.Embedding(config.max_position_embeddings, config.hidden_size)

再把原来的position 修改一下

self.position_embeddings = nn.Embedding(config.max_position_embeddings//2, config.hidden_size)

区别在于第一个参数 //2
在这里插入图片描述

然后在 forward 函数里面 将原来的 position_embeddings 替换成 position_embeddings_test
在这里插入图片描述

训练的代码中,加载完模型参数后添加

add_position_embeddings = torch.tensor(model.bert.embeddings.position_embeddings_test.weight)
add_position_embeddings[:512] = torch.tensor(model.bert.embeddings.position_embeddings.weight)

如果后半部分也是用 原始的位置编码初始化那就吧下面的代码也加上

add_position_embeddings[512:] = torch.tensor(model.bert.embeddings.position_embeddings.weight)

最后将改好的位置编码放回去

model.bert.embeddings.position_embeddings_test.weight = nn.Parameter(add_position_embeddings)

在这里插入图片描述
但是运行时提示用sourceTensor.clone().detach() 或者sourceTensor.clone().detach().requires_grad_(True) 代替上面的torch.tensor(**)
在这里插入图片描述
现在position_embeddings 长度就可以使1024了
在这里插入图片描述
后面接nn.linear和crf就可以做ner了
在这里插入图片描述
PS:

BertConfig {
  "architectures": [
    "BertForMaskedLM"
  ],
  "attention_probs_dropout_prob": 0.1,
  "gradient_checkpointing": false,
  "hidden_act": "gelu",
  "hidden_dropout_prob": 0.1,
  "hidden_size": 1024,
  "id2label": {
    "0": "LABEL_0",
    "1": "LABEL_1",
    "2": "LABEL_2",
    "3": "LABEL_3",
    "4": "LABEL_4",
    "5": "LABEL_5",
    "6": "LABEL_6",
    "7": "LABEL_7",
    "8": "LABEL_8",
    "9": "LABEL_9",
    "10": "LABEL_10",
    "11": "LABEL_11",
    "12": "LABEL_12",
    "13": "LABEL_13",
    "14": "LABEL_14"
  },
  "initializer_range": 0.02,
  "intermediate_size": 4096,
  "label2id": {
    "LABEL_0": 0,
    "LABEL_1": 1,
    "LABEL_10": 10,
    "LABEL_11": 11,
    "LABEL_12": 12,
    "LABEL_13": 13,
    "LABEL_14": 14,
    "LABEL_2": 2,
    "LABEL_3": 3,
    "LABEL_4": 4,
    "LABEL_5": 5,
    "LABEL_6": 6,
    "LABEL_7": 7,
    "LABEL_8": 8,
    "LABEL_9": 9
  },
  "layer_norm_eps": 1e-12,
  "max_position_embeddings": 1024,
  "model_type": "bert",
  "num_attention_heads": 16,
  "num_hidden_layers": 24,
  "pad_token_id": 0,
  "position_embedding_type": "absolute",
  "transformers_version": "4.9.0",
  "type_vocab_size": 2,
  "use_cache": true,
  "vocab_size": 30522
}
  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值