返回列表

9th Place - Post Process LB 0.926 to LB 0.963!

419. Rainforest Connection Species Audio Detection | rfcx-species-audio-detection

开始: 2020-11-17 结束: 2021-02-17 环境监测 数据算法赛
第9名方案 - 后处理将 LB 0.926 提升至 LB 0.963!

第9名方案 - 后处理将 LB 0.926 提升至 LB 0.963!

作者: Chris Deotte | 比赛排名: 第9名

感谢 Kaggle 和 RFCx 举办了这场有趣的比赛。我未经过后处理的最终提交得分为 Private LB 0.926,而经过后处理的提交得分为 Private LB 0.963!后处理带来了 +0.037 的提升!

如何达到 LB 0.950+

本次比赛的评估指标与其他比赛不同。我们需要提交 submission.csv,其中每一行是一个测试样本,每一列是一个物种的预测结果。

在其他比赛中,指标通常计算列方向 AUC。而在本次比赛中,指标本质上是行方向 AUC。因此,我们需要每一列代表概率。常见物种的列值需要较大,而稀有物种的列值需要较小。

训练集分布

训练数据的分布中,每个物种的假阳性数量大约是真阳性数量的 6 倍。如果你使用这些数据训练模型,那么当模型对预测不确定时,它会预测在训练数据中观察到的均值,即 1/7。因此,如果它不确定物种 3,它会预测 1/7;如果不确定物种 19,它也会预测 1/7。

这是一个问题,因为物种 3 大约出现在 90% 的测试样本中,而物种 19 仅出现在大约 1% 的测试样本中。因此,当你的模型不确定时,它应该预测 90% 给物种 3,预测 1% 给物种 19。

测试集分布 - 后处理

为了修正模型的预测,我们对几率进行缩放。注意,缩放几率不会影响 0 和 1 的预测,它只影响不确定的中间预测值。

首先,我们将 submission.csv 的概率列通过公式转换为几率:
$$ \text{odds} = \frac{p}{1-p}$$
然后我们通过以下公式缩放几率:
$$ \text{new odds} = \text{factor} * \text{old odds}$$
最后我们转换回概率:
$$ \text{prob} = \frac{\text{new odds}}{1 + \text{new odds}}$$

示例代码

# 将概率转换为几率,应用乘数,再转换回概率
def scale(probs, factor):
    probs = probs.copy()
    idx = np.where(probs!=1)[0]
    odds = factor * probs[idx] / (1-probs[idx])
    probs[idx] =  odds/(1+odds)
    return probs

for k in range(24):
    sub.iloc[:,1+k] = scale(sub.iloc[:,1+k].values, FACTORS[k])

将 LB 提升 +0.040!

剩下的唯一细节是如何计算上面的 FACTORS(因子)。至少有 3 种方法。

  • 创建一个输出层为 sigmoid(而非 softmax)的模型。使用真阳性和假阳性数据,配合 BCE loss 进行训练。预测测试数据。计算每列的均值。转换为几率并除以训练数据的几率。
  • 使用全 0 且某一列为 1 的 submission.csv 来探测 LB。然后利用数学计算该物种的 factor。更新:使用小于 1 的随机数代替 0,以避免排序的不确定性。
  • 使用 RFCx 论文 此处 第 2.4 节表 2 中列出的因子。

就我个人而言,我使用了上面列出的第一种方法。我没有 5 天的时间去探测 LB 24 次(针对第二种方法)。至于第三种方法,我在比赛最后一天才找到那篇论文。

我的单模型未经后处理的得分为 Private LB 0.921,经过后处理得分为 Private LB 0.958。集成多种图像尺寸和主干网络后,LB 分别提升至 0.926 和 LB 0.963。

模型细节

我使用 Librosa 的 feature.melspectrogrampower_to_db 将每个音频文件转换为梅尔频谱图,参数为采样率 32_000n_mels = 384

同比赛其他方案