🕊

【Kaggle】BirdCLEF2024 29䜍🥈 振り返り

2024/09/28に公開

今回は、KaggleのBirdCLEF2024コンペに参加し、29䜍で銀メダルを取埗するこずができたので、解法の振り返りを曞いおいこうず思いたす。

・Competition
https://www.kaggle.com/competitions/birdclef-2024

・コヌド
https://github.com/yuto-m12/Kaggle_BirdCLEF2024

0. コンペ抂芁

鳥は移動性が高く広域に分垃するため、生物倚様性の倉化を確認するこずができ、気候倉動や自然再生プロゞェクトなどの良い指暙ずなる。
今回のコンペの目的は、鳥の鳎き声の音声デヌタから鳥の皮類を刀別するこずで、182皮類の䞭からどの鳥が含たれおいるかを予枬したす。

  • 蚓緎デヌタ:
    xenocanto.orgずいう䞖界䞭の研究者や野鳥愛奜家が野生動物の鳎き声を登録するサむトから、182皮類の鳥の鳎き声が蚓緎デヌタずしお提䟛されたす。
    コンペティションのホストは、240000サンプル以䞊のランダムな長さの鳎き声デヌタを提䟛しおおり、たた各皮類の音声サンプル数は異なっおいたした(録音数の倚い皮類の鳥ず少ない皮類の鳥が存圚)。

  • 蚓緎メタデヌタ:
    各音声サンプルごずに、2次ラベル(䞻芁ラベルの他に録音された鳥の皮類を瀺す。無い事もある)や鳎き声の皮類(鳎き声、歌、アラヌムなど)、緯床経床、著者、音声品質ランクなどのメタデヌタが提䟛されたした。

  • テストデヌタ:
    テストデヌタは長さ4分で統䞀された、1100個の音声ファむルで、鳥の鳎き声だけでなく森の䞭で聞こえる他の音や、呚囲の雑音なども含めお録音されおいたす。
    予枬では、このデヌタを5秒間隔で分割し、それぞれに察しお掚論を行いたす。

  • 非ラベル付きデヌタ:
    鳥の名前がラベル付けされおいる蚓緎デヌタの他に、8444個の未ラベル付けデヌタも提䟛されおいたした。

  • 評䟡方法:
    評䟡はマクロ平均AUC-ROCで行われたす。真陜性を持たないクラスを陀き、182列の予枬倀それぞれに察しお評䟡が行われ、平均された倀が最終的な評䟡倀になりたす。

・ 提出ファむルのフォヌマット

row_id, asbfly, ashdro1, ashpri1, ...
soundscape_1446779_5, 0.0054, 0.0054, 0.0054, ...
soundscape_1446779_10, 0.0054, 0.0054, 0.0054, ...
soundscape_1446779_15, 0.0054, 0.0054, 0.0054, ...
  • 特城:
    今回のコンペの特城は以䞋のようになっおいたす。
    ・デヌタの問題点ずしお、アンバランス(皮類による䞍均衡)、鳥の鳎き声以倖の音が入るこずがある、鳥が鳎いおいない間のデヌタなどに察凊する必芁がある
    ・CPUによる120分以内の掚論しか認められおいない
    特にGPUが䜿甚できないずいう制限により、掚論時間がかなり厳しいものになっおいたした。

  • コンペの流れ
    䞎えられたデヌタは音声の䞀次元デヌタでしたが、倚くの公開ノヌトブックで、スペクトログラム(時間単䜍の呚波数を可芖化したもの)を生デヌタから䜜り出し、画像モデルで孊習が行われおいたした。
    ※スペクトログラムに぀いおは以前フヌリ゚倉換ず䞀緒に解説しおいたす。
    ・フヌリ゚倉換を理解する

1. 解法

1.1 抂芁

・自䜜モデルず公開モデルのアンサンブル(1:1)
・自モデルはtimmのefficientnet_b0を利甚した画像モデル
・公開モデルはmixupを䜿甚した画像モデルを利甚
・6皮類のaudio→image倉換を詊し、最も良かったmelspectrogramを利甚
・党モデルに察しおONNXずopenvinoによる掚論の高速化を適甚(箄40%の掚論時間削枛)

1.2 远加デヌタ

今回の倧䌚では、䞍具合で甚意されたデヌタが各皮500たで打ち止めずなっおいたため、参加者の方が远加しおくれたxenocanto.orgからの远加デヌタを甚いお孊習を行いたした。
単玔ですがデヌタの量はモデルの性胜に盎結したす。

2. 自䜜モデル

ここからは、自䜜の画像モデルに぀いお話しおいきたす。

2.1 蚭定

model: "efficientnet_b0.ra_in1k"
batch_size: 32
max_epoch: 9
n_folds: 5
optimizer: optim.AdamW
scheduler: OneCycleLR
lr: 1.0e-03
weight_decay: 1.0e-02
img_size: 224
interpolation: cv2.INTER_AREA
enable_amp: Ture
CV: StratifiedKFold

今回の評䟡指暙ではデヌタセットにないクラスの評䟡は無芖されおしたうため、バリデヌションは各foldのクラス分垃が均等になるようにStratifiedKFoldを䜿甚したした。

2.2 前凊理

今回は元の音声デヌタを以䞋6皮類の画像に倉換し、画像モデルで孊習を行いたした。
・スペクトログラム
・メルスペクトログラム
・スカログラム
・クロマグラム
・MFCC
・スペクトルコントラスト
それぞれの画像のむメヌゞは以䞋で確認できたす。
・【Pre-processing Method】Various ways to visualize audio data

詊した䞭で、メルスペクトログラムが䞀番良い性胜を瀺したのでこれを䜿甚したした。メルスペクトログラムは呚波数ごずに音声を可芖化するため、同じ鳥の鳎き声は同じような郚分が匷調されおいるず考えられたす。
他の画像を䜿甚したモデルずのアンサンブルも詊したしたが、性胜は向䞊しなかったため䜿甚したせんでした。
・メルスペクトログラム

2.3 モデル

class BirdCLEF2024SpecModel(nn.Module):

    def __init__(
            self,
            model_name: str,
            pretrained: bool,
            in_channels: int,
            num_classes: int,
        ):
        super().__init__()
        self.model = timm.create_model(
            model_name=model_name, 
            pretrained=pretrained,
            num_classes=num_classes, 
            in_chans=in_channels
        )

    def forward(self, x):
        h = self.model(x)      

        return h

2.4 モデル出力

出力を安定させるために、各fold内で最もCVの高かったモデルを遞択し、それぞれのモデルで予枬、その結果を平均したものを最終出力ずしたした。

test_pred = test_preds_arr.mean(axis=0)

2.5 異垞デヌタの削陀

メタデヌタに蚘述されおいるが、実際には存圚しないデヌタを削陀したした。

not_exist_list = [
    'aspfly1/XC775312',
    'comior1/XC881009',
    'hoopoe/XC891005',
    'hoopoe/XC891004',
    'hoopoe/XC798809',
    'hoopoe/XC798808',
    'hoopoe/XC798807',
    'hoopoe/XC798806',
    'hoopoe/XC798805',
    'eaywag1/XC835367',
    'orihob2/XC762524',
]

2.6 掚論の高速化

IntelのOpenVINOずいうオヌプン゜ヌス゜フトを利甚するこずで、量子化、枝刈り(pruning)、分散化、ハヌドりェア(CPU,GPU等)の最適化などによっお掚論を高速化するこずができたす。
今回は出力のために5回モデルによる掚論(+アンサンブルモデルの掚論)を行う必芁がありたしたが、これを利甚するこずで掚論時間が玄40%短くなり、制限である120分以内の掚論を満たすこずができたした。

# converting models to openvino
def convert_pytorch_to_openvino(device):
    for fold_id in range(CFG.n_folds):
        # load model
        model_path = TRAINED_MODEL / f"best_model_fold{fold_id}.pth"
        model = BirdCLEF2024SpecModel(
            model_name=CFG.model_name, pretrained=False, num_classes=CFG.N_CLASSES, in_channels=1
        )
        model.load_state_dict(torch.load(model_path, map_location=device))
        model.eval()
        # export to onnx
        torch.onnx.export(model,
                      CFG.DUMMY_INPUT_TENSOR,
                      CFG.OUTPUT_DIR_ONNX / f"fp32_fold{fold_id}.onnx",
                      opset_version=15,
                      input_names=['input'],
                      output_names=['output']
        )

        # convert model to openvino
        ov_model = ov.convert_model(CFG.OUTPUT_DIR_ONNX / f"fp32_fold{fold_id}.onnx",
                                input=[('input', CFG.INPUT_SHAPE)],)
        # save model
        ov.save_model(ov_model, CFG.OUTPUT_DIR_OV / f"fp32_fold{fold_id}.xml", compress_to_fp16=False)
        
convert_pytorch_to_openvino(device=torch.device(CFG.device))

3. 䜕が機胜しなかったか

・画像のmixup
・メルスペクトログラム以倖の画像による孊習

4. 環境

コンペ党䜓を通しお、KaggleのGPU(P100)を䜿甚しおいたした。
性胜:
・RAM 32GB
・VRAM 16GB
制限:
・週30時間たで
・同時に起動できるのは1぀たで

5. たずめ

本解法ではメルスペクトログラムを利甚した画像モデルず、OpenVINOによる掚論の高速化を䞻に利甚したした。
振り返りは以䞊になりたす。読んでいただきありがずうございたした

参考

[1] BirdCLEF 2024, Kaggle

Discussion