Slide 1

Slide 1 text

睡眠コンペ振り返り 2023/12 ちば

Slide 2

Slide 2 text

背景 ● このコンペのソリューションで研究者が計測器のデータからより睡眠についての研究 を進める手助けとしより個別最適化された睡眠をサポートするような研究開発につ なげていきたい ● 子供の手首につけたリストバンド型の計測器をもとにアノテータが入眠と起床がおき た時点を判断しているがコストがかかる ● アノテータがつけたアノテーションを元にしたデータセットで機械学習を使うことで自 動化する 2

Slide 3

Slide 3 text

問題設定 ● 手首につけた計測器からデータから入眠(onset)と起床(wakeup)を予測する ● データセット ○ データの属性 ■ series_id: 各データの識別用unique_id ■ step: ステップ数 ■ enmo : 加速度(のようなもの) ■ anglez : 地面への垂線との角度 ■ timestamp: 時刻 ○ テストデータは約200series_id(public25%, private75%) ● 評価指標:許容誤差ごとのaverage precision を各series_idで計算して平均をとる 3

Slide 4

Slide 4 text

キーポイント ● クラス不均衡 ○ 1日17280step(1step/5sec)のうちラベル(onset/wakeup)がついてるのは最低でも2step ○ 一つのseries_idに対して約1ヶ月分のデータ(30 * 17280)に対して期待されるラベルの数は60step ■ 後述するが欠損やラベルノイズが多々あるので120stepもない ○ ナイーブにやると簡単に過学習する 4

Slide 5

Slide 5 text

キーポイント ● データに不自然な周期的な箇所があった ○ (多分)データが計測されてない区間があるのをホストが平均値を使って埋 めてる 5 1日単位(17280step) での繰り返しが見られる 画像引用: 34th solution

Slide 6

Slide 6 text

キーポイント ● 周期的な部分の予測は除去することでスコアがあがった ○ 上位陣はほぼほぼ対処してる ○ ただこの周期的な部分にもラベルがついてるものもある ● ラベルノイズ ○ ついているべきと思われる箇所についていなかった ■ ハンドラベリングすることでスコアがあがった ○ 細かく見るとラベルが波形データ上では若干ずれてそう ■ 修正したけどこっちはスコア上がらず ■ おそらくテストデータにもラベルのズレはある 6 画像引用: 34th solution

Slide 7

Slide 7 text

自チームのソリューション(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

Slide 8

Slide 8 text

自チームのソリューション Feature Extractor ● 系列データを畳み込んでWavegramを作成する ○ 使った特徴量は以下の値 ■ enmo ■ angleze ■ hour sin ■ hour cos ○ clipして正規化とclipしてないデータで学習したモデルを作成 ■ clipして正規化はenmoの値に外れ値が見られるため追加(スコア微 増) 8

Slide 9

Slide 9 text

自チームのソリューション 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

Slide 10

Slide 10 text

自チームのソリューション Decoder ● 1D-Unet ○ 前段のencoderを受け取って、系列の予測を出す ○ どのステップでどのイベントが起きてる確率が起きてるのが高いのか ■ segmentationっぽい感じ ○ ここでは特に工夫できずベースラインのまま 10

Slide 11

Slide 11 text

自チームのソリューション Sliding Inference ● 予測区間を半分ずつずらしながら予測 ○ 仮説:区間の端(特に左端)は予測に使える情報が真ん中より少ないはず=信頼度が低い ○ score += 0.01 ○ 更に両端の500step分を予測範囲から除外することで更にスコア微増 ■ score += 0.005 ● ensemble ○ 各区間に各モデルで予測 →対応する区間に加算 →モデル数で割ることで平均を出す ○ あらかじめチャンク数*(duration//2)で予測したい区間を定義しておく 11

Slide 12

Slide 12 text

自チームのソリューション クラス不均衡対策 ● gaussian target ○ soft labelとしてラベルを正規分布にする ● label smoothing on sleep label ○ 学習用に追加してるsleep classに対してソフトラベルにする ● augmentation ○ mixup on wavegram ○ spec_augment on wavegram 12

Slide 13

Slide 13 text

上位ソリューション 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

Slide 14

Slide 14 text

上位ソリューション 1st solution ● CMSS GRUNET Trainに基づいたアーキテクチャ構成 14 画像はCMSS GRUNET Trainから引用

Slide 15

Slide 15 text

上位ソリューション 1st solution ● SEScale(https://arxiv.org/abs/1709.01507) ○ 入力全体を見て畳み込みができる ○ ボトルネック機構を使ってチャネル間に非線形な関係を入れる ○ CNNに簡単にSelf-Attention的な役割のコンポーネントを追加 ○ 追加時には計算量は1%以下の増加に抑えれる ○ 参考: ■ https://qiita.com/daisukelab/items/0ec936744d1b 0fd8d523 15

Slide 16

Slide 16 text

上位ソリューション 1st solution ● Minute Connection ○ タスクが1分のずれを競うものなので時間のエンコーディングを入れてる ○ 単に入れるのじゃなくて最終層に入れてる ■ 最後に少し調整するイメージ? ○ データセットの時間方向へのバイアスの対処 ■ 00秒じゃなくて微妙にずれたものがあった 16

Slide 17

Slide 17 text

上位ソリューション 1st solution ● dataset ○ 各チャンクは1日分のstep数(17280)で0.35日分ずつずらす ○ targetはgaussian ■ 裾野にいくにつれ値が低くなるようなsoft label ○ 特徴量は次ページ 17

Slide 18

Slide 18 text

上位ソリューション 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

Slide 19

Slide 19 text

上位ソリューション 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

Slide 20

Slide 20 text

上位ソリューション 1st solution ● PostProcess ○ データの特徴を把握して、それに対する対策 ○ public: 0.768->0.790, private: 0.829->0.852 ○ 優勝の決め手 20

Slide 21

Slide 21 text

上位ソリューション 1st solution ● データの特徴 ○ labelがつけられてる箇所の秒数部分は常に0 ○ 評価指標が30秒未満のずれはスコアが不変 21 画像は1st solutionから引用

Slide 22

Slide 22 text

上位ソリューション 1st solution ● 整理 ○ 元のモデルはソフトラベル使ってある区間にイベントがあるように学習 していた ○ 予測は0, 5, 10, 15, …と5秒ごとにイベントの起きる確率をそれぞれ 予測 ○ ラベルは00秒単位で付与されてる ○ 評価指標は30秒以内のずれでは精度は不変 22

Slide 23

Slide 23 text

上位ソリューション 1st solution ● 二つ目のモデルとして、区間内の予測を秒数0に集約するモデルを学習する ● イベントが起きた周辺の特徴量の集約を入力として正確にイベントが起きた 時を1それ以外を0として学習する 23

Slide 24

Slide 24 text

上位ソリューション 1st solution ● 同じ分数の中であればどの秒数でもスコアが変わらない ● 15秒と45秒時点でのスコアを推定して、最も高い値を選ぶ ● スコアの再計算をする ○ 効果的な範囲に予測が残るように間引いていく ○ これを許容誤差範囲ごとに繰り返す ○ 残った予測をサブに追加する ○ 詳細は1st solution ■ 正直難しくて詳細を理解できてない 24

Slide 25

Slide 25 text

上位ソリューション 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

Slide 26

Slide 26 text

上位ソリューション 2nd solution ● 全体概要 26 画像は2nd Place Solutionから引用

Slide 27

Slide 27 text

上位ソリューション 2nd solution 27 画像は2nd Place Solutionから引用

Slide 28

Slide 28 text

上位ソリューション 2nd solution 28 画像は2nd Place Solutionから引用

Slide 29

Slide 29 text

上位ソリューション 2nd solution ● 2nd Stage ○ 1日にonset/wakeupは1回ずつしか起きない制約がある ○ 1st stageのモデルはこれを考慮できてない ○ NNはメタ的な特徴や長い周期性のある特徴の扱いがうまくない ○ 以上の理由から補正した最適化をするためにGBDTを使う 29

Slide 30

Slide 30 text

上位ソリューション 2nd solution 30 画像は2nd Place Solutionから引用

Slide 31

Slide 31 text

上位ソリューション 2nd solution 31 画像は2nd Place Solutionから引用

Slide 32

Slide 32 text

上位ソリューション 2nd solution 32 画像は2nd Place Solutionから引用

Slide 33

Slide 33 text

感想・振り返り ● 実装のメインは自分、データを見るのはチームメイトで分けたのが時間がない中でハマった ● 可視化とデータセットをよく見るとはどういうことかを実感した ○ ミクロとマクロ両方でみる必要がある ○ 他の人も ○ わかりやすくする何を可視化してるのかのロジックはちゃんと説明できるようにする ● 実験管理は面倒でもちゃんとやる ○ 仮説と対策はセットだけどまとめて検証しない ■ 一つ一つ情報としてしっかり確定させる ■ 試したことを振り返れるようにしておく ○ どれが効いたのかから更に有効な仮説の方向性が絞れる ● 評価指標・データセットの理解大事 ○ 上位との差は評価指標を理解してるかの部分も大きい ● モデリングでの差 ○ SEDアプローチの前に育ててた方ももっと取り組めば伸び代あったかも ■ ResidualGRN, Skip Connected Transformer ○ わかりやすく情報をNNに与える(clip -> 正規化) 参考記事: Medium, モデルの気持ちになって情報を与えよう, Jun Koda 33

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

まとめ ● 34thで銀メダル🥈 ● データの周期性・ラベルノイズがキーポイント ● キーポイントの対策の手札の差とモデリングの差が上位層との差 35