cheniison / e2e-coref-pytorch

Bert for End-to-end Neural Coreference Resolution in Pytorch
24 stars 8 forks source link

英文效果不好 #6

Closed unikcc closed 3 years ago

unikcc commented 3 years ago

大佬你好,先赞一下代码,比原版tf看起来舒适多了👍。 然后我跑了你的代码,中文完美复现,2万步F1到0.64; 英文的话,只改了下文件路径和Bert模型位置,别的没改,直接用效果就很差,从4万步开始,一直快到6万步,F1最好效果还是只有0.55; 我看你在别的问题下回答可以改下数据处理部分,方便说下具体(可能)改哪些会部分的代码有用吗?谢谢!

cheniison commented 3 years ago

感谢提出问题。

数据预处理代码需要改的地方大概是按 section 读入文本的部分(即 section_to_example 函数中 tokenize 及其之前的部分),中文和英文在这部分解析时差距很大。另外,分割 section 部分(即 onf_to_section 函数)可能也需要适当修改。

如果觉得本项目的代码修改起来比较困难的话,可以直接写一个简单的转换代码,将 bert-coref 项目里的数据文件转换过来,其项目中的数据文件(*.jsonlines)格式和本项目的非常相似,其格式见 bert-coref 样本。但需要去掉 sentences 中的 [CLS] 和 [SEP],并对应地做出如下修改:(1)去掉 speakers 中的 [SPL] ,并改变属性名字为 speaker_ids(2)去掉 sentence_map 中的对应位置(3)去掉 subtoken_map 中的对应位置(4)clusters 中的指代位置需要根据去掉的 [CLS] 和 [SEP] 做修改。

欢迎编码出适合解析英文的预处理代码并且提pull requests。

unikcc commented 3 years ago

好的,好的,感谢大佬如此详细地解答! 我仔细看了预处理的代码,恕我眼拙,处理英文也没找出啥问题。找了几个例子,指代的内容跟原文也是能对应上的。 我还是先尝试一下转换的方法吧,看效果如何,虽然那个代码不优雅,谢谢👀

BugMaker-99 commented 3 years ago

大佬你好,先赞一下代码,比原版tf看起来舒适多了👍。 然后我跑了你的代码,中文完美复现,2万步F1到0.64; 英文的话,只改了下文件路径和Bert模型位置,别的没改,直接用效果就很差,从4万步开始,一直快到6万步,F1最好效果还是只有0.55; 我看你在别的问题下回答可以改下数据处理部分,方便说下具体(可能)改哪些会部分的代码有用吗?谢谢!

可以简单说一下代码改了哪些部分吗,我按照transformer和pytorch的版本安装了环境,用onf_to_data.py生成了3个json,跑起来挺正常,就是准确率和召回率以及f1分数都是0

BugMaker-99 commented 3 years ago

大哥不好意思,我又来问问题了。是这样的,loss很快就降成了0。可train的时候进行每隔c["eval_frequency"]次进行evaluate,返回的p、r、f都是0,这就很奇怪了。 于是我打印了一些中间变量

在model.py中 def evaluate(self, data, transformer_model)里面的predicted_clusters=[](空列表)

def get_predicted_antecedents(self, top_antecedents_index, top_antecedents_score)里面的predicted_antecedents=[-1,-1,-1,-1,......](全是-1的列表)

其中在get_predicted_antecedents这个函数里,if index == len(top_antecedents_score[i]) - 1一直都成立,也就导致一直执行predicted_antecedents.append(-1)

def get_predicted_clusters(self, top_m_spans, predicted_antecedents)里面的predicted_index=-1,len(idx_to_clusters[i]) =1,predicted_clusters是空列表

大佬可以解答一下吗?谢谢您啦!

unikcc commented 3 years ago

可以简单说一下代码改了哪些部分吗,我按照transformer和pytorch的版本安装了环境,用onf_to_data.py生成了3个json,跑起来挺正常,就是准确率和召回率以及f1分数都是0

中文的话开箱即用,几乎啥都没改啊。 sentences_embed= transformer_model(sentences_ids.to(device=torch.device(self.config["device"])), sentences_masks.to(device=torch.device(self.config["device"])))[0] 我用的最新的transformers,就改了这一行,只要能跑起来效果应该就不会差。

BugMaker-99 commented 3 years ago

可以简单说一下代码改了哪些部分吗,我按照transformer和pytorch的版本安装了环境,用onf_to_data.py生成了3个json,跑起来挺正常,就是准确率和召回率以及f1分数都是0

中文的话开箱即用,几乎啥都没改啊。 sentences_embed= transformer_model(sentences_ids.to(device=torch.device(self.config["device"])), sentences_masks.to(device=torch.device(self.config["device"])))[0] 我用的最新的transformers,就改了这一行,只要能跑起来效果应该就不会差。

大佬有裁剪数据集嘛?如果直接用作者的3个list生成json作为输入,我用colab直接提示内存不够

unikcc commented 3 years ago

大佬有裁剪数据集嘛?如果直接用作者的3个list生成json作为输入,我用colab直接提示内存不够 没有剪裁,直接设的原始长度512,内存还够用。剪裁一下也没关系吧,预处理那里应该可以自适应

BugMaker-99 commented 3 years ago

ok,非常感谢大佬

cheniison commented 3 years ago

大哥不好意思,我又来问问题了。是这样的,loss很快就降成了0。可train的时候进行每隔c["eval_frequency"]次进行evaluate,返回的p、r、f都是0,这就很奇怪了。 于是我打印了一些中间变量

在model.py中 def evaluate(self, data, transformer_model)里面的predicted_clusters=[](空列表)

def get_predicted_antecedents(self, top_antecedents_index, top_antecedents_score)里面的predicted_antecedents=[-1,-1,-1,-1,......](全是-1的列表)

其中在get_predicted_antecedents这个函数里,if index == len(top_antecedents_score[i]) - 1一直都成立,也就导致一直执行predicted_antecedents.append(-1)

def get_predicted_clusters(self, top_m_spans, predicted_antecedents)里面的predicted_index=-1,len(idx_to_clusters[i]) =1,predicted_clusters是空列表

大佬可以解答一下吗?谢谢您啦!

出现 loss=0 并且不输出指代(即predicted_antecedents全为-1)有可能是因为训练数据较少,模型容易过拟合,从而预测出那些无指代的span。在这种情况下,可以查看 top_m_spans 相关变量,会发现这些 span 都并不是 gold mentions。 原tensorflow版本的模型(bert-coref)也会出现这种情况,这是因为其损失函数中没有显式考虑 “span是否是mention” 。若想避免该问题的出现,可以显式加入 mention detection 损失。具体设定和参数详见论文 Neural Coreference Resolution with Deep Biaffine Attention by Joint Mention Detection and Mention Clustering

BugMaker-99 commented 3 years ago

大哥不好意思,我又来问问题了。是这样的,loss很快就降成了0。可train的时候进行每隔c["eval_frequency"]次进行evaluate,返回的p、r、f都是0,这就很奇怪了。 于是我打印了一些中间变量 在model.py中 def evaluate(self, data, transformer_model)里面的predicted_clusters=[](空列表) def get_predicted_antecedents(self, top_antecedents_index, top_antecedents_score)里面的predicted_antecedents=[-1,-1,-1,-1,......](全是-1的列表) 其中在get_predicted_antecedents这个函数里,if index == len(top_antecedents_score[i]) - 1一直都成立,也就导致一直执行predicted_antecedents.append(-1) def get_predicted_clusters(self, top_m_spans, predicted_antecedents)里面的predicted_index=-1,len(idx_to_clusters[i]) =1,predicted_clusters是空列表 大佬可以解答一下吗?谢谢您啦!

出现 loss=0 并且不输出指代(即predicted_antecedents全为-1)有可能是因为训练数据较少,模型容易过拟合,从而预测出那些无指代的span。在这种情况下,可以查看 top_m_spans 相关变量,会发现这些 span 都并不是 gold mentions。 原tensorflow版本的模型(bert-coref)也会出现这种情况,这是因为其损失函数中没有显式考虑 “span是否是mention” 。若想避免该问题的出现,可以显式加入 mention detection 损失。具体设定和参数详见论文 Neural Coreference Resolution with Deep Biaffine Attention by Joint Mention Detection and Mention Clustering

好的好的,确实是数据太少了,感谢

BugMaker-99 commented 3 years ago

没有剪裁,直接设的原始长度512,内存还够用。剪裁一下也没关系吧,预处理那里应该可以自适应

我剪裁过数据,每个list里面都只有100~300个onf文件,用colab pro依然是内存不够。想问一下大佬你用什么跑的呀?

BugMaker-99 commented 3 years ago

没有剪裁,直接设的原始长度512,内存还够用。剪裁一下也没关系吧,预处理那里应该可以自适应

tcmalloc: large alloc 1913225216 bytes == 0x558a9aa60000

服务器说要900多G内存

cheniison commented 3 years ago

没有剪裁,直接设的原始长度512,内存还够用。剪裁一下也没关系吧,预处理那里应该可以自适应

我剪裁过数据,每个list里面都只有100~300个onf文件,用colab pro依然是内存不够。想问一下大佬你用什么跑的呀?

使用的空间和onf文件的数量关系不大,训练时模型每次只处理一个样本。与使用内存有较大关系的要素是:(1)每个样本里文本的长度;(2)config 中的 max_span_width;(3)config 中的 max_training_sentences。 可以尝试调小以上的配置。不过 900G 确实有点夸张了

BugMaker-99 commented 3 years ago

没有剪裁,直接设的原始长度512,内存还够用。剪裁一下也没关系吧,预处理那里应该可以自适应

我剪裁过数据,每个list里面都只有100~300个onf文件,用colab pro依然是内存不够。想问一下大佬你用什么跑的呀?

使用的空间和onf文件的数量关系不大,训练时模型每次只处理一个样本。与使用内存有较大关系的要素是:(1)每个样本里文本的长度;(2)config 中的 max_span_width;(3)config 中的 max_training_sentences。 可以尝试调小以上的配置。不过 900G 确实有点夸张了

嗯嗯,我真的是小白临时跑个项目,打扰大佬这么长时间,再次感谢您!!!