はじめに
こんにちは。NRI 向後と申します。
先日、データ分析コンペサイトProbSpaceで開催された「日本画の登場人物分類」コンペティションに参加させていただき、 参加ユーザ数165名のうち1位を獲得することができました。
こちらの記事に私が取り組んだコンペの概要と解法をご紹介します。
日本画の登場人物分類コンペ概要
本コンペは、日本の文学作品に描かれるさまざまな人間模様の特徴を捉え、登場人物の階級身分を分類するコンペティションです。
絵巻物に描かれる、貴族や皇族などの人物は「引目鉤鼻(ひきめかぎはな)」と呼ばれるような特徴が施されているなど、人文科学分野では盛んに研究されています。
本コンペでは、絵巻物から抽出された人物の「顔貌データ」を用いて「貴族・武士・化身・庶民」の4つの身分を分類するタスクでした。
画像データと階級身分のラベルのみ与えられているため、絵巻物の属性情報や登場人物の関係性を用いることはできず、シンプルながら難しいコンペでした。
提供データは下記サイトから確認できます。
『顔コレデータセット』(CODHが国文学研究資料館・ROIS-DS人文学オープンデータ共同利用センター、慶應義塾大学、京都大学附属図書館から収集、DOI:10.20676/00000353)
解法の紹介
コンペ期間を大きく3つに分けて、アプローチを変えていきました。
序盤
- コンペ序盤は単体モデルでの精度向上を目指し、実験を重ねていきました。
特にData Augmentation(学習データに対して回転・反転などの加工を行い、データを水増しする手法)やモデルのアーキテクチャ周りで試行錯誤を繰り返しました。
- コンペ序盤は単体モデルでの精度向上を目指し、実験を重ねていきました。
中盤
- コンペ中盤は序盤で作成した単体モデルをアンサンブルし、精度向上を目指しました。
アンサンブルの方針として、新しくモデルを作成した際に、CVまたはLBの精度が向上しているかどうかによって、作成したモデルをアンサンブルに含めるかどうかを判断しました。
この考え方はKaggleコンペ「Pet Finder2」における6th Place Solutionを参考にしました。
他で開催されたコンペの知見をどんどん試すことができることはコンペの面白さであり、一方でどの解法が今回のコンペに有効であるかを判断する「目利き」が必要になることが難しさの一つでもあります。
- コンペ中盤は序盤で作成した単体モデルをアンサンブルし、精度向上を目指しました。
終盤
- 中盤で試したアンサンブルでは精度向上の幅が鈍化してきたため、Optunaによるパラメータ最適化や後処理を検討しました。
終盤はLBがほぼ上がらなかったため、手元のCVの向上を頼りに実験を繰り返しました。
上位陣のスコアが非常に密だったため、スコアの乖離は少ないと考え、提出ファイルはCVが最もよいもの、LBが最もよいものをそれぞれ一つずつ選び、フィニッシュしました。
- 中盤で試したアンサンブルでは精度向上の幅が鈍化してきたため、Optunaによるパラメータ最適化や後処理を検討しました。
解法の全体像
提出ファイルは下記のフローで作成しました。
大きく5つのステージに分かれていますので、それぞれの手順をこれからご紹介していきます。
Stage 1
- コンペ序盤はアンサンブルの種になる単体モデルをたくさん作成していく方針で進めました。本タスクではVision Transformer(ViT)モデルが刺さっていたので、ViTのアーキテクチャをガチャガチャいじりながら精度向上を図っていきました。
アンサンブルはモデルの多様性が活きるため、ViTの他にSwin Transformerを加え、さらにEfficientNetやConvNextのCNNも試しました。
また、事前学習モデルのDINOを活用できたのもよかったです。
timmライブラリで提供されているモデルはImageNetを用いた学習済みモデルになっており、今回用いた日本画の顔貌データはImageNetとは特徴が異なる画像であると考えました。
さまざまな条件でモデルをアンサンブルし、最終的に図に示す条件のモデルのアンサンブル結果が最も精度が良くなり、採用しました。
アンサンブル後の結果をPseudo Labelとし、Stage 3のモデル学習に活用しました。
- コンペ序盤はアンサンブルの種になる単体モデルをたくさん作成していく方針で進めました。本タスクではVision Transformer(ViT)モデルが刺さっていたので、ViTのアーキテクチャをガチャガチャいじりながら精度向上を図っていきました。
Stage 2
- Stage 1でアンサンブルを重ねていくにつれ、精度向上が鈍化していきました。
モデルではどうしても分類できないデータがあるのではないかと考え、それぞれのモデルで外しやすいデータを確認したところ、一部の実験全てで不正解となっているデータが見られました。
これらのデータを学習させてしまうとノイズになる可能性があったため、学習データから取り除き、残りのデータでモデルを学習させるアプローチを検討しました。
上記で作成したモデルはStage 3で活用しています。
- Stage 1でアンサンブルを重ねていくにつれ、精度向上が鈍化していきました。
Stage 3
- Stage1, Stage 2のアプローチを活用したモデルを迎え、Optunaを用いて重み最適化を実施しました。
ここで、Data Augmentationの種類も直しました。
学習データの中に横向きの画像(お辞儀していたり、横たわっている)が含まれていましたが、テストデータにはあまり見られなかったため、RotateやShiftScaleRotateを除外しました。
また、さらに多様性を求めるために、CV分割方法を検討しました。
これまではラベルごとのStratified KFoldで分割していましたが、画像の色味や顔貌から年代や絵巻物の種類をある程度分割できないかと考え、事前学習済みモデルを使って各画像のEmbeddingを抽出し、次元圧縮後にクラスタリングを行い、画像を分類しました。
それらのクラスタ毎にStratified KFoldで分割することによって、絵巻物の種類が各Foldにバランスよく分布するようにし、モデルを学習させました。
この時点の結果がコンペを通してCVが最もよい結果であったため、提出ファイルの1つとして選定しました。
- Stage1, Stage 2のアプローチを活用したモデルを迎え、Optunaを用いて重み最適化を実施しました。
Stage 4
- Stage 3でさまざまなモデルを組合わせて実験を繰り返しましたが、ある時点から結果が全く変わらなくなりました。しかし、この時点でまだ上位陣にスコアが追い付いていなかったため、別の方針を検討する必要がありました。
Stage 1~Stage 3では、各モデルはマルチクラス分類(画像に対して、貴族・武士・化身・庶民のうちどれかを当てる)としていましたが、貴族か貴族以外かを予測するモデルを作成し、ラベルが貴族の予測確率について他のモデルと組み合わせてOptunaを実行しました。
最適化された確率を用いて、元の確率との平均を算出し、結果を採用しました。
- Stage 3でさまざまなモデルを組合わせて実験を繰り返しましたが、ある時点から結果が全く変わらなくなりました。しかし、この時点でまだ上位陣にスコアが追い付いていなかったため、別の方針を検討する必要がありました。
Stage 5
- いよいよコンペ終盤となり、さらなる精度向上を図るため、学習データを全て用いた全学習モデルを作成し、Stage 4で作成した結果と組み合わせました。
全学習モデルはCVを算出することができないため、Optunaによる最適化は難しく、今回は1:4の割合で重みを小さめにしてアンサンブルしました。
全学習データの結果を寄与させつつ、かつ支配的にならないように検討した結果、上記の割合を採用しました。
アンサンブル後のラベルとStage 4で作成した二値分類モデルを比較し、二値分類モデルで「貴族」と予測した結果で上書きしたものを提出ファイルの二つ目としました。
ただし、「化身」と予測しているケースについては上書きしないようにしました。
「化身」は人間の目からみても特徴的であることが明らかであったため、マルチクラス分類モデルの方が高精度だろうと考えました。
- いよいよコンペ終盤となり、さらなる精度向上を図るため、学習データを全て用いた全学習モデルを作成し、Stage 4で作成した結果と組み合わせました。
最終結果は二つ目の提出ファイルがPublic, Privateともに1位となり、優勝することが出来ました。
おわりに
最後まで混戦でShake Downが発生する懸念もありましたが、多様性を重視したアプローチを一貫したことが功を奏したか、そのままの順位でフィニッシュすることが出来ました。
突飛なアイデアで精度を大きく上げたわけではないですが、他のコンペの知見を応用することができ、最後まで走りぬくことができたのは非常に良い経験になりました。
本コンペで得た経験を今度は他のコンペに応用できるように、データサイエンスに取り組み続けていきます。
※本記事の掲載図の一部に、コンペで提供されたデータを使用しています。