返回列表

Public LB 14th Solution

515. Google AI4Code – Understand Code in Python Notebooks | AI4Code

开始: 2022-05-11 结束: 2022-11-10 基础软件 数据算法赛
Public LB 14th Solution

Public LB 第14名方案

作者: Alireza
发布时间: 2022-08-12

首先,我要感谢 Kaggle 和 Kaggle 社区为我们提供通过经验和协作学习的机会。这是我第一次参加 Kaggle 比赛,我感到非常高兴,因为我学到了很多关于各种模型架构(如 Transformers、Pointer Networks 等)以及一般 NLP 的知识。

针对排序问题,我们有三种方法(如果我错了请纠正!):Point-wise、Pair-wise 和 List-wise。Point-wise 方法缺乏全局上下文是一个问题,不过有些参与者尝试通过将代码单元格子集附加到每个 Markdown 单元格来解决这个问题。Pair-wise 策略看起来非常强大,但代价是运行时间长。最后,List-wise 尝试利用全局和局部信息的组合来对单元格进行排序。

我选择了 List-wise 方法,因为它比 Pair-wise 方法更快,而且对我来说似乎更自然。

下图展示了模型架构:

Model Architecture
  1. 使用 sentence-transformers/all-mpnet-base-v2 分别计算单元格特征: 在预处理每个单元格的文本后,我选择前 64 个和后 64 个单词,以了解单元格的开始和结束方式。然后将其输入到 Sentence Transformer 模型中,生成一个 768 维的特征向量。
  2. 然后,我将以下 8 个特征附加到每个向量上:
    • is_code:如果是代码单元格则为 1,否则为 0
    • is_markdown:如果是 Markdown 单元格则为 1,否则为 0
    • code_rank:如果是代码单元格,则为代码单元格的排名,否则为 0
    • toc_rank:如果是 Markdown 单元格且存在目录(ToC),则为 Markdown 单元格在目录中的排名,否则为 0
    • numberd_rank:如果 Markdown 单元格有编号标题(如 1.1, 1.2),则为其排名,否则为 0
    • has_heading_1:如果 Markdown 单元格包含一级标题则为 1,否则为 0
    • has_heading_2:如果 Markdown 单元格包含二级标题则为 1,否则为 0
    • has_heading_3:如果 Markdown 单元格包含三级标题则为 1,否则为 0
  3. 接着,我使用一个 8 头、10 层的 Encoder-only Transformer 来计算每个单元格的最终特征。
  4. 最后,我为代码单元格设置两个输出,为 Markdown 单元格设置四个输出:
    • rank:这是我在推理中使用的排序输出。我对其应用 Sigmoid 函数。
    • code_rank:代码单元格在其他代码单元格中的排名。
    • markdown_rank:Markdown 单元格在其他 Markdown 单元格中的排名。
    • toc_rank:Markdown 单元格在目录中的排名。
    • numbered_rank:Markdown 单元格在其他编号 Markdown 单元格中的排名。

损失函数

使用了 L1Loss,但我没有在 [0, 1] 范围内使用,而是在 [0, #cells](单元格数量)范围内使用。为此,我首先应用 Sigmoid,然后乘以单元格数量,并将结果用作预测输出。这是因为较长的 Notebook 对评分函数的贡献更大,因此我们应该更加关注它们的错误。

训练时间

训练 Notebook Transformer 非常快。在 P100 上,批次大小为 10 个 Notebook、步数为 17k 的情况下,一个 Epoch 的训练不到 30 分钟。

推理时间

整个推理过程(包括我的预处理)大约需要两个小时。但是,模型本身完成只需要不到一个小时。

预处理

  1. 修复编码
  2. 修复 Markdown 单元格中的 HTML
  3. 检测目录排名
同比赛其他方案