まだタイトルない

アウトプット用です

【Kaggle挑戦記】鳥コンペ銅メダル取組内容【#3】

f:id:teyoblog:20200917234404p:plain:w150
こんにちは

kaggle登録して3回目のコンペに参加してきました。

Cornell Birdcall Identification

結果はpublic53位→private127位/1395で上位10%の銅メダルフィニッシュです。
publicが銀圏内だっただけにshake downでの銅は悔しいものがありますが、上位解放と比べると工夫ができてないのでまだまだ精進が必要です。

さて、今回コンペについて、取組内容と感想を書きたいのですが、一緒の投稿にすると見にくくなると思うので今回は取組内容について振り返っていきます。

違う畑の人や、興味のある人に、こういうことをやるんだなってことが伝われば幸いです。

コンペ概要

鳥の鳴き声を学習して、 与えられた音声データ内でどの種の鳥が鳴いているかを推定するタスクでした。
※今回の対象は264種類

何故するのか

コンペの概要欄によると

  • 世界には1万種以上の鳥が生息している
  • 熱帯雨林から都市部までほぼすべての環境に生息している
  • 鳥は食物連鎖の上位に位置し、食物連鎖の下位で発生している変化の影響も反映される
    • 生息地の質の低下や環境汚染の指標として優秀な調査対象
  • 鳥の生息状況の確認は目視より耳で聞くほうが簡単な場合が多い
  • 音の検出と分類ができるとその地域の変化の要因を把握することにつながる

ということで鳥の鳴き声をうまく認識できることは副効果がかなり大きいようです。

音声データへのアプローチ

画像に変換する

音声データの機械学習はまず画像に変換して画像分野の手法を用いることが多いです。
スペクトログラムや、メルスペクトログラムなどがあります。 いずれも縦軸に周波数、横軸に時間を取ります。

イメージとしては1枚目の画像のような波形を2枚めのような画像にします。
f:id:teyoblog:20200917232740p:plain:w300

f:id:teyoblog:20200917232822p:plain:w300

音声のまま

画像にしないでそのままつかうアプローチもあるようですが、勉強不足なため割愛します。

所感

  • メルスペクトログラムは人の聴覚に合わせたスケールを用いた変換なので、このスケールをカスタムして鳥の鳴き声の周波数帯を広く捉えられる画像に変換するのも手かと思いました。
  • いかに鳥が鳴いている部分を使って学習するかということのほうが重要だったかもしれません。

コンペのポイント

  • すべてnocallで提出すると0.544になる
    • nocallかどうかを判別するためのモデルを作るの手
      • 私達はしきい値でnocallは割と出現するので特に対策はしませんでした。
  • trainデータとtestデータで背景音やノイズの大きさが違う
    • 与えられたsample testデータを聞く限りtestデータのほうがノイズが大きいようでした
      • 後述しますがノイズを加えたり、逆にでノイズするアプローチが考えられます

solution

それでは最終的な私達のsolutionを書いていきます。
基本的には公開notebookをベースにさせていただきました。
www.kaggle.com

waveform transform

まずは音声データ状態でDataAugmentをします。 参考サイト
qiita.com

ノイズについては、testデータとtrainデータの波形と画像を見比べながらどれくらい加えるか判断しました。

このような変化をします。3つの変換を確率的に行うため、8種類の処理方法が生まれます。 f:id:teyoblog:20200917233352p:plain

画像変換

音声データをメルスペクトログラムに変換します。

Mixup

  • ランダムでもう一つ音源をピック
  • 上記waveformtransformを行う
  • メルスペクトログラムに変換
  • mixする

メンバーが作成したため参考サイトがわかりません...

f:id:teyoblog:20200917233936p:plain

SpecAugment

比較的新しい音声認識におけるデータ拡張方法ということで採用。
時間軸、周波数軸に沿ってマスクを掛けます。

qiita.com

f:id:teyoblog:20200917234106p:plain

まとめ

以上が主な処理です。なんとまぁ単純。 その他設定を下記に記します

  • model
    • resnest50_fast_1s1x64d
  • loss
    • BCEWithLogitsLoss
  • optimizer
    • AdamP(lr:0.001)
  • scheduler
    • CosineAnnealingLR(T_max:10)
  • DataAugment
    • waveform
      • add whitenoise noise(p=0.5)
      • shift(p=0.5)
      • stretch(p=0.5)
    • mixup
    • Specaugment
  • fold
    • StratifiedKFold(n_splits=5)
  • melspectrogram parameters
    • n_mels: 128
    • fmin: 20
    • fmax: 16000
  • image size: 224x547

最終的には5fold文のモデルを作成しましたがその中からpublicで精度が出ていた3つをピックし、それがprivateの記録になっています。

試したけどだめだったもの

  • p=1でノイズを加える
    • testにノイズレベルを合わせるために行いました
    • testにも同じようにノイズをくわえたほうがまだ成績が良かった
  • denoise
    • testをtrainに近づけようと思って実験
  • TTA
    • 推論時にwavetransformを行って4つの推論結果をアンサンブルしてみましたが振るわず
  • efficientnet
    • 違うモデルで学習した結果とアンサンブルしようと思ったがあまりうまく学習できず
  • データを増やす
  • ESResNet,PANNs,SED
    • 実装できませんでした。
  • CV
    • 実装できませんでした。

おわり

以上になります。
間違った情報等ありましたら報告ください。記事のスタイルについてのアドバイスも貰えたら嬉しいです。

また、パイプラインを一枚図にするの憧れてるので後日トライしてみようと思います。