Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Rango94 opened this issue Dec 21, 2020 · 7 comments
Open

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

Rango94 opened this issue Dec 21, 2020 · 7 comments

Comments

@Rango94
Copy link

Rango94 commented Dec 21, 2020

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

@pikapikapikaka
Copy link

pikapikapikaka commented Dec 25, 2020

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

@nathinal
Copy link

nathinal commented Jan 28, 2021

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

@bigheary
Copy link

bigheary commented Mar 9, 2021

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

@nathinal
Copy link

nathinal commented Mar 9, 2021

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

@bigheary
Copy link

bigheary commented Mar 9, 2021

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

@PeihanDou
Copy link

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

@nathinal
Copy link

nathinal commented Dec 8, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants