返回列表

A High Schooler’s Solo Journey to get a Silver Medal.

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

开始: 2022-05-11 结束: 2022-11-10 基础软件 数据算法赛
一名高中生的银牌单打独斗之旅

一名高中生的银牌单打独斗之旅

作者: antorino | 比赛排名: 第18名

模型架构

该模型基于将问题视为回归任务,其中已知的代码单元相对位置被分配一个介于0到1之间的值,而预测的Markdown单元位置可以取-0.2到1.2之间的值。通过这种方式,我对代码单元施加了归纳偏置,并允许Markdown单元放置在代码单元之前或之后的任何位置。

模型架构如下:

模型架构图

首先,分词后的(CodeBERT分词器)代码和Markdown单元分别输入到CodeBERT中。仅选取CodeBERT输出的第一个潜在代码和Markdown向量:

x_code = self.code_bert(code_tokens.flatten(0,1),
                                attention_mask=code_mask.flatten(0,1).to(device))\
                .last_hidden_state.view(*code_tokens.shape[:3],-1)[:,:,0,:]

然后,将位置编码添加到潜在代码向量中,作为编码器的输入。编码器的输出随后与潜在Markdown向量一起(作为上下文)输入到解码器中,解码器可以关注所有单元(代码和Markdown)之间的交互。解码器的输出最终输入到回归器中,输出Markdown单元的位置预测。

模型训练

模型仅使用比赛提供的数据集进行训练。与其他解决方案相比,训练中唯一显著的区别在于,我没有使用MSE或MAE作为损失函数,而是尝试使用受Spearman Rho启发的损失函数来近似Kendall Tau,该函数内部使用软排名,使其具有可微性。

def spearman_p_loss(pred, target_ranks, **kw):
    d2 = 0.
    n = 0.
    for p,t in zip(pred.flatten(1),target_ranks.flatten(1)):
        mask = t != -1
        rp = soft_rank(p[mask].unsqueeze(0), **kw) - 1.
        rt = t[mask].unsqueeze(0)
        d2 += (rt-rp).square().sum()
        n  += mask.sum()
    return 4. * d2/ ((n*(n-1)))

参考链接:维基百科:斯皮尔曼等级相关系数

快速计算 Kendall Tau

我注意到计算Kendall Tau的代码有点慢,即使是基于二分查找的版本也是如此。因此,作为一个有趣的实验,我加快了它的速度,并在没有任何循环(且批量化)的情况下实现了它:

   def update(self,preds,index_gt):
        masks = index_gt != -1
        _preds=preds.clone()
        _index_gt = index_gt.clone()
        m = masks.flatten(1)
        _index_gt[~masks] = MAX_CELLS*2
        _preds[~masks] = np.inf
        pred_ranks = _preds.flatten(1).argsort(dim=1)
        ranks=torch.gather(_index_gt.flatten(1),1,pred_ranks)
        self.inversions += torch.triu((ranks.unsqueeze(1).permute(0,2,1)>ranks.unsqueeze(1))).sum()
        len_gt = masks.sum(dim=(1,2))
        self.total_2max +=((len_gt-1)*len_gt).sum()

    def compute(self):
        return  1. - 4. * self.inversions /  self.total_2max

结束语

由于在截止日期前一个月才参加比赛,我的算力和时间都不足,因此我的模型最终训练不足。

我非常享受这次比赛,咱们下一场见!

同比赛其他方案