返回列表

18th place solution: efficientnet b3

399. Cornell Birdcall Identification | birdsong-recognition

开始: 2020-06-15 结束: 2020-09-15 环境监测 数据算法赛
第18名方案:EfficientNet B3

第18名方案:EfficientNet B3

作者: CPMP (Grandmaster) | 团队成员: ONODERA (Grandmaster)
比赛排名: 18th

首先,我要感谢主办方和Kaggle举办了这场极具挑战性的比赛,以及那个真正“隐蔽”的测试集。也许隐蔽得有点过头了,但多亏了社区,像我们这样的后来者才能在几天内搞定提交模板。我还要感谢我的队友Kazuki,如果没有他,在多次尝试未能击败公共Notebook基线后,我可能早就放弃了……

概述

我们最好的提交是基于在Log梅尔声谱图上训练的单个EfficientNet模型。对于基线,我是从零开始构建的,而不是复用现有的优秀基线。原因是我参加Kaggle比赛是为了学习,而从头尝试比修改别人的代码能让我学到更多。在比赛结束前的两周里,我们在这个基线上进行了迭代。

鉴于整体方法已广为人知且可能被大多数参赛者采用,我将只讨论可能与其他人做法略有不同的部分。

训练数据片段

主办方明确表示,在随机5秒片段上训练有一个缺点:某些片段可能不包含目标鸟类。因此我们采用了一个简单的假设:片段是经过裁剪的,即为了减少存储需求,开头或结尾没有歌声的时段已被移除。因此,我们在片段的前5秒或后5秒进行训练,假设这些部分包含目标鸟类。我们将所有数据预处理为32 kHz采样率。

噪声

我们添加了从提供的两个测试序列中提取的噪声,有点像Theo Viel的做法。但我们利用元数据提取不含鸟叫的子序列,然后将这些序列平滑过渡合并。接着,我们将合并序列中的随机片段添加到我们的训练片段中。

无叫声

我们将标记为“nocall”的freefield1010片段添加到训练数据中。我们增加了一个第265个类别来代表“无叫声”。结果我们的模型可以预测一只或多只鸟,以及“无叫声”。添加这些数据和“无叫声”类别可能是我们在CV和LB分数上看到的最重要的一项改进。正是这让我们超越了公共Notebook基线。

多鸟片段

训练数据和测试数据之间的主要记录差异在于,训练数据是多分类数据,而测试数据是多标签数据。因此,我们实现了一种mixup变体,最多可以合并3个片段。这并不完全是mixup,因为合并片段的目标是每个合并片段目标的最大值。

次要标签

主要标签存在噪声,但次要标签的噪声更大。因此,我们屏蔽了次要标签的损失,因为我们不想在不确定的情况下强迫模型学习存在或缺失。我们定义了一个次要掩码,将次要标签的BCE损失置零。例如,假设只有3个ebird_code:b0、b1和b2,一个片段的主要标签是b0,次要标签是b1,那么这两个目标值是可能的:

[1, 0, 0]

[1, 1, 0]

因此次要掩码是:

[1, 0, 1]

对于合并片段,如果目标不是主要标签之一且是次要标签之一,则该目标被屏蔽。

损失函数

我们在ebird代码的独热编码上使用二元交叉熵。使用BCE而不是softmax是有意义的,因为BCE可以无缝扩展到多标签。我们尝试了Dice Loss来直接优化F1分数,但由于某些原因,这导致了非常严重的过拟合。

类别权重

每个物种的记录数量并不总是100条。为了不惩罚频率较低的物种,我们使用与类别频率成反比的类别权重。对于“无叫声”类别,我们将其设为1,尽管它比每个鸟类类别都要频繁得多,以确保模型正确学习“无叫声”。

模型

我们最好的模型是基于Log梅尔声谱图的EfficientNet。我们将图像大小调整为EfficientNet图像的两倍:EfficientNet B1使用240x480,B2使用260x520,B3使用300x600。我们从efficientnet_pytorch预训练模型开始。我们尝试了PANNs模型的注意力头,但导致了严重的过拟合。老实说我不确定为什么,也许我们做错了什么。

训练

没什么特别的,Adam优化器和余弦学习率调度器,共60个epoch。通常最后一个epoch是得分最高的,我们使用最后一个epoch的权重进行评分。

Log梅尔声谱图

没什么特别的,除了我们在最初创建的声谱图中看到低频部分有很多能量。因此我们将频率裁剪为至少300 Hz。鉴于测试数据的采样率是该频率的两倍,我们还将频率上限裁剪为16 kHz。

数据增强

时间和音调变化以非常简单的方式实现:修改裁剪序列的长度,并修改采样率,而不修改数据本身。例如,我们会读取片段的

同比赛其他方案