Flair NLP训练输出与evaluate函数结果存在极端性能差异问题咨询
这种前后评估结果差得离谱的情况确实挺让人懵的,结合你用的是小规模数据集,我梳理了几个最可能的原因,你可以挨个排查:
可能的原因及排查方向
1. 两次评估用的根本不是同一个数据集
你第一次训练完输出的结果,大概率是训练过程中验证集的评估分数,而第二次调用evaluate用的是corpus.test测试集。在小规模数据集里,验证集和测试集的样本分布可能极端不均衡——比如验证集刚好攒了所有标注模糊、难识别的样本,测试集全是特征明显的简单样本,自然会出现一边分数极低、一边分数爆表的情况。
另外还要留意:如果你的代码加载语料时没设置固定的随机种子,两次运行时的训练/验证/测试集划分可能完全不同,这种“随机划分”在小数据集里会直接导致评估结果天差地别。
2. 加载的模型不是同一个
Flair训练NER模型时默认会存两个模型文件:
best-model.pt:在验证集上表现最好的那个epoch的模型final-model.pt:训练最后一个epoch的模型
你第一次训练完输出的结果,可能是best-model.pt在验证集的表现,而第二次加载的是final-model.pt去测测试集?或者反过来?比如训练后期模型过拟合了,final-model在验证集上拉胯,但best-model在测试集上表现极佳?你可以试试加载best-model.pt再跑一次评估,看看结果能不能对上第一次的分数。
3. 评估参数或数据集加载有差异
比如第一次训练时的评估用了默认的mini_batch_size(比如8或16),而你第二次特意设成了mini_batch_size=1——虽然这个差异一般不会这么夸张,但在小数据集下,不同batch size可能会影响模型推理(比如用到batch normalization的话)。
另外还要检查两次评估时的语料标签是否一致:比如第一次训练时的标签映射有没有被正确加载,第二次加载corpus时会不会出现标签遗漏、格式错误的情况。
4. 对评估指标的理解偏差
虽然Flair的NER评估默认是实体级别的F1分数,但有时候容易混淆token级别和实体级别的指标。你看两次结果里的tp(真正例)数量:第一次Symptom的tp只有46,第二次却有72,这说明两次评估的数据集里的实体总数差了一大截,进一步坐实了“两次用的不是同一个数据集”的可能性。
内容的提问来源于stack exchange,提问作者George

