题目
关于使用[MASK]做完形填空时需要注意的点
关键点
Q1: 选取谁做[MASK]
A:关于这个问题取决于语料库中的每句话的平均长度
比如我在glue【sst2】中就对整个语料库中的所有句子进行了筛选【单词长度大于10】,取中选了第5个单词,又因为第一个token是[cls]所以input_ids[:,5],其实是选择了第四个单词
Q2:如何实现[MASK]
A:因为bert中的编码是根据每一个单词进行编码的,所以我们只需要取到对应单词的encode编码并将它变为[MASK]
step1:先取出index位置的encode编码
labels = input_ids[:,index].reshape(-1).clone() # [batch_size]
这里解释一下为什么要用clone(),原因是单纯使用reshape会破坏input_ids的结构,它是创建了一个新的指向数据的指针,两者还是共享一份数据,所以clone的作用在于重新创建,开辟一块心得内存空间存储。
step2: 将对应的index位置变为[MASK]
input_ids[:,index] = tokenizer.get_vocab()[tokenizer.mask_token]
Q3: 为什么自己训练的模型loss不会下降
A:我一开始也遇到这个问题了,后来看了别人的经验是nn.Linear(bias=False),当对Linear函数里的偏置矩阵进行归0后,会发现loss开始下降。
- 另一个可能是因为BertModel比较难训练,当我该用AutoModelForMaskedLM时,模型很快就能收敛