Kaggle「DFL – Bundesliga Data Shootout」で6位、Competitions Masterの称号を獲得しました

2023年2月8日

はじめに

2022年7月から10月にかけて開催されたKaggleコンペティション DFL – Bundesliga Data Shootout に弊社エンジニア3名のチームで参加し、530チーム中6位の成績を収めました。
この結果弊社チームに金メダルが与えられ、2名がKaggle Competitions Masterの称号を獲得しました。
本投稿ではコンペの概要と解法について紹介します。

コンペ概要

サッカーの試合を撮影した動画が与えられ、その中から特定のアクションが発生したタイミングおよび種別(プレイ、スローイン、チャレンジの3種類のいずれか)を識別するというタスクでした。

識別対象のアクション

  • プレイ
    • パスまたはクロス(フリーキックやコーナーキックも含む)等、チーム内でボールをやり取りするアクション
  • スローイン
    • ボールがゲームエリア外に出た後に手でボールを投げてプレイを再開するアクション
  • チャレンジ
    • 両チームのプレイヤーがボールを自分の制御下に置こうとする(ボールに対する競り合い、ファウル等)アクション

データセット

参加者には以下のデータセットが提供されました。
学習用ラベルとしてはアクションが発生したタイミングと種別等の最低限の情報が与えられていましたが、
各参加者が独自に追加のラベルを付与して学習することもルール上許容されていました。

  • 学習用動画
    • 8試合分のデータで構成され、その内4試合はフルゲーム、残り4試合はハーフゲームが含まれている
  • テスト用の動画
    • Public leaderboard用に1試合のフルゲームと4試合のハーフゲーム(学習用に含まれるものと同じ試合で学習用に含まれなかった片方のデータ)が含まれる
  • ラベル無し学習用動画
    • ラベルが付与されていない短い動画
  • 学習用ラベル
    • 学習用動画に対して、アクションが発生したタイミングを教示したデータ
    • 以下の属性で構成される
      • video_id: 動画のID
      • event: アクションの種別(プレイ、スローイン、チャレンジ)
      • event_attributes: 各アクションの追加属性
      • time: アクションが発生したタイムスタンプ (秒)

参加者が作成する必要がある推論コードでは以下の条件で予測を出力することが求められました。

  • 入力
    • mp4形式の動画
  • 出力 (以下をcsvフォーマットで出力)
    • video_id: 動画を識別するID
    • time: アクションが発生したタイムスタンプ (秒)
    • event: 発生したアクション種別 (play, throwin, challenge)
    • score: アクションの信頼度

精度評価指標

モデルの精度評価はコンペ独自のmean Average Precision(以下、mAP)が採用されました。
今回のコンペでのmAPの定義は以下の通りです。

  • ① アクションごとのAP: 各アクションごとに許容されるタイムスタンプのずれの閾値でAPを計算し、各閾値での結果を平均
  • ② 全体のAP: 3アクション分の①の結果を平均

ベースライン手法

Kaggleでは参加者がモデルの学習・推論コードをフォーラムに共有することが盛んに行われており、今回も参考になるコードがいくつか投稿されていました。
弊社チームではベースライン手法としてtitoさんの以下のNotebookを参考にさせていただきました。

ベースライン手法の概要は以下の通りです。

  • 入力動画の各フレームをそれぞれ4クラス(背景+ターゲット3クラス)のいずれかに識別するタスクとして学習・推論を実行
  • 推論時の後処理で時間方向にNMSを適用し、一定期間内の予測を1つに削減
  • モデルはEfficientNet B5を使用
  • 学習・推論フレームワークとしてPyTorchおよびtimmを使用

弊社チームの最終解法

基本的な考え方はベースライン手法に基づきつつ、時系列情報の活用およびコンペでよく利用される精度改善トリックの適用を実施しました。
またモデルの推論時間にも制約(testデータに対する予測を9時間以内に完了しなければならない)があったため、いくつか推論時間短縮の工夫も適用しています。
詳細なパラメータ設定等はKaggleのフォーラムに以下の記事を投稿していますので、もし興味がございましたらそちらも合わせてご参照ください。

A simple approach based on baseline notebooks (6th place solution)

時系列情報の活用

ベースラインモデルの精度を上げるためには時系列情報をどのようにモデルに組み込むかが課題となりました。
入力動画が与えられた際に時系列情報を活用したモデルを構築する方法はいくつか考えられますが、
弊社チームでは連続する3枚のフレームを2次元画像のチャンネル方向に結合する2.5次元CNNアプローチを最終的に採用しました。
処理の概要は以下の通りで非常にシンプルな方法ですが、今回のタスクでは比較的短いスパンのアクション識別だったこともあってか、
単一フレームのみを使用した予測と比較すると十分に効果がありました。

  • 認識したいフレームの前後フレームを含む3枚のRGB画像をグレースケール画像に変換
  • 3枚のグレースケール画像をチャンネル方向に結合し新たなRGB画像を生成
  • 生成したRGB画像を入力としてベースライン手法と同じ方式で学習・推論を実行

図で表すと下記の通り時系列方向の情報が2次元の画像として表現されていて、そのまま2次元CNNモデルに入力して学習・推論を実行すれば時系列情報を考慮した予測が可能となります。

コンペでよく利用される精度改善トリックの適用

今回適用したトリックは以下の通りです。Kaggleの画像系コンペによく参加されている方にとっては一般的な手法ばかりだと思いますが、簡単に紹介します。

  • 教示ラベルの見直し
    • ベースライン手法ではラベルの定義に不備(同じフレームに対して異なる2クラスがラベル付けされてしまう)があったため修正しました
  • 可能な限りモデルへの入力解像度を高くする
    • ベースラインでは456×456が使用されていましたが、最終的には1280×720の解像度を使用しました
  • loss関数を解きたい問題に合った適切なものを採用する
    • ベースラインでは4クラスのSoftmax cross entropyを使用していましたが、4クラスのBinary cross entropyに変更しました
    • 今回のコンペの精度評価方法においては、入力動画の各フレームに対する各クラスの予測スコア列の順序が重要であり、クラス間のスコアの関係はあまり重要ではありませんでした。そのためベースラインのようにSoftmaxを使用してクラス間でスコアを補正してしまうと最終的な精度に悪い影響を与える可能性がありました
  • データ拡張の追加
    • デフォルトではImageNet用のデータ拡張が適用されていましたが今回のデータに合わせて以下のデータ拡張を採用しました
    • RandomAffine, RandomPerspective, RandomHorizontalFlip, ColorJitter(brightness, contrast), Mixup
  • モデルアンサンブル
    • 最終的な提出では以下の2種類のアンサンブルを適用しています
      • 学習用データセットを複数のfoldに分割して、それぞれで学習したモデルでアンサンブル
      • 2.5次元画像を生成する際の飛ばすフレーム数を1, 2, 3と変化させたフルデータ学習モデルでアンサンブル
  • 推論時のデータ拡張(Test time augmentation、TTA)
    • オリジナル画像と左右反転画像の2種類を各モデルで推論し結果をマージしています
  • 後処理のパラメータ調整
    • 動画全体の予測結果に対して後処理で時間方向のNMSを掛ける際のWindow幅をターゲットクラス毎に調整しました

推論時間を短縮するための工夫

今回はKaggleのサーバ上でモデルの予測を実行するCode Competitionの形式で開催され、モデルの予測に掛けられる時間が9時間以内に制限されていました。
そのため、精度の良いモデルを単純に組み合わせるだけでなく、モデルの取捨選択や実行時間の制限を満たすように推論方法を工夫することも要求されました。
最終モデルには以下のような工夫を取り入れました。

  • 軽量モデルの採用
    • ベースラインのB5モデルからB0やB1の比較的軽量なモデルに変更
  • フレーム間引きおよび予測の補間
    • 入力された動画の全フレームを予測することは無駄が多いため、1フレーム飛ばして予測を実行
    • 予測しなかったフレームの結果は前後のフレームの予測結果を基に線形補間で予測を生成
  • カスタムデータローダー
    • モデルの推論処理をGPUで実行している間にCPUで次の画像の前処理を実行

スコアまとめ

今回実施した主要な実験によるスコアの推移を下表のとおりです。
ローカルの評価値(Val AP)とKaggleプラットフォーム上でのPublicスコア(Public LB)が相関していたので、精度改善作業が非常にスムーズに進みました。
最終提出ではVal APおよびPublic LBでスコアの良かったID13, 14を選択しました。

IDdescriptionmodelVal APPublic LBPrivate LB
1titoさんのベースラインモデルb5_ap0.2150.249N/A
2+ Test time augmentationb5_apN/A0.255N/A
3+ ラベルエラーの修正b5_ap0.2420.283N/A
4+ 前後1フレーム飛ばしの2.5次元画像を使用b5_ap0.3120.425N/A
5+ 入力画像の解像度を960×540に変更、2フレームごとに推論b5_ap0.5540.563N/A
6+ loss関数を4クラスBinary cross entropy lossに変更b5_ap0.6090.618N/A
7+ カスタムデータローダーb5_ap0.6250.634N/A
8+ データ拡張の追加b5_ap0.70.703N/A
9+ b5モデルをb0モデルに軽量化、4-foldのモデルアンサンブルb0_ap (4-fold)0.6690.72N/A
10+ 2フレームごとに推論した際に飛ばしたフレームの予測を線形補間で生成b0_ap (4-fold)0.6860.74N/A
11+ 入力画像の解像度を1280×720に変更、3-foldのモデルアンサンブルb0_ap (3-fold)0.7220.772N/A
12+ Mixupデータ拡張追加b0_ap (3-fold)0.7470.761N/A
13+ 3つのb0モデルの内、1つをb1モデルに置き換えb0_ap (2-fold), b1_ap (1-fold)0.7510.7680.802568
14+ 3つのフル学習b0モデル
(各モデルは前後1フレーム、2フレーム、3フレーム飛ばしの2.5次元画像を使用)
b0_ap (full-fit, time_stride=1, 2, 3)0.7530.7820.803753

上位チームの解法

Kaggleではコンペ終了後に参加者が自分の解法をフォーラムに投稿することが慣例となっています。
ここではそのような投稿の中から上位チームの解法について簡単に紹介します。
今回のタスクは定番のタスクというわけではなかったため、使用するデータやモデルパイプラインに各チーム各様の工夫が見られました。

  • 1位: Team Hydrogen Scores!
    • 2.5次元データとして隣接フレームのグレースケール画像を結合
    • 予測対象のターゲットフレームの前後7フレームを含む区間での2.5次元データをbackboneで処理し、5つの特徴量を抽出
    • 5つの特徴量をPoolingで3次元情報として集約しeventを予測
  • 2位: K_mat
    • 入力画像からオプティカルフローを抽出し、カメラの動きを予測
    • カメラの動き情報を基に前後フレームの画像を再構成し、現在フレームとの差分情報からボールの位置を予測
    • ボールの位置周辺をクロップし各フレームの特徴量を2次元CNNで抽出、ボールの軌跡情報から1次元CNNで特徴量を抽出
    • 上記2種の特徴量を1次元CNNで処理しeventを予測
  • 3位: Camaro
    • 64フレーム分の入力データを2.5次元CNN(EfficientNet with TSM)で処理し、1次元UNetモデルでeventを予測
    • SoccerNet tracking datasetを事前学習に使用
  • 4位: ohkawa3
    • 入力画像をグレースケール化し、隣接フレームの差分絶対値画像を作成
    • ターゲットフレームの前後5フレームを含む計11フレーム分の入力を処理してeventを予測
    • 学習データ中の未教示の区間について手動教示を実施
  • 5位: kzykmyzw
    • 入力動画中から識別対象とする候補フレームを抽出
    • 各候補フレームの画像中からeventが発生している可能性のある領域を検知
    • 抽出した領域に対して識別処理を適用しeventを予測
    • event領域検知用のデータは手動教示により作成

1位のチームの解法はシンプルではあるのですが、他のチームに比べて圧倒的に高いスコアを示していました。
弊社チームの解法も2.5次元情報を入力として使用するという部分では共通していて、そのテクニックだけでもスコアが大幅に伸びました。
しかし2.5次元情報からさらにその先で3次元情報として集約するという点が大きく異なる点であり、そこでスコアに差が付いているものと考えられます。

さらに詳しい内容は各チームの方がKaggle上にソリューションまとめを共有してくれていますので、そちらも合わせてご参照ください。

おわりに

本投稿では弊社チームで参加したKaggleコンペについて、コンペの概要や金メダルを獲得した解法を簡単にご紹介しました。
他の上位チームの解法と比較してシンプルな方法ですが、それなりに良いスコアを獲得することが出来ました。
これから画像系のコンペに参加されようとしている方の参考になれば嬉しいです。

本コンペには、Fixstars全社の有志で活動しているKaggleグループの取り組みとして参加しました。
Kaggleグループではチームを組んでコンペに参加したり、またソロでのコンペ結果をグループ内で報告したりして、機械学習の技術力向上に努めています。

参考文献

Tags

About Author

kosuke.mizuno

Leave a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Recent Comments

Social Media