端の知識の備忘録

技術メモになりきれない、なにものか達の供養先

【IMC2023】KaggleでなんやかんやあってExpertになれた話

概要

最近久しぶりにKaggleに復帰して、Image Matching Challenge 2023というコンペに参加しました。結果、92位/464グループ という成績でギリギリ銅メダルを獲得でき、晴れてKaggle Competitions Expert(コンペで銅メダル以上2個獲得)となることができました。

アイコン周りの表示も紫色になってちょっと嬉しい

Kaggleを始めたのは2022年の4月くらいですが、ここ半年くらい何故かTypeScriptの勉強と称してLeetCodeに時間を割り当てていた時期があったので、実質半年くらいのKaggle歴です。

実は1つ目の銅メダルも昨年のImage Matching Challenge 2022にて獲得したのであまり幅広いKaggleの経験があるわけではないのですが、なんかネット上のKaggleに関する記事はKaggle MasterとかGrand Masterによる立派な記事ばかりな気がするので、平凡Kagglerの視点から感想を書いてみます。

ちなみに、タイトルの「なんやかんや」という部分に関しては、期せずKaggle悪徳業者の被害者になりかけたのでそのことを指してます。詳しくは続きをどうぞ。

まとめ

  • コンペをうまく選べばCompetition Expertになるのはそこまで難しくないと思う。コツは次の通り

    • 比較的上位のスコアがばらついているコンペに狙いを定める
    • スコアが最も高い公開ノートブックを追いかける。Disscussionにも一通り目を通して拾えそうな改善案を見つける。
    • 一通りみんなが試してそうな改善案をベースラインノートブックに加える
    • さらなる差別化として、モデルのアンサンブルやTTA(Test Time Augmentation)などを行ってチマチマ精度を上げてみるといいと思います。運が良ければそのまま100位以内に残れます。
  • Kaggleではコードを裏で売買したり、チームを組む機能を悪用してメダルの獲得を斡旋するなど不正行為を働く不届き者がいるため、コンペ終了後の不正チェックの結果順位が上がることがある。メダルギリギリの順位でもワンチャンあるかも。

無事に漠然と目標としていた1年位でKaggle Expertになるという目標を達したので、後はたまに興味のあるコンペに参加してみる感じで続けられればと思います。

また、銅メダルはこんなもんで取れてしまうので、"最低限他人の書いたコードが読めて、単純・定番な改善策を加えることができる"程度の証明にしかならないとも思いました。頑張っていつか銀以上のメダルを取ってみたいと思います。

Image Matching Challenge 2023について

www.kaggle.com

コンペの概要

大した順位ではないしこのコンペで使う技術に専門性があるわけでもなく、提出したのもベースラインのノートブックにちょっとした変更を加えただけのものなので真面目なSolution紹介をするつもりはないですが、一応どんなことをやったか書いておきます。

このコンペでは、同じ建物や物体を色々な場所から撮影された画像(以下同一シーン画像と呼びます)をもとに立体構造の復元を行う、Structure from Motion(SfM)を行います。具体的な提出内容としては、SfMの結果より得られる画像パラメータである3x3rotation_matrixと3次元のtranslation_vectorを各画像ごとに求め、flattenして次のようなCSVファイルとして提出します。

image_path,dataset,scene,rotation_matrix,translation_vector
da1/sc1/images/im1.png,da1,sc1,0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9,0.1;0.2;0.3
da1/sc2/images/im2.png,da1,sc1,0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9,0.1;0.2;0.3

SfMの原理的なところは他のサイトをご参照ください。ちなみに、私は次の本でさらってなんとなくわかった気になっています。この本は深くはないものの幅広く画像処理の基礎知識が載っているので辞書的な使い方ができて良き。

Amazon.co.jp: ディジタル画像処理[改訂第二版] : ディジタル画像処理編集委員会: 本

rotation_matrixtranslation_vectorをどのように求めるか、というところですが、実際のところはcolmapというパッケージ(と、それをPython用にラップしたpycolmap)が難しいところを全部やってくれます。

つまるところ我々が機械学習でやるべきことは、①同一シーン画像のペアを作り、②そのペア毎に学習済みのFeature DetectorとMatcherを使って一致するポイントをなるべくたくさん正確に見つけ出すことです。次のノートブックの図がわかりやすいかも。

https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5065877%2F68911db7c4cc430dec05670cd196a960%2Fslide_architecture.png?generation=1687202186098466&alt=media

https://www.kaggle.com/competitions/image-matching-challenge-2023/discussion/416873

このとき、結構複雑なデータ処理パイプラインを構築する必要があるわりに、自前でモデルのトレーニングなどは行わず既存の特徴量抽出機やマッチングモデル(LoFTRやSuperGlue, DISCなど)を使うため、普通の機械学習コンペっぽくないデータエンジニアリングが重要なコンペでした。

自分のやった工夫

ノートブックはここ。

https://www.kaggle.com/code/bobfromjapan/imc-2023-submission-92nd-solution

  • ベースにしたのはこちらのノートブック: imc-2023-submission-example | Kaggle
    • 非常に良くできたノートブックで、本データセットにおけるSfMの処理を一通り行うことができるうえ、3つの特徴点抽出&マッチング方法(LoFTR, KeyAffHardNet, DISC)を実装している。
  • これのパラメータ(画像サイズ、ペア画像数の最低数、画像から取得する特徴点の数、特徴点の選択Threshold)を最適化するため、ローカルマシンで実行環境を整えてTrainデータを利用してグリッドサーチ
    • モデルを自分でトレーニングしないコンペであっても、やはりローカルでそこそこ良いマシンを持っているとこういうところで有利です。
  • 画像の明るさを調整するためにCLAHEを施す
    • これは明確に数%前半の精度向上があったと思う。同じ被写体をいろんな条件で撮った写真のマッチングなので、これはリーズナブルな結果かな?
  • 元の実装では最終的に構築された3次元モデルの中から最も利用された画像枚数が多いもののみを選択し一部の画像のみ結果を出すようになっていたが、これを全モデル利用するように変更。
    • Trainデータにおいての改善は微々たるものだったので、これが本当に意味があったかはわからん。まあサルでも思いつくような変更なので、理由があって最良モデルのみを選択していたのだと思う。
  • LoFTRとKeyAffHardNetのアンサンブル
    • これは今回精度向上には役立たなかった。KeyAffHardNet単体のほうが数%精度が良かった。

言い訳でしかないですが、眼精疲労が酷すぎたり、仕事関連でモチベが下降気味だったり、出張が重なったり、TrainデータとTestデータでかなりスコアが違っており改善効果が読みにくかったり、そもそもSfMに関する理解不足であまり根本的な改善案を入れられなかったりで、途中からまあワンチャン銅メダル取れればいいや的なスタンスでパラメータのチューニングだけしかやらなくなってしまいました。

しかし、今回のコンペに関してはこのパラメータ設定が争点の一つだったため、結果的に大したことはしてないものの銅メダルを取得できました。

反省

画像の対応付けに参考ノートブックの元実装のtorch.cdistから変更してFAISS使いたいとか、明らかに画像の向きが揃っていなかったのでこれを揃える改良をしたいとかアイデアはあったものの、やる気と時間がなく(改めてこれは言い訳で単なる実力不足だが)実装をやめてしまった。

結果的に上位陣の解法でもこの画像の対応付けと回転に対する対応が結構大きなウェイトを占めていたので、ここをもう少し頑張れていたら銀メダルくらいは取れたかもしれないとちょっと後悔……。

Kaggleのちょっとした闇の話

また、今回のコンペに限らずKaggle界隈で蔓延る不正行為の犠牲になりかけたので、その話も少し。実は最初コンペ終了時私の順位は101位/502グループ(!!) と、ギリギリ銅メダルを取れない順位にいました。

あまりにギリギリの順位だった(しかもPublicもPrivateも101位という奇跡)ので、最後頑張らなかったツケが回ってきたかと半笑いでスクショを撮っていたのだが、こんなDisscussionを発見。

Medals sellers are always there

どうやら中国のネットマーケット上でこのIMC2023のメダルの販売が行われているという内容。

今まで参加したコンペでもちょくちょくこういう不正の噂は聞いていたものの、今回はまさに当落線上にいる身としてこの話は無視できない。

今回は諸々の事情(おそらく、ここのディスカッションで議論されてたロシアのウクライナ侵攻に関連した、上位者のCVPR参加可否の件?)でだいぶ順位確定まで時間がかかったのですが、提出締切から1週間ほど経った頃に不正のチェックが終わり、順位が9位くらい上昇し、無事に銅メダル圏内となりました。

まあ、こんな不正業者に負けるようなスコアで喚くのも情けない話ですが、銅であってもメダルを貰えるに越したことはないので、スタッフの方々の頑張りには大変感謝しております。