富士フィルムコンペの解法まとめ

 

はじめに

今回,富士フィルムさん主催のデータサイエンスチャレンジコンテスト*1に参加しました.結果としては特別賞をいただけました.

ここでは自分の解法について簡単に紹介しようと思います.

 

 コンペの概要

アナログ写真の画像が与えられ,その画像の撮影年を推定するというコンテストでした.

評価指標

基本的には正解率で,上下一年のずれは正解とするというものでした.

データ

画像サイズは256x256でクラス数としては40クラスありました.

データの特徴としては

  • データ数が少ない
  • 不均衡データ(少ないクラスはサンプル数 3)

などがありました. 

自分の解法

モデルにEfficientNet-B5を用いて39クラスの分類問題として解きました.

なぜ,39クラスかは後で説明します.

前処理

最も少ないクラスのサンプル数が3ぐらいでした.

そのため,そのクラスを分類するのは難しいかなと思い,次の年のクラスとして学習させました.そのため,39クラス問題になっています. 

Augmentations

以下のコードに追加でMixup(alpha=0.25)もやっています.

いろいろやっていますが,結構適当に決めています.

data_transforms = albu.Compose([
        albu.Resize(height=img_height, width=img_width, p=1.0),
        albu.RandomRotate90(p=0.5),
        albu.HorizontalFlip(p=0.5),
        albu.VerticalFlip(p=0.5),
        albu.ShiftScaleRotate(shift_limit=0.1, scale_limit=0.1, rotate_limit=45, p=0.3),
        albu.OneOf([
            albu.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, p=0.5),
            albu.RandomGamma(gamma_limit=(85, 115), p=0.5),
            albu.CLAHE(clip_limit=2, p=0.3),
        ], p=0.5),
        albu.OneOf([
            albu.Blur(blur_limit=7, p=0.1),
            albu.MotionBlur(p=0.2),
            albu.MedianBlur(blur_limit=3, p=0.1),
            albu.GaussianBlur(blur_limit=7, p=0.1)
        ], p=0.5),
        albu.OneOf([
            albu.GaussNoise(var_limit=(10.0, 50.0), p=0.1),
            albu.ISONoise(color_shift=(0.01, 0.05), p=0.1),
            albu.MultiplicativeNoise(multiplier=0.5, p=0.1),
        ], p=0.5),
        albu.CoarseDropout(max_holes=8, max_height=8, max_width=8, fill_value=0, p=0.1),
        albu.Normalize(),
        AT.ToTensorV2()
    ])

モデル

モデルとしてはEfficientNet-B5を用いて,損失関数にFocalLossを用いました.

あとの細かい設定は次のようになっています.

  • CV : StratifiedKFold(n_splits=5)
  • Epochs : 200
  • LR : 1e-3
  • Batch size : 24
  • Optimizer : RAdam
  • Scheduler : OneCycleLR
  • Loss Function : FocalLoss(gamma=2, alpha=0.25)

 後処理

各モデルでTTA(Flip)を行い,それらの平均を最終出力しました.

その後,モデルの予測クラスTop3を持ってきて連続値なら真ん中の年を選んだり,Top1の予測と残りの2つが連続,または1年離れているなどした場合は,その真ん中を選ぶなどしました.

例えば,予測結果が1999, 2000, 2001年と並んでいた場合,予測結果は2000年とし,予測結果が1999, 2005, 2001と並んでいた場合,予測結果は2000年としました.

この後処理がかなり効果的で,2,3%ぐらいスコアが上がったと思います.

他に試したこと

  • 回帰問題として解く(全然精度でなかった)
  • 他のモデル:se-resnext101, inceptionV4, inception-resnetV2(se-resnext101は同じぐらいの精度は出た)
  • CE(FocalLossと変わらない)
  • 他のモデルとのアンサンブル(いい組み合わせが見つからなかった)
  • GeM(ほぼ変わらず)*2

他の方の解法

他の方もblogなどで自身の解法などを書いているのでここに載せておきます!

モデルの学習まわりの工夫などがすごく勉強になりました。

私のよりもきれいにまとまっており、コンペの概要なども詳しく載っています。

www.inoichan.com

hrhr08hrhr.hatenablog.com

おわりに

簡単にですが自分の解法をまとめてみました.

前回に引き続き画像の問題でとても楽しかったです.

去年,夏ごろの同じコンテストに参加してから機械学習のコンペに参加したりするようになって,自分のきっかけになってくれたコンテストだったので,そのコンテストで賞をいただけたのはとても嬉しかったです.

また,自分の作ったベースラインを何人かの方が使ってくれており,自分のように機械学習のコンペなどに参加するきっかけになってくれればいいなと思いました.

最後に,主催していただいた富士フィルムさん本当にありがとうございました.

次回もあるらしいので興味のある学生の方は是非参加してみてください.

いいカメラもらえます!