roberta_zh icon indicating copy to clipboard operation
roberta_zh copied to clipboard

关于MLM中,中文全词掩盖的预测标签问题

Open Rango94 opened this issue 5 years ago • 7 comments

我注意到在脚本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阶段却不会做分词处理,这在中文中合理吗?

Rango94 avatar Dec 21 '20 15:12 Rango94

我注意到在脚本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函数 )进行掩码预测,效果很差,这合理么?是一个新人,在自己慢慢摸索这些库。

pikapikapikaka avatar Dec 25 '20 09:12 pikapikapikaka

咨询量一下哈工大,他们将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]))

nathinal avatar Jan 28 '21 14:01 nathinal

咨询量一下哈工大,他们将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中的情况。

bigheary avatar Mar 09 '21 08:03 bigheary

咨询量一下哈工大,他们将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也可以使用。

nathinal avatar Mar 09 '21 09:03 nathinal

咨询量一下哈工大,他们将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 avatar Mar 09 '21 12:03 bigheary

你好,请问有更新的进展吗。我最近也对这个地方比较好奇,为什么需要手动去掉##呢?这样不是把一些词的位置信息取消了吗(如 bigheary所举的例子 “中国”和“其中”)

PeihanDou avatar Dec 08 '21 07:12 PeihanDou

谢谢合作! 

nathinal avatar Dec 08 '21 07:12 nathinal