返回列表

11th Place Solution: Nested Transformers

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

开始: 2022-05-11 结束: 2022-11-10 基础软件 数据算法赛
第11名方案:嵌套Transformer

概览

我们将我们的网络架构称为“嵌套Transformer”,因为它包含两个层级的Transformer:

  • 单元格Transformer(Cell transformer):一个用于编码单元格Token的Transformer编码器,这可以是一个典型的用于NLP的Transformer。
  • 笔记本Transformer(Notebook transformer):一个具有单元格*单元格自注意力机制的Transformer编码器,用于学习单元格之间的交互。
嵌套Transformer架构图

源代码:https://github.com/ShinSiangChoong/kaggle_ai4code_nested_transformers

有效的方法

修改单元格Transformer的输入格式

  • 输入采用以下格式:<code><sep><source_tokens><mark><sep><source_tokens>
  • 感谢 @cabbage972 验证了这个想法的有效性。

单元格特征

  • 代码单元格的顺序是已知的,而Markdown单元格的顺序是未知的,因此笔记本Transformer中直接的位置嵌入方案无法正常工作。单元格特征旨在告知模型已知的代码单元格位置/顺序。
  • 我们为每个单元格使用2个特征,即单元格类型(代码 -> 1,Markdown -> 0)和代码单元格中的百分位排名:如果单元格是Markdown单元格,此特征 = 0。
  • 这2个特征通过全连接(FC)层进行“扩展”,使其表示为与单元格Token嵌入具有相同维度的嵌入向量。
  • 然后将这些单元格特征嵌入与Token嵌入连接起来,一起传递到聚合注意力层。

聚合注意力

  • 我们认为不同的Token(以及单元格特征)在表示单元格时具有不同的重要性。聚合注意力层用于学习每个Token嵌入(以及单元格特征嵌入)的权重。
  • 权重通过Softmax层进行归一化,使得最终的单元格嵌入是其Token和特征嵌入的加权平均值。
  • 感谢 @cabbage972 验证了这个想法的有效性。

双头架构

  • 逐点头:输出每个单元格的百分位排名。应用L1损失。
  • 成对头:对于每对单元格A和B,预测单元格B是否是单元格A的下一个单元格。应用交叉熵损失。
  • 我们在推理时只使用逐点头,即单元格根据预测的百分位排名进行排序。
  • 推理期间不使用成对头,然而,在我们的实验中,包含成对头有助于将验证分数提高约0.03。

代码顺序修正

  • 由于我们的模型预测每个单元格(包括代码单元格)的百分位排名,因此可能会违反代码单元格的顺序(这是已知的)。
  • 如果发生这种情况,我们根据给定的顺序交换代码单元格。
  • 这个想法仅略微提高了分数。实际上,在给定单元格特征的情况下,模型能很好地学习代码顺序。

无效的方法

  • 以贪婪的方式利用成对头预测,同时满足代码顺序约束,即通过选择预测得分最高的单元格来持续确定下一个单元格。
  • 将成对头预测用作距离矩阵,然后使用LKH求解序列排序问题(带优先约束的TSP)。
  • 端到端地一起训练2个单元格Transformer骨干网络,依靠聚合注意力来聚合来自2个骨干网络的Token嵌入。

补充说明

  • 最终模型是4个不同单元格Transformer骨干网络的集成,即CodeBERT、Deberta-large
同比赛其他方案