560. Benetech - Making Graphs Accessible | benetech-making-graphs-accessible
我希望你们觉得训练和推理代码整洁有序,我已经尽力不制造混乱!
以下是我们与 @cody11null 团队合作解决方案的简要说明。
我们的解决方案由对象检测器 (EfficientDet) 和图像编码器/文本解码器 (Matcha 和 Donut) 组成:
vertical_bar、horizontal_bar、line 和 dot),我们使用了 Matcha 模型
我们训练了不同的图像编码器/文本解码器架构来检测坐标轴标签。我训练了一个 Donut 模型(令人惊讶地获得了最佳结果)和另外两个 Matcha 模型,但表现较差。尽管使用不同的 max_patches 进行训练,所有模型的结果都相当相似。大多数复杂情况与坐标轴标签的共享原点、长序列、具有多位小数的浮点数等有关。在这一步中,最重要的是正确获取每个轴的最小值和最大值,以便正确进行交叉相乘。
这是我耗时最多的部分之一。在比赛初期,直到 Nicholas 分享了他的 Donut 模型之前,我不知道图像编码器/文本解码器模型能在比赛中表现如此出色,所以我专注于一个能够良好检测数据系列的对象检测器模型。为此,我缺乏边界框训练数据,于是开始手动标记数千张图像。这花费了我很多天时间。我的 EfficientDet 对象检测器在生成图像上表现极好,但在提取图像上表现不佳。我尽可能多地标记了图像。我的对象检测器在散点图上的精确匹配准确率约为50%。它在其他图表类型上表现更好,但由于散点图可能包含*大量*点,因此这是一项更艰巨的任务。
以下是一些我的对象检测器的预测结果:
作为管道的一部分,我必须检测图表的边界框,以便将像素坐标映射到坐标轴标签的真实数值。这一步相当简单,基本上是将第(2)部分相同的代码应用于注释中的 plot-bb 边界框。我们在 JSON 文件中拥有这些训练数据,这是一项简单的任务,因此对象检测器达到了高准确率。
在比赛初期,我开始对 Nicholas 的 Donut 模型进行多次更改,很快发现通过执行一些基本的后处理可以获得更高的性能。然而,即使训练更多轮次、执行数据增强和其他技巧,我意识到无法获得更高的性能。然后我尝试实现 Matcha 模型,并通过很多努力才使其工作(再次感谢 Nicholas 提出了 GitHub 讨论的问题)。一旦 Matcha 模型开始工作,我尝试了各种方法,直到能够尽可能提高性能。以下是在公开排行榜上达到 0.74 的路线图:
max_patches 从512增加到1024太多无效尝试!我将写下我能记住的:
statista、chartqa、plotqa。最佳性能来自 matcha-baseRGBShift、RandomBrightness、ColorJitter 等max_patches 参数增加到1536(介于1024和2048之间)。因此,当我看到将 max_patches 从512增加到1024的改进后,我想,为什么不进一步增加一点看看会发生什么?嗯,它似乎没有提高分数,当然消耗了更多的显存和计算时间。增加 max_patches 会大大增加显存消耗,因此必须降低批量大小,训练时间也更长OneCycleLR 进行训练,但之前尝试过其他调度器,甚至是恒定学习率,从未通过修改学习率调度器看到性能提升tf_efficientnetv2_s 作为我的对象检测器的骨干网络,但尝试过更大的模型,如 tf_efficientnetv2_l,但没有成功bfloat16) 进行混合精度训练没有提供任何性能提升。然而,由于与 float32 相比你使用了更少的显存,你可以使用更大的批量大小,这是一个推荐的做法(我听说 Karpathy 说最好总是使用你能使用的最大批量进行训练,我可能在这里错了)使用 Kaggle 提供的 P100 训练像 Matcha 和 Donut 这样的模型几乎是不可能的。我们最终购买了 Google Colab Pro+,它提供带有40 GB显存的 A100 GPU,因为我们俩都没有像 RTX 3090/4090 这样的深度学习 GPU。使用 A100,我们能够训练大型模型并更快地进行更多实验!我训练了超过30个不同的模型!
尽管我本希望进入金牌区(总是希望做到最好),但我对我们获得的结果和在整个比赛中吸取的所有教训心怀感激。我坚信,如果你想学习某些东西,就去改变它!从头开始编写代码!这是最好的学习方式。我真的很期待阅读其他团队的解决方案。我还想知道是否有人尝试更改 Pix2Struct 的视觉模型和文本模型。我不知道是否可行或如何操作,所以如果你知道,请在评论中留言。
谢谢大家!