Upgrade to Pro — share decks privately, control downloads, hide ads and more …

KaggleのChild Mind Institute - Detect Sleep Stat...

Avatar for nnc_5522 nnc_5522
January 02, 2026
9

KaggleのChild Mind Institute - Detect Sleep Statesで銀メダルとった時の振り返り

Avatar for nnc_5522

nnc_5522

January 02, 2026
Tweet

Transcript

  1. 問題設定 • 手首につけた計測器からデータから入眠(onset)と起床(wakeup)を予測する • データセット ◦ データの属性 ▪ series_id: 各データの識別用unique_id

    ▪ step: ステップ数 ▪ enmo : 加速度(のようなもの) ▪ anglez : 地面への垂線との角度 ▪ timestamp: 時刻 ◦ テストデータは約200series_id(public25%, private75%) • 評価指標:許容誤差ごとのaverage precision を各series_idで計算して平均をとる 3
  2. キーポイント • 周期的な部分の予測は除去することでスコアがあがった ◦ 上位陣はほぼほぼ対処してる ◦ ただこの周期的な部分にもラベルがついてるものもある • ラベルノイズ ◦

    ついているべきと思われる箇所についていなかった ▪ ハンドラベリングすることでスコアがあがった ◦ 細かく見るとラベルが波形データ上では若干ずれてそう ▪ 修正したけどこっちはスコア上がらず ▪ おそらくテストデータにもラベルのズレはある 6 画像引用: 34th solution
  3. 自チームのソリューション(34th) public: 0.744(88th), private: 0.803(34th) • 17model ensemble(ちばpart) ◦ 2D

    Unet ▪ FeatureExtractor: 1D CNN ▪ Encoder: Unet ▪ 1D-Unet: Decoder ◦ detaset(チームメイトpart) ▪ ラベルがついてるべき場所につけたもの(v1119) ▪ ラベルノイズを修正したもの(v1130) ◦ loss: BCEWithLogits / FocalLoss • sliding inference ◦ duration // 2ずつずらして予測 ◦ 長さdurationの各チャンクの両端offset=500分は予測に使わない(duration-2*offset分の予測値 のみ使う) • 後処理(チームメイトpart) ◦ 周期的な部分の予測結果を除去 7
  4. 自チームのソリューション Feature Extractor • 系列データを畳み込んでWavegramを作成する ◦ 使った特徴量は以下の値 ▪ enmo ▪

    angleze ▪ hour sin ▪ hour cos ◦ clipして正規化とclipしてないデータで学習したモデルを作成 ▪ clipして正規化はenmoの値に外れ値が見られるため追加(スコア微 増) 8
  5. 自チームのソリューション Encoder • 2D Unet ◦ inputにwavegramをとる ◦ 初めはsegmentation_model_pytorchを使っていたがカスタムしたも のに変更した

    ◦ Unetのencoderにtimmから以下のモデルを使った ▪ eca_nfnet_f1 ▪ dm_nfnet_l0 ▪ maxvit_rmlp_tiny_rw_256.sw_in1k(single model best) 9
  6. 自チームのソリューション Sliding Inference • 予測区間を半分ずつずらしながら予測 ◦ 仮説:区間の端(特に左端)は予測に使える情報が真ん中より少ないはず=信頼度が低い ◦ score +=

    0.01 ◦ 更に両端の500step分を予測範囲から除外することで更にスコア微増 ▪ score += 0.005 • ensemble ◦ 各区間に各モデルで予測 →対応する区間に加算 →モデル数で割ることで平均を出す ◦ あらかじめチャンク数*(duration//2)で予測したい区間を定義しておく 11
  7. 自チームのソリューション クラス不均衡対策 • gaussian target ◦ soft labelとしてラベルを正規分布にする • label

    smoothing on sleep label ◦ 学習用に追加してるsleep classに対してソフトラベルにする • augmentation ◦ mixup on wavegram ◦ spec_augment on wavegram 12
  8. 上位ソリューション 1st solution public: 0.790(3rd), private: 0.852(1st) • model: UNet

    + GRU ◦ single model: cv:0.8206, public: 0.768, private: 0.829 • 周期的な部分の除去 • postprocess ◦ public: 0.768->0.790, private: 0.829->0.852 13
  9. 上位ソリューション 1st solution • SEScale(https://arxiv.org/abs/1709.01507) ◦ 入力全体を見て畳み込みができる ◦ ボトルネック機構を使ってチャネル間に非線形な関係を入れる ◦

    CNNに簡単にSelf-Attention的な役割のコンポーネントを追加 ◦ 追加時には計算量は1%以下の増加に抑えれる ◦ 参考: ▪ https://qiita.com/daisukelab/items/0ec936744d1b 0fd8d523 15
  10. 上位ソリューション 1st solution • Minute Connection ◦ タスクが1分のずれを競うものなので時間のエンコーディングを入れてる ◦ 単に入れるのじゃなくて最終層に入れてる

    ▪ 最後に少し調整するイメージ? ◦ データセットの時間方向へのバイアスの対処 ▪ 00秒じゃなくて微妙にずれたものがあった 16
  11. 上位ソリューション 1st solution features • categorical features ◦ hour ◦

    minute ◦ weekday (曜日) ◦ periodicity flag (周期的データかどうかのフラグ) • numerical features ◦ anglez / 45 ◦ (enmo.log1p() / 0.1).clip_max(10.0) ◦ anglez, enmo 12 steps rolling_mean, rolling_std, rolling_max ◦ anglez_diff_abs 5 min rolling median 18
  12. 上位ソリューション 1st solution Change logs (1st solutionから引用) • baseline model

    (cv: 0.7510) - public: 0.728 • Add a process to decay the target every epoch (cv: 0.7699, +19pt) • Add a periodicity filter to the output (cv: 0.7807, +11pt) • Add a periodicity flag to the input as well (cv: 0.7870, +6pt) - public: 0.739 • batch_size: 16 → 4, hidden_size: 128 → 64, num_layers: 2 → 8 (cv: 0.7985, +11pt) - public: 0.755 • Normalize the score in the submission file by the daily score sum (cv: 0.8044, +6pt) • Remove month and day from the input (cv: 0.8117, +7pt) • Trim the edges of the chunk by 30 minutes on both sides (cv: 0.8142, +4pt) - public: 0.765 • Modify to concatenate the minute features to the final layer (cv: 0.8206, +6pt) - public: 0.768 19
  13. 上位ソリューション 1st solution • 整理 ◦ 元のモデルはソフトラベル使ってある区間にイベントがあるように学習 していた ◦ 予測は0,

    5, 10, 15, …と5秒ごとにイベントの起きる確率をそれぞれ 予測 ◦ ラベルは00秒単位で付与されてる ◦ 評価指標は30秒以内のずれでは精度は不変 22
  14. 上位ソリューション 1st solution • 同じ分数の中であればどの秒数でもスコアが変わらない • 15秒と45秒時点でのスコアを推定して、最も高い値を選ぶ • スコアの再計算をする ◦

    効果的な範囲に予測が残るように間引いていく ◦ これを許容誤差範囲ごとに繰り返す ◦ 残った予測をサブに追加する ◦ 詳細は1st solution ▪ 正直難しくて詳細を理解できてない 24
  15. 上位ソリューション 2nd solution public: 0.799(1st), private: 0.850(2nd) • 3stage pipeline

    ◦ 1. Event Detection 1D-Unet & Peak Detection ◦ 2. 制約を考慮した最適化とRescoring ◦ 3. offset predictで数ステップずらしたものにscoreつけてWBF 25
  16. 上位ソリューション 2nd solution • 2nd Stage ◦ 1日にonset/wakeupは1回ずつしか起きない制約がある ◦ 1st

    stageのモデルはこれを考慮できてない ◦ NNはメタ的な特徴や長い周期性のある特徴の扱いがうまくない ◦ 以上の理由から補正した最適化をするためにGBDTを使う 29
  17. 感想・振り返り • 実装のメインは自分、データを見るのはチームメイトで分けたのが時間がない中でハマった • 可視化とデータセットをよく見るとはどういうことかを実感した ◦ ミクロとマクロ両方でみる必要がある ◦ 他の人も ◦

    わかりやすくする何を可視化してるのかのロジックはちゃんと説明できるようにする • 実験管理は面倒でもちゃんとやる ◦ 仮説と対策はセットだけどまとめて検証しない ▪ 一つ一つ情報としてしっかり確定させる ▪ 試したことを振り返れるようにしておく ◦ どれが効いたのかから更に有効な仮説の方向性が絞れる • 評価指標・データセットの理解大事 ◦ 上位との差は評価指標を理解してるかの部分も大きい • モデリングでの差 ◦ SEDアプローチの前に育ててた方ももっと取り組めば伸び代あったかも ▪ ResidualGRN, Skip Connected Transformer ◦ わかりやすく情報をNNに与える(clip -> 正規化) 参考記事: Medium, モデルの気持ちになって情報を与えよう, Jun Koda 33
  18. 課題 • 仮説構築力 ◦ 何をやるのか、裏側にあるロジックは何か • データ可視化 ◦ わかりやすい可視化によって課題に気付く確率が上がる ◦

    細かくみるミクロな可視化と俯瞰でみるマクロな可視化 • 実験管理 ◦ 説明性 ▪ 検証する仮説は何か?、検証方法、結果からの解釈 ◦ 効率化 ▪ キャッシュ、中間状態をファイルに書き出す ◦ 高速化 ▪ compile, amp, num_workers=8, etc • デバッグ力 ◦ うまく行かない時にどこが怪しいのか特定する(特にコードがバグを吐いてない時) • モデリング力 ◦ 上位層との決定的な差、モデル一つ学習させるのでもスコアで0.02くらい差がついてる 34