Benetech图表可及性竞赛第一名解决方案
Benetech图表可及性竞赛第一名解决方案
作者:YumeNeko (Kashiwaba)
发布时间:2023年6月22日
竞赛排名:第1名
得票数:60
首先,我要向所有参与本次竞赛的选手致敬。我也感谢主办方组织了这个有趣的任务竞赛。这个任务非常有趣,我享受了工作过程,因为我可以想到许多不同的方法。我很荣幸能在这个非常有趣的竞赛中赢得第一名。
概述
我的解决方案由一个两步流程组成,首先使用分类模型对图表类型进行分类,然后进行数据系列推理。在数据系列的推理阶段,Bar、Line和Dot分别由针对每种图表类型训练的Deplot进行端到端预测,而Scatter则采用基于目标检测的方法进行预测。
最终分数如下表所示:
|
总体 |
散点图 |
点图 |
折线图 |
垂直条形图 |
水平条形图 |
| 公开 |
0.86 |
0.10 |
0.00 |
0.32 |
0.39 |
0.05 |
| 私有 |
0.72 |
0.30 |
0.01 |
0.13 |
0.26 |
0.01 |
数据集
我使用了以下三个数据集:
- 竞赛数据集
- 同时使用了提取的数据集(comp_extracted_dataset)和生成的数据集(comp_generated_dataset)
- 对于生成的数据,通过简单检查去除了约100张标注有噪声的图像
- ICDAR数据集
- 使用了1406条有标注的数据和1903条无标注的数据
- 对于有标注的数据,我目视检查了标注内容,并手动修正了所有不符合竞赛标注规则(例如%符号)或含有噪声的数据
- 对于无标注的数据,我先目视检查了所有数据的外观,选出可用于竞赛的数据。然后使用Deplot模型推断并分配伪标签,再次目视检查所有结果,并手动修正所有错误的标注
- 生成的合成数据集
- 在检查竞赛数据集后,我发现comp_generated_dataset alone没有足够的多样性来达到鲁棒性,因此我生成了约65k张合成数据
- 我主要生成comp_generated_dataset所没有的特征:
- 直方图
- 标签包含换行
- 带误差条的条形图
- 折线图包含不在数据系列中的x标签
- 等等
- 为了增加多样性,我还包含了来自@brendanartley发布的10k张图像
解决方案流程
1. 图表分类
- 没有太多需要注意的,我执行了一个简单的分类任务
- 使用了两个模型(convnext_large_384和swin_large_patch4_window12_384),并通过加权集成结果
训练配置
- 数据集(训练和验证随机划分)
- 训练集(78k图像):comp_extracted_dataset, comp_generated_dataset, ICDAR_dataset, synthetic_dataset(horizontal_bar/dot)
- 验证集(4k图像):comp_extracted_dataset, ICDAR_dataset, synthetic_dataset(horizontal_bar/dot)
- 超参数
- 训练轮数:15
- 批大小:16
- Adafactor优化器(学习率=3e-5)
2. 数据系列预测
基于第一步的分类结果,对散点和其余图表采用不同的方法。除了散点,其余使用Deplot预测,散点使用基于目标检测的预测。
2-a. 条形图、折线图和点图
- 我基于@nbroad发布的Donut笔记本进行了实验,将模型改为Deplot。但仅改变模型无法很好地训练,因此我做了一些修改:
- 真实标签格式:移除图表类型,并调整为Deplot原始格式:
<0x0A> x_value1 | y_value1 <0x0A> x_value2 | y_value2 <0x0A> x_value3 | y_value3 </s>
- 水平条形图的x轴和y轴交换:由于竞赛标注规则中x轴和y轴的概念与Deplot原始格式相反,我按照Deplot的原始概念进行训练,在推理时交换值
- 训练分多个阶段:第一阶段使用所有图表类型的数据训练(All Chart-type Train),然后使用该训练结果作为初始权重,再针对特定图表类型进行一到两次额外训练(Specific Chart-type Train),生成针对特定图表类型的模型
- 垂直条形图和折线图的分数通过此方法略有提升(垂直条形图进行了两次特定图表类型训练,折线图进行了一次)
- 水平条形图在第二阶段训练后CV变差,可能由于提取数据量较小,因此我决定使用All Chart-type Train模型进行预测
- 点图只有生成的数据,我认为无法成功验证,因此决定不进行第二阶段训练,使用All Chart-type Train模型预测
训练配置
- All Chart-type Train
- 数据集
- 训练集(120k图像):comp_extracted_dataset, comp_generated_dataset, ICDAR_dataset, synthetic_dataset
- 验证集(2.5k图像):comp_extracted_dataset, ICDAR_dataset, ICDAR_manualannot_dataset
- 超参数
- 训练轮数:8
- 批大小:2
- Adafactor优化器(学习率=1e-5)
- 带预热步的余弦调度器(warmup_step=4000)
- 数据增强:高斯模糊、高斯噪声、一些色彩增强
- Specific Chart-type Train(vertical_bar)
- 第一次训练
- 训练集(6k图像):comp_extracted_dataset, ICDAR_dataset, synthetic_dataset
- 验证集(1.3k图像):comp_extracted_dataset, ICDAR_dataset, ICDAR_manualannot_dataset
- 第二次训练
- 训练集(1500图像):comp_extracted_dataset, ICDAR_dataset, ICDAR_manualannot_dataset
- 验证集(500图像):comp_extracted_dataset, ICDAR_dataset, ICDAR_manualannot_dataset
- 超参数
- 带预热步的余弦调度器(warmup_step=0)
- 其他与All Chart-type Train相同
- Specific Chart-type Train(line)
- 第一次训练
- 训练集(1150图像):comp_extracted_dataset, ICDAR_dataset, ICDAR_manualannot_dataset
- 验证集(400图像):comp_extracted_dataset, ICDAR_dataset, ICDAR_manualannot_dataset
- 超参数
- 带预热步的余弦调度器(warmup_step=0)
- 其他与All Chart-type Train相同
分数对比
All Chart-type Train结果:
|
总体 |
散点图 |
点图 |
折线图 |
垂直条形图 |
水平条形图 |
| 公开 |
0.78 |
0.06 |
0.00 |
0.29 |
0.38 |
0.05 |
| 私有 |
0.53 |
0.13 |
0.01 |
0.12 |
0.26 |
0.01 |
Specific Chart-type Train结果:
|
总体 |
散点图 |
点图 |
折线图 |
垂直条形图 |
水平条形图 |
| 公开 |
0.81 |
0.06 |
0.00 |
0.32 |
0.39 |
0.05 |
| 私有 |
0.55 |
0.13 |
0.01 |
0.13 |
0.26 |
0.01 |
2-b. 散点图
- 只有散点图使用Deplot无论怎么尝试都不够准确,因此采用了基于目标检测的方法
- 由于散点图保证具有数值类型的标签值,因此如果知道"标签位置"、"标签文本"和"散点位置",就很容易通过比例计算值。我使用CACHED检测"标签位置",Deplot读取"标签文本",YOLOX检测"散点"
- 标签边界框和标签文本的映射有点粗糙,但最小的标签文本映射到最左边的标签边界框(y标签则为最上),最大的标签文本映射到最右边的标签边界框(y标签则为最下)。检测到的标签边界框总数可能与读取的标签文本总数不匹配,但我们在验证数据中检查时发现这种模式非常罕见,因此没有采取特殊措施
- 上述目标检测方法得到的散点图分数为公开:0.10/私有:0.30,远优于基于Deplot的分数(公开:0.06/私有:0.13)
更多细节
散点检测
- 使用comp_extracted_dataset, ICDAR_dataset, synthetic_dataset作为训练数据(约12.5k图像)
- 使用提供的标注数据和图像处理半自动化生成,但不可避免有噪声,因此通过人工标注修正
- 为了提高检测精度,仅对绘图区域进行裁剪用于训练和推理
- 模型为YOLOX-l,输入图像尺寸为1280,训练50个epoch
标签文本读取
- 使用comp_extracted_dataset, ICDAR_dataset, comp_generated_dataset作为训练数据(约62k图像,所有图表类型)
- 训练参数与2-a中的All_Chart-type_Train相同,但修改Ground Truth格式为:
<0x0A> x_label1 | x_label2 | x_label3 <0x0A> y_label1 | y_label2 </s>
- 最初考虑使用EasyOCR等方法,但存在许多问题,如支持字符旋转等,似乎很难通过调优提高通用性,因此采用Deplot批量读取的方法
最后,我要再次感谢所有参与本次竞赛的人。非常感谢您花时间阅读本文!