kaggle"PetFinder.my - Pawpularity Contest"でゴールドメダルを獲得しました
2021年9月から2022年1月の期間開催されたkaggleのコンペPetFinder.my - Pawpularity Contestにて3557チーム中Public 1st/Private 5thの成績を納めゴールドメダルを獲得しましたので、取り組みやソリューションを紹介したいと思います。
コンペ概要
PetFinder.my - Pawpularity Contest(以後PetFinderコンペ)はマレーシアのペットの里親を募集するサイト"PetFinder.my"に投稿されたペットの写真がいかに可愛いか、魅力的であるかを表す独自指標"Pawpularity"を予測するコンペです。写真の魅力度を定量化する予測モデルができれば、写真の撮り方や構図の改善が促せるようになり、里親の早期発見に繋がり動物福祉に役立てられます。
学習データに与えられているデータは、ペットの写真の他に写真に写っているものを人がラベリングしたメタデータが与えられていました。予測対象であるPawpularityは具体的な算出方法は公開されていませんが、Webサイトのアクセスログから算出された値であると説明がありました。
コンペ取り組み
画像からPawpularityを予測するモデルとしてまず最初にEfficientNet-B0を使いベースラインモデルを作成しました。
コンペ序盤では軽量なアルゴリズムを使って様々な実験を回し、コンペ中盤以降で重いアルゴリズムを使って精度を向上させる進め方です。多くのkagglerがこのような取り組み方をしているのではないでしょうか。
ベースラインモデルとして画像のみからPawpularityを予測するモデル以外に、画像とメタデータを使ったモデルも作成しましたが精度はよくならなかったためメタデータは使用しませんでした。kaggleのディスカッションや公開notebookでもメタデータをうまく活用できている例はありませんでした。
メタデータは画像に写っているものを人がラベル付けしたものもであり、経験的にもこのようなデータが精度向上につながることは少ないように感じます。画像から判断できないもの、例えばペットの年齢や、飼い主の情報などがメタデータとしてあれば活用できた可能性はあると思います。
ベースラインモデルの作成後は早々に何をどう改善したら良いのかわからない問題にぶつかりました。というのもPawpularityはペットの魅力度の指標であるにもかかわらず、Pawpularityが低くくても可愛いペットの写真が沢山ありました。なにがPawpularityと関係しているのかわらなかったので、仮説を立てて改善していくというアプローチが非常に難しいコンペでした。
改善のポイントがわからないこともあり、比較的早いタイミングでアンサンブルも試しましたが微改善にとどまりました。アンサンブルは多様性を持たせるためにViT系とCNN系のアルゴリズムを混ぜた他、画像のCrop有無や異なるLoss Functionで作ったモデルを使いました。
色々試す中で大きく精度を改善できた実験がひとつありました。それは、過去コンペのデータを使った後処理でした。
お題は違いますが過去にもPetFinder.my主催のコンペがあり、過去コンペの画像と今回のコンペの画像が一部重複していることがディスカッションで報告されていました。
私たちのチームも重複については確認していたのですがデータを見た結果あまり活用できなさそうと判断して一旦は放置していました。しかしコンペ中盤に後処理に使うことで大きく精度を改善できる方法を見つけました。後処理で精度向上できるとわかってからは多くの時間を後処理の改善に費やしました。この後処理が決め手となりゴールドメダルを獲得することができました。どのような後処理をしたかはソリューションで紹介します。
ソリューション
概要
私たちのチームの最終submitのソリューションは14モデルのアンサンブルに対して後処理を加えたものです。
今回はSwinTransformerがとても強くアンサンブルに組み込んだ14モデル中9モデルがSwinTransformerです。
アンサンブルはBayesianRidgeでStackingしたものと、単純平均をしたものそれぞれに後処理を加えて最後にこの二つを加重平均しています。コンペ中盤まではStackingのみのアンサンブルでしたがValidationデータに過学習しているような傾向が見られたため単純平均をアンサンブルに組み込み正則化として機能させました。
後処理は次のステップで行っています
1. 前回コンペとの重複データを抽出
前回コンペと重複しているデータに対して後処理をするため、重複している画像を抽出します。
重複している画像は、ピクセル単位で完全に一致しているわけではなかったので画像の差分をとるなどの簡単な方法では重複画像を見つけ出すことはできませんでした。そこで私たちのチームではEfficientNet-B0の学習済みモデルを使って画像の埋め込みベクトル作成しコサイン類似度をもとに重複画像を抽出しました。
2. 後処理①
重複していた画像の予測値に対して後処理をしました。具体的にはBayesianRidgeでモデルを作りました。このモデルの特徴量に犬種/猫種、年齢、ペットページの概要(自然言語から特徴抽出したもの)など、前回コンペでメタデータとして提供されていた情報を使いました。
3. 前回コンペの学習データ抽出
「1.前回コンペとの重複データを抽出」で抽出した重複データのうち前回コンペの学習データのみを抜き出します。これは次の「4. 後処理②」で前回コンペの学習データと重複があったデータに対して後処理をするためです。
4. 後処理②
「3.」で抽出したデータの予測結果に対して後処理をします。この時に後処理に前回コンペの予測対象であったAdoptionSpeedに対して後処理をします。(AdoptionSpeedは里親が決まるまでにかかった日数を離散化したもので、日数に応じて0~4のグループに分けられている)
ここでもBayesianRidgeを使ったモデルを作っていますが、ここでは、AdoptionSpeed0~4のデータごとに計5つの予測モデルを作りました。
AdoptionSpeedごとにPawpularityの分布が異なっていたためこのようなことをしています。AdoptionSpeedごとにモデルを分けずに、モデル1つでAdoptionSpeedを特徴量に使う実験もしていましたがモデルを分けたほうが精度が良かったです。
解法についてはkaggleのDiscussionにも投稿してあります。
後処理が非常に強力であったため、前回コンペと重複していないデータに対しても後処理を行いたいと考え、前回コンペのメタデータを予測するモデルやAdoptionSpeedを予測するモデルを作り全データに対して後処理を加える実験もしたのですがこれは精度改善につながりませんでした。
コンペを終えて
ゴールドメダルを獲得できたのは「Do Everything」と「Trust CV」を貫いたことが大きいと思っています。
kaggleではすべてのアイディアを試すDo Everythingの精神が大事だと言われています。今回のコンペではコンペ序盤ではあまり使えなそうと判断した前回コンペのデータを活用して大きくスコアを伸ばすことができました。それ以外にも思いついたアイディアは全て試しました。ただ、コンペ終了直前に論文で発表されたConvNextを使うと良い精度が出たという情報もあり、私たちのチームはConvNextの存在を知りながらも試していなかったのでこの辺りは詰めが甘かったなと感じています。また上位の解法を見ると後処理を行わなくてもSVMを使うことで高い精度を出しているソリューションもあり、まだまだできることはあったなと感じさせられました。
Leader Boardのスコアを信じすぎず手元の評価を信じるTrust CVこれもkaggleでは非常に重要なことだと言われていますが、最後までTrust CVを貫き通すことができました。Private Leader Boardで4位に留まることができたのはTurst CVのおかげだと感じています。コンペ中盤上位争いをしていたチームの中には最後大きく順位を落としているチームもいたためTrust CVを貫いていなかったら私たちのチームもゴールドメダルは獲得できていなかったと思います。