返回列表

16th Place Solution

587. Stanford Ribonanza RNA Folding | stanford-ribonanza-rna-folding

开始: 2023-09-07 结束: 2023-12-07 基因组学与生物信息 数据算法赛
第16名解决方案
作者:acwh | 竞赛排名:第16名 | 发布时间:2023-12-09

第16名解决方案

首先,我要感谢主办方组织本次竞赛,也感谢社区中所有参与讨论的成员。

概述

  • Transformer架构
    • 分别为2A3和DMS使用独立的模型
  • 使用从BPPM推导出的Pr(碱基配对)(即每个碱基配对概率)
  • 动态位置偏置

解决方案说明

数据

输入特征包括:

  • 序列
  • 来自4个RNA结构预测包的Pr(碱基配对)(即BPPM矩阵沿一个轴的求和)

我最初对是否包含BPPM有所顾虑,认为这可能影响模型对更长序列的泛化性能:

  1. 碱基-碱基配对概率包含过于具体的"错误"信息
  2. 缺乏对伪结的考虑
  3. 与较短的训练序列相比,较长测试序列的单个概率会被稀释

我的折中方案是考虑每个碱基的全局配对概率。Das实验室的这篇论文评估了各种RNA结构预测包计算的Pr(配对)与化学图谱实验结果的比较。他们发现CONTRAfold 2、60°C下的ViennaRNA 2以及带有BLStar参数的RNAsoft是最有效的方法。因此,我使用这三种方法以及Eternafold为所有序列生成了Pr(配对)向量作为特征。

顺便提一下,我使用Arnie来运行这些软件包,并在配置多进程上花费了比我愿意承认的更多时间,不过总体而言,我认为这最终节省了时间。我确实尝试扩展到更多方法,但由于bug和运行时间限制,很快就放弃了。

在竞赛早期,我也尝试了从ViennaRNA生成的各种结构特征(MFE、质心、集成)。与仅使用序列相比,我能够获得性能提升,但一旦加入Pr(碱基配对)特征后,这些特征就没有任何额外益处了。

架构

我的最终方案是一个单独的Transformer架构,分别训练用于预测2A3或DMS。

序列(Seq)

  • 4个token嵌入 → 512维输出

Pr(碱基配对)

  • 线性层:4维输入 → 512维输出

Transformer

  • 18层,512维,8个头
  • 后归一化(Postnorm)
  • 动态位置偏置
  • 注意力内部门控值(Intra-attention Gating on Values)
  • 输入:序列 + Pr(碱基配对)

这是我第一次使用Transformer架构。幸运的是,我找到了@lucidrains开发的x-transformers库,并用它来尝试/学习各种Transformer变体。

有效改进:

动态位置偏置
我的首要目标之一是理解如何使Transformer泛化到更长的序列。最初我发现了ALiBi论文,并认为这会是一个有用的方法。然而,根据x-transformers文档,动态位置偏置似乎更可能在此场景中有效。由于我不相信仅从训练集中就能准确评估长度外推的性能差异,因此我没有直接比较ALiBi(或其他相对位置偏置)与动态位置偏置。动态位置偏置在公开与私有数据集上显示出最大的提升(公开:0.15400 vs 0.15002;私有:0.18476 vs 0.14976)。注意:此结果是在使用Pr(碱基配对)数据之前得到的。

注意力内部门控值
这是来自Alphafold2的注意力变体,用输入门控聚合值。这是x-transformers中可用的特性之一,似乎在性能上有小幅提升。注意:我在很久前就添加了这个特性并一直保留,因此它很可能在最终模型中没有实际价值。

后归一化(Postnorm)
我对Transformer最早期的修改之一是从普遍更受推荐的前归一化(prenorm)切换到原始的后归一化方法。这带来了收敛速度和性能的提升。在竞赛过程中,随着架构和输入数据方法的改变,我多次重新检查了这一点,结果始终相同。我也尝试了x-transformers中的其他归一化方法,但都没有明显改进。

18层
18层在性能和训练时间之间似乎达到了最佳平衡。我主要测试了12、18、24层。12层与18层相比在排行榜上显示出小幅性能提升(公开:0.14383 vs 0.14330;私有:0.14595 vs 0.14517)。18层与24层相比,我没有注意到CV分数的任何差异,因此没有提交任何24层模型。

嵌入求和
在通过线性层(维度均为512)后,我采用简单元素级求和的方式整合嵌入的序列和Pr(碱基配对)。我尝试过其他方法,但它们似乎都对收敛和/或性能产生了负面影响。

训练

我使用了@iafoss的Transformer starter notebook中的数据分割,所有实验工作都使用第0折。由于我最终为2A3和DMS预测使用了独立模型,满足SN >= 1.0和reads >= 100的序列集对每组都更高,因为存在一部分序列只有2A3或DMS满足约束条件。

此外,我引入了react_error值作为损失加权手段,以便更有信心地使用更多低质量序列(幸运的是,这正好发生在react_error问题被发现和修正之后)。react_error值严格大于0,通常相当低(我认为高质量样本的中位数至少约为0.125)。我决定尝试使用指数函数为每个碱基的损失加权:

加权方案v1:
exp(-react_error)

加权方案v2:
exp(-(react_error²))

这将为序列中的每个碱基产生一个介于0和1之间的权重值。虽然我没有很好的数学理论依据,也确信可能有更好的方法,但这确实使CV性能提升了约0.0005-0.001,即使仅使用高质量序列时也是如此。

我的最终模型训练方法有些不稳定:

  • 2A3模型
    • fit_one_cycle(周期=256, 学习率=5e-4, pct_start=0.01)
    • SN >= 1.0, 读数 >= 100
    • exp(-(react_error²))加权
    • 提前停止于第45周期
  • 2A3模型第二部分
    • 微调2A3模型,学习率=5e-5
    • SN >= 0.2, 读数 >= 75
    • exp(-react_error)加权
  • DMS模型
    • 微调2A3模型第二部分,学习率=5e-5
    • SN >= 1.0, 读数 >= 100
    • exp(-(react_error²))加权
  • DMS模型第二部分
    • 微调DMS模型,学习率=5e-5
    • SN >= 0.2, 读数 >= 75
    • exp(-react_error)加权

正如我前面提到的,我所有实验都使用了第0折的交叉验证分割。不幸的是,我在最后两周失去了测试其他架构方法的时间,直到最后一天才决定回归到独立模型,因为它们在CV中显示出轻微的性能提升,因此未能运行完整的交叉验证折。然而,作为最后的努力,我尝试在第二个最终提交中对第0折验证数据运行1个周期,这在排行榜上获得不错的提升(公开:0.14330 vs 0.14199;私有:0.14517 vs 0.14458)。

同比赛其他方案