返回列表

38th Place Solution - My learnings from AI4C

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

开始: 2022-05-11 结束: 2022-11-10 基础软件 数据算法赛
第38名方案 - 我在 AI4C 中的学习心得

第38名方案 - 我在 AI4C 中的学习心得

(来自:Google AI4Code – 理解 Python Notebooks 中的代码:预测代码与注释之间的关系)

作者:Allohvk (Kaggle Master) | 比赛排名:第38名

概述:

  • 模型:Point-wise(DeBERTa-V3-Small 和 GraphCodeBERT-base,感谢 Guo)和 Pair-wise 集成的简单混合,主要是为了增加多样性。Pair-wise 的权重约为 20%。
  • 数据:通过仔细筛选 Notebooks,使用了约 70% 的数据。未使用外部数据。
  • 算力:免费的 Kaggle 和 Google Colab。最后几周间歇性租用了 A5000-24GB。
    由于算力有限且我只能在周末工作,因此使用了轻量级模型:

有效的策略:

  • 核心:核心方案在 Nguyen 的公开 kernel 中已有详细概述,其基本思想是添加“上下文”,这有助于模型更好地对单元进行排序。

  • 预处理 1:保留 Markdown 中的最后几个 token(即最后几个词)有一点帮助。换句话说,与其简单地截断冗长的 Markdown,我们保留结尾的几个 token。这些最后的词/token 似乎与随后的代码单元联系更紧密,有助于模型建立更好的关联。

  • 预处理 2:从代码单元中提取类名和函数名并将它们移至代码单元的顶部(以避免截断)也略有帮助。将“代码单元中的所有注释”移至代码单元顶部并没有帮助,尽管我强烈感觉这对更大的模型会有帮助(我的模型只有 768 个 token)。

  • 数据选择:选择的 Kernel 应与实际测试数据相关且匹配。这在三个方面很重要:
    ** 符合我的算力预算
    ** 我可以进行更多实验
    ** 在缺乏强验证数据的情况下,我觉得当实际结果开始出炉时,这将起关键作用
    具体有帮助的做法:
    ** Kaggle 在 3 年前将内存大小从 5GB 增加到了 20GB。我可以通过简单搜索关于“You can write up to 5GB to”的 Markdown 来识别一堆旧的 Kernel
    ** 识别使用旧库的 R Kernel、TF1 Kernel 等
    ** 识别共同的祖先/父 Kernel 等
    ** 很多时候,Kernel 没有被复刻,而是被手动复制。因此识别前几个单元(比如 2 个 Markdown 和 3 个代码单元)并移除重复项
    ** 在采样时,从上述类别中取很少的样本(但不要设为 0%)。对于剩余的 Kernel,进行健康采样。
    ** 总的来说,我可以使用约 70% 的样本并仍然获得不错的结果。这 70%,我进一步分为训练集和验证集
    ** 调优后,我也在验证数据上进行了训练
    ** 在过去 3 个月里,随着新数据的不断涌入,每次运行都略微提高了我的分数

  • 集成时的一个小点:在集成期间,通过检查最后一个单元是否为 Markdown,获得了非常微小(小数点后第 4 位)的提升。Pair-wise 模型无法正确对此类 Markdown 进行排序(由于三元组生成的方式)。因此,如果最后一个单元是 Markdown,不要在 Pair-wise 和 Point-wise 之间取平均值,而是直接采用 Point-wise 的数据。

无效的尝试:

  • 尝试了多种注意力头(至少 5 种),但没有一个比默认的好多少。
  • 在顶层添加 Bi-LSTM 也没有帮助。
  • 在 Pair-wise 中,使用了 Arcface 和 Cosface 来锐化嵌入,但效果不佳。事实上,我在一致地复现该模型的结果时遇到了麻烦。
  • “无效”类别中最大的一项是我在“附加背景”部分详述的关于 BigBird 和 Longformer 的经历。
  • 两个代价高昂的错误:浪费了大量 token 空间,因为我没有发现这个 bug。我觉得这本来可以显著提高我的分数。其次,最后几天不得不处理内存错误。我有理由相信根本原因可能是