关于MLM中,中文全词掩盖的预测标签问题
我注意到在脚本create_pretraining_data.py中564行, masked_lms.append(MaskedLmInstance(index=index, label=tokens[index])) 这一行制作MLM预测标签时,label采用的是tokens[index],而tokens为了全词掩盖,在预处理阶段对部分字做了"##"处理,按照这一行的逻辑,全词掩盖后MLM的监督标签中,将有很大部分由带有前缀"##"的token组成。这种情况在英文中是可以理解的,因为在fine tune阶段英文词同样会做wordpiece处理,但中文在fine tune阶段却不会做分词处理,这在中文中合理吗?
我注意到在脚本create_pretraining_data.py中564行, masked_lms.append(MaskedLmInstance(index=index, label=tokens[index])) 这一行制作MLM预测标签时,label采用的是tokens[index],而tokens为了全词掩盖,在预处理阶段对部分字做了"##"处理,按照这一行的逻辑,全词掩盖后MLM的监督标签中,将有很大部分由带有前缀"##"的token组成。这种情况在英文中是可以理解的,因为在fine tune阶段英文词同样会做wordpiece处理,但中文在fine tune阶段却不会做分词处理,这在中文中合理吗?
您好 。 我加载了roberta模型 (通过transformer库的BertForMaskedLM函数 )进行掩码预测,效果很差,这合理么?是一个新人,在自己慢慢摸索这些库。
咨询量一下哈工大,他们将masked_lm_labels中文的##(前面分词时手动加上的)去掉了,我改成下面这种了:
# masked_lms.append(MaskedLmInstance(index=index, label=tokens[index]))
masked_lms.append(MaskedLmInstance(index=index,
label=tokens[index][2:] if len(
re.findall('##[\u4E00-\u9FA5]', tokens[index])) > 0 else tokens[
index]))
咨询量一下哈工大,他们将masked_lm_labels中文的##(前面分词时手动加上的)去掉了,我改成下面这种了:
# masked_lms.append(MaskedLmInstance(index=index, label=tokens[index])) masked_lms.append(MaskedLmInstance(index=index, label=tokens[index][2:] if len( re.findall('##[\u4E00-\u9FA5]', tokens[index])) > 0 else tokens[ index]))
我看现在master上的finetuning代码已经改成这样了。 但是从github上给的预训练好的模型RoBERTa_zh_L12来看,对应的vocab还是包含了“##”的版本,请问应该怎么处理呢?如果直接用的话用另外的预料作预训练会出现token不在vocab中的情况。
咨询量一下哈工大,他们将masked_lm_labels中文的##(前面分词时手动加上的)去掉了,我改成下面这种了:
# masked_lms.append(MaskedLmInstance(index=index, label=tokens[index])) masked_lms.append(MaskedLmInstance(index=index, label=tokens[index][2:] if len( re.findall('##[\u4E00-\u9FA5]', tokens[index])) > 0 else tokens[ index]))我看现在master上的finetuning代码已经改成这样了。 但是从github上给的预训练好的模型RoBERTa_zh_L12来看,对应的vocab还是包含了“##”的版本,请问应该怎么处理呢?如果直接用的话用另外的预料作预训练会出现token不在vocab中的情况。
个人感觉最后中文带“##中”和“中”两个字的embedding会被训练成一样,二者最终可能是差不多的,所以使用训练好的RoBERTa_zh_L12也可以使用。
咨询量一下哈工大,他们将masked_lm_labels中文的##(前面分词时手动加上的)去掉了,我改成下面这种了:
# masked_lms.append(MaskedLmInstance(index=index, label=tokens[index])) masked_lms.append(MaskedLmInstance(index=index, label=tokens[index][2:] if len( re.findall('##[\u4E00-\u9FA5]', tokens[index])) > 0 else tokens[ index]))我看现在master上的finetuning代码已经改成这样了。 但是从github上给的预训练好的模型RoBERTa_zh_L12来看,对应的vocab还是包含了“##”的版本,请问应该怎么处理呢?如果直接用的话用另外的预料作预训练会出现token不在vocab中的情况。
个人感觉最后中文带“##中”和“中”两个字的embedding会被训练成一样,二者最终可能是差不多的,所以使用训练好的RoBERTa_zh_L12也可以使用。
谢谢你的回答。可是我觉得还是有两个问题呀。 1)按照带“##”的方式,在vocab里面“##中”表示的是那些被jieba分词之后处于非开头的“中”字比如“其中”,“中”表示那些单独无法成词或者是分词之后第一个位置的那些词比如“中国”,“中间”。这两种分别占一个位置可能最终得到的向量有差别吧。 2)我看vocab里面也不是所有的元素都是带“##”与不带成对出现的,比如片段“nge”就没有单独的这个词,只有“##nge”, 说明这个词片没有在开头出现过。这样的话,如果分完词之后仍然去掉“##”程序会抛异常,相当于OOV了。
你好,请问有更新的进展吗。我最近也对这个地方比较好奇,为什么需要手动去掉##呢?这样不是把一些词的位置信息取消了吗(如 bigheary所举的例子 “中国”和“其中”)
谢谢合作!