このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
Fixstars Autonomous Technologiesの重岡です。2021/4-5月に実施されたKaggleのコンペティション(BirdCLEF2021)に参加して、銀メダル(816チーム中37位)を取得しました。本記事では、本コンペでの私の取り組みと、ランキング上位者の解法から得られた機械学習の技術、特にアンサンブル学習について紹介します。
KaggleはGoogleの子会社であり、2010年に設立されたデータサイエンティストと機械学習のオンラインコミュニティを運営しています。Kaggleのコミュニティでは、企業や大学の主催者がデータセットと学習モデルの開発環境を提供しており、データサイエンスの課題を解決するためのコンペティションに参加できます。
BirdCLEF (The LifeCLEF Bird Recognition Challenge)は、鳥の鳴き声を含む環境音データを入力とした、鳥の鳴き声を分類する学習モデルを作成し、その分類精度を参加者同士で競い合うコンペティションです。
コーネル大学鳥類学研究所が主催、Google Research、LifeCLEF、xeno-cantoと協力して、2021/4-5月の2か月間で実施されました。鳥類は食物連鎖の上位にいるため、環境音データから鳥の鳴き声を高精度に分類できるようになると、生態系の状況を正確に追跡でき、環境汚染のよい指標として扱えるようになります。
与えられた環境音データを5秒ごとに区切り、その区切り(以下、セグメント)ごとの鳴き声をマルチラベリングします。鳥の分類は397種類であり、鳥が鳴いていないセグメントは”nocall”として該当なしのラベルを付与します。以下に、作成する学習モデルの入出力を示した図を記載します。
鳴き声のタイミングを出力せずに鳴き声の分類のみを出力するタスクを、AudioTaggingと呼びます。一方、鳴き声の分類と共に鳴き声の開始/終了タイミングも出力するタスクを、SoundEventDetection(SED)と呼びます。以下に、AudioTaggingとSEDの出力を比較した図を示します。
セグメントを1枚の画像、時刻を座標位置と見立てると、AudioTaggingとSEDは、画像処理タスクにおける画像認識(ImageRecognition)とオブジェクト検出 (ObjectDetection)の関係に類似しています。
BirdCLEF2021では、鳥の鳴き声のタイミング検出にSEDではなく、5秒ごとのセグメントのAudioTaggingを用います。この理由は、xeno-cantという鳥の鳴き声の共有Webサイトから生成した、AudioTaggingのデータセットを使用するためです。 以下に主催者から用意されるデータを列挙します。
項目 | 説明 |
primary_label | 環境音データでメインとなる鳥の分類 |
secondary_labels | 環境音データに含まれるprimary_label以外の鳥の分類 |
type | ”primary_label”の鳴き声の種類 (“song”: さえずり, “call”: 地鳴り 等) |
latitude | 録音した緯度 |
longitude | 録音した経度 |
scientific_name | “primary_label”の学名 |
common_name | “primary_label”の一般名 |
author | xeno-cantoでの投稿者名 |
date | 録音した年月日 (yyyy-mm-dd) |
filename | 環境音データのファイル名 |
license | ライセンス名 (全て Creative Commons Attribution-NonCommercial-ShareAlike 3.0) |
rating | xeno-cantoでのレーティング (0.0~5.0) |
time | 環境音データの長さ (分:秒) |
url | xeno-cantoのWebURL |
本コンペでは、参加者が提出した学習モデルにTestデータが入力され、セグメントごとのmicro F1-Scoreの平均を評価指標としてスコアが算出されます。
前節に記載したように、 BirdCLEF2021では鳴き声のタイミングを出力するタスクであるにもかかわらず、 SEDではなくAudioTaggingのデータセットを使用します。このように、目的の出力に対して不完全なデータセットを使用した学習を弱教師あり学習と呼びます。本課題で高スコアを取りづらくするTrainデータの問題点を、弱教師あり学習であるという点に着目して以下にまとめます。
BirdCLEFでは”ドメイン不一致”および”ノイズあり”が問題となり、RNN (Recurrent Neural Network)のような音声データの時系列処理では音声の検出/分類精度が低くなります。そのため、今回の参加者の多くは、音声データをメルスペクトグラムと呼ばれる X軸: 時刻、Y軸: 周波数、ピクセル値: その時刻、周波数でのゲインとする2次元画像に変換し、そのメルスペクトグラムの画像認識 (ImageRecognition) を用いてAudioTaggingをしています。
また、より高スコアを取得するためには、ドメインシフトを対策した学習データの構築、およびメタデータを使用した分類精度の向上をする必要があります。
以下に、私の解法での学習パイプラインを示します。私の解法は3つの学習モデルのアンサンブル学習となっています。鳴き声の分類精度向上のために、ValidationデータはTrainデータと比べて異常なノイズデータがない点に着目し、教師無しの外れ値検出を用いて Trainデータ からノイズの大きい環境音データを除去しています。これにより、Trainデータのノイズを主催者のValidation/Testデータと合わせられるため、鳴き声の分類性能を向上できました。
使用するモデルは以下の3種類です。
1つ目のPANNsのモデルは、AudioSet (オーディオ分野のImageNet)でPreTrainされたモデルを転移学習して生成した音声認識のモデルです。畳み込み層をdensenet121としたモデルを使用し、以下の2通りの学習データによるモデルを作成しました。
Train+Validationデータ(異常データ除去)の”改善1 異常データ除去”では、ヒストグラムベースの教師無し外れ値検出 HBOSを用いて異常なノイズデータを除去します。また、”改善2 環境ノイズの追加”として、TrainデータにValidationデータと同等の環境ノイズを追加します。環境ノイズとしてESC-50と呼ばれる環境音分類用の外部データセットを使用して、車両/飛行機/雨/風/虫/犬の環境ノイズを追加しました。これはValidationデータの音声を実際に確認したところ、市街地や道路沿いなど人間の生活圏内で録音された環境音が多かったためです。
2つ目のResNext101のモデルは、今回の1位解法でも使用されている学習スクリプトで作成されており、検証データ(OutOfFold)で生成したモデルの予測確率が高いセグメントを優先して学習します。このような特徴を持つモデルをアンサンブルすることで分類精度の向上を図っています。
今回、私の手法では3モデルのアンサンブル学習としてバギングを使用しました。アンサンブル学習には、有名な手法としてブースティングおよびバギングの2つがあります。以下に、これら2手法の役割を図示します。今回の課題は分類問題ですが、説明が容易な回帰問題を用いて説明します。
ブースティングは単純なベースモデルを作成し、その推論値と正解値との誤差を学習するモデルを繰り返し構築する手法です。構築したモデルの推論値に学習率と呼ばれる定数値を掛けた上でベースモデルの推論値に積算し、正解データとより誤差が小さい推論値を出力します。つまり、ブースティングではバイアス(正解値と推論値との誤差)を小さくできます。一方、バギングは、複数の学習モデルの推論値の平均(もしくは多数決)を出力することで、学習モデルごとの過学習による誤差を小さくします。つまり、バギングではバリアンス(学習データの選択による推論値の変動)を小さくできます。推論時間の高速化ではなく推論精度の勝負が多いKaggleコンペでは、ブースティングとバギングを合わせてよく使用されます。
高スコア取得に不足していた対策を明確にするために、学習データの4つの問題点ごとに、私の対策と上位者の対策を比較します。各項目の説明は省略しますが、上位者の解法と比べて私の解法で未対策の問題点は、”ドメインシフト”および”メタデータの使用”の2点であることが分かりました。
問題点 | 私の対策 | 1位解法の対策 | 2位解法の対策 |
ドメイン不一致 | 1. メルスペクトグラムを入力とする鳴き声分類器 (PANNs+densenet121, resnext101_32x8d_wsl) | 1. メルスペクトグラムを入力とする鳴き声分類器 (resnest50) | 1. メルスペクトグラムを入力とする鳴き声分類器 (resnet34、tf_efficientnetv2_s_in21k、tf_efficientnetv2_m_in21k、eca_nfnet_l0) |
ノイズあり | 2. 誤ラベル除去 3. 環境ノイズ追加 4. モデルのバギング | 2. label smoothingによる無音声/ノイズの過学習防止 3. nocallの2項検出器 (鳴き声分類の学習損失を重みづけに使用) 4. LightGBMによる鳴き声分類の正解判定 | 2. label smoothingによる無音声/ノイズの過学習防止 3. 環境ノイズ追加 4. モデルのバギング 5. セグメントごとの予測確率の調整 (環境音データでの鳥ごとの平均予測確率、隣接するセグメントの予測確率を使用) |
ドメインシフト | なし | 5. nocallの2項検出器 (LightGBMの正解データ作成に使用) | 6. nocallの2項検出器 7. ブートストラップ法によるTrainデータからTestデータを再現 |
メタデータの使用 | なし | 6. LightGBMによるメタデータの学習 | 8. レーティング情報による鳴き声分類の学習損失を重みづけ 9. 場所/時間を元にありえない予測の削除 |
まず、”ドメインシフト”の対策について説明します。1, 2位の解法ともにTestデータの全セグメントを”nocall”とラベリングした場合、micro F1 ScoreがValidationデータよりTestデータで大きくなること、つまりTestデータのnocall率が大きいというドメインシフトがあることに気づいたと述べています。この対策として、1位解法では鳴き声の分類と”nocall”の分類は別課題であると考えて、外部データセット(freefield1010)を用いて”nocall”の2項分類器を構築しています。また2位の解法では、ブートストラップ法によりTrainデータをサンプリング抽出して、Testデータの”nocall”および鳥の種類の割合を再現したデータを用いて学習モデルを評価しています。
次に”メタデータの使用”については、1位解法ではLightGBMと呼ばれる決定木アルゴリズムにメタデータを入力として、鳴き声分類器の出力ラベルが正解である確率を予測しています。また、2位解法では環境音データのレーティングを元に鳴き声分類器の学習損失を重みづけて、過学習とならないようにしています。
次節では1位解法でのLightGBMによるバイアス削減について詳述します。
1位の解法で使用されているLightGBMは勾配ブースティングのフレームワークであり、C/Python/R言語で使用することができます。LightGBMは、ブースティング (“私の解法”の節に記載)における誤差の学習モデルに決定木を使用し、その決定木の学習にGOSS(Gradient-based One-Side Sampling)、およびEFB(Exclusive Feature Bundling)と呼ばれる計算量が小さくかつ高速なアルゴリズムを使用しています。欠損データを含む学習データの特徴量をそのまま入力しても高精度に分類ができる、またその特徴量の重要度を出力できるなどの理由から、Kaggleコンペではテーブルデータの特徴量を入力とする分類問題でよく使用されます。
1位の解法では、以下のような推論パイプラインを用いて、セグメントごとの鳥の鳴き声をマルチラベリングします。
まず、環境音データをメルスペクトグラムの画像に変換し、その画像を鳴き声分類器の入力とします。鳴き声分類器からは確率テーブル(セグメント数×397種類)を生成し、その確率テーブルおよびメタデータの情報から、27個の特徴量を計算します。これらの特徴量は、各セグメントごとに予測確率が高い上位5種類の鳥について計算されます。
以下に、特徴量を列挙します。メタデータからそのまま取得した特徴量、およびドメイン知識から自作した特徴量(特徴量エンジニアリング)で構成されていて、LightGBMにおける特徴量の重要度を元に選定されています。
項目 | 説明 |
bird_id | 対象の鳥(“nocall”確率が閾値以上ではない場合) |
year | 録音した年 |
month | 録音した月 |
seconds | セグメントの開始秒数(5ごと) |
latitude | 録音した緯度 |
longtitude | 録音した経度 |
sum_prob | 確率テーブル: 397種類の推論確率和 (セグメントごと) |
mean_prob | 確率テーブル: 397種類の推論確率平均 (セグメントごと) |
max_prob | 確率テーブル: 397種類の推論確率最大 (セグメントごと) |
prev6_prob~prev_prob | 確率テーブル: 前6セグメント までの対象の鳥が鳴いている確率 |
prob | 確率テーブル: 現セグメントで鳥が鳴いている確率 |
next_prob~next6_prob | 確率テーブル: 後6セグメント までの対象の鳥が鳴いている確率 |
rank | 確率テーブル: 対象の鳥について、397種類中の確率の大きさ順位 |
num_appear | 学習データ内で対象の鳥がprimary_labelである音声データ数 |
site_num_appear | 推論するSiteの学習データ内で、対象の鳥が鳴いている音声データ数 |
site_appear_ratio | 対象の鳥について、推論するSiteでの音声データ数の割合 (site_num_appear / num_appear) |
prob_diff | 確率テーブル: 3セグメント(prev_prob, prob, next_prob)の確率平均からprobの確率を引いた値 |
パイプラインの末尾ではLightGBMを用いて、入力特徴量(27個)を元に各セグメントで鳴き声分類器のラベリングが正解である確率(0.0~1.0)を出力します。この正解の確率をLightGBMが学習するために、”nocall”の2項分類器が出力するnocall確率およびTrainデータの正解ラベルを組み合わせて生成したセグメントごとの正解ラベルを使用します。
Kaggle BirdCLEF2021のコンペティションで銀メダルを取得しました。本稿では、まず自分の解法である異常な学習データ除去について説明し、上位の解法との比較を記載しました。この解法の比較により、ドメインシフト対策とメタデータの使用によるバイアス削減が、自分の解法に不足していることが分かりました。そのため、1位の解法が用いたLightGBMによるバイアス削減を調査し、その概要を説明しました。
本コンペには、Fixstars全社の有志で活動しているKaggleグループの取り組みとして参加しました。Kaggleグループではチームを組んでコンペに参加したり、またソロでのコンペ結果をグループ内で報告したりして、機械学習の技術力向上に努めています。
keisuke.kimura in Livox Mid-360をROS1/ROS2で動かしてみた
Sorry for the delay in replying. I have done SLAM (FAST_LIO) with Livox MID360, but for various reasons I have not be...
Miya in ウエハースケールエンジン向けSimulated Annealingを複数タイルによる並列化で実装しました
作成されたプロファイラがとても良さそうです :) ぜひ詳細を書いていただきたいです!...
Deivaprakash in Livox Mid-360をROS1/ROS2で動かしてみた
Hey guys myself deiva from India currently i am working in this Livox MID360 and eager to knwo whether you have done the...
岩崎システム設計 岩崎 満 in Alveo U50で10G Ethernetを試してみる
仕事の都合で、検索を行い、御社サイトにたどりつきました。 内容は大変参考になりま...
Prabuddhi Wariyapperuma in Livox Mid-360をROS1/ROS2で動かしてみた
This issue was sorted....