More Related Content
Similar to Kaggle Happywhaleコンペ優勝解法でのOptuna使用事例 - 2022/12/10 Optuna Meetup #2 (20)
More from Preferred Networks (20)
Kaggle Happywhaleコンペ優勝解法でのOptuna使用事例 - 2022/12/10 Optuna Meetup #2
- 2. 2
● -2021 東京大学コンピュータサイエンス修士課程
○ 深層学習の研究
○ 競技プログラミング(ICPC, AtCoder, Codeforces, etc.)
● 2021- Preferred Networks エンジニア
○ 半導体・リテール関連のプロジェクト
○ 2022/04- Optuna開発にも携わる
■ TPEの制約付き最適化・CMA-ES with Marginなど
● 2022年のHappywhaleコンペでKaggleを始める
Kenshin Abe / @knshnb
- 6. 6
● タスク概要
○ 様々な種類のクジラやイルカの画像から
個体を識別
● 目的
○ 専門家が時間をかけて行っていた個体
識別の自動化により、海洋研究の効率
化・環境保全への貢献
○ 実際にコンペ終了後にホストとシステム
導入に向けてのディスカッション
コンペのタスク
https://www.kaggle.com/competitions/happy-whale-and-dolphin/data
- 8. 8
● SoftmaxにMarginを持たせクラス内分散を抑える手法
● ここ数年、様々なKaggleコンペで高い性能
○ 1st place solution of “Human Protein Atlas Image Classification” by
bestfitting, 2019/01
○ 1st place solution of “Google Landmark Recognition” by Dieter, 2021/10
○ 3rd place solution of “Foursquare - Location Matching” by Psi, 2022/07
○ 1st place solution of “Google Universal Image Embedding” by Shihao
Shao, 2022/10
● 一方、性能がマージン・温度の2つのハイパーパラメータに
対してかなり敏感
○ 不均衡データに対応するためのDynamic Marginとい
う手法を採用すると、更にハイパラが増えて調整が大
変に
ベースライン: ArcFace [Deng+, CVPR 2018]
https://arxiv.org/pdf/1801.07698.pdf
- 9. 9
● 本体Crop + Sub-center ArcFace + Dynamic Margin + k-NN
● ポイント
○ ArcFaceのハイパーパラメータをOptunaにより調整
○ 複数種類のBounding boxを混ぜることによるData augmentation
○ k-NNとlogitを組み合わせたPostprocess
○ 疑似ラベル・アンサンブル
○ その他大量の試行錯誤によるアーキテクチャ・パイプラインの改善
● 詳細
○ Kaggle Discussionへの投稿: https://www.kaggle.com/competitions/happy-whale-and-dolphin/discussion/320192
○ https://github.com/knshnb/kaggle-happywhale-1st-place
○ https://github.com/tyamaguchi17/kaggle-happywhale-1st-place-solution-charmq
1st Place Solution サマリー
- 13. 13
● もともとPyTorch Lightningで実装していたので簡単に組み込めた
● 中間値を自動でreportしてくれるので、学習曲線の可視化が可能に
● PrunerはデフォルトのMedianPrunerよりNopPrunerの方が性能が良かった
(MedianPrunerのパラメータ調整の余地あり)
PyTorch Lightning Integration
import optuna
from optuna.integration import PyTorchLightningPruningCallback
def train(..., cfg: Config, trial: Optional[optuna.Trial] = None) -> float:
...
if trial is not None:
callbacks.append(PyTorchLightningPruningCallback(trial, "val/map5"))
...
return trainer.callback_metrics["val/map5"].item()
base_cfg = load_config(...)
def objective(trial: optuna.Trial) -> float:
cfg = copy.deepcopy(base_cfg)
cfg["s"] = trial.suggest_float("s", 10.0, 80.0)
cfg["margin_power"] = trial.suggest_float("margin_power", -0.8, -0.05)
...
return train(..., cfg, trial=trial)
def train(..., cfg: Config):
...
cfg = load_config(...)
train(..., cfg)
- 14. 14
● 実際の学習はV100 (32GB)を2-4個使って半日程度かかる
● V100 (16GB) 1つで1時間程度で終わるような軽量な目的関数を設定
○ モデルサイズ縮小(efficientnet_b5,6,7 → efficientnet_b1)
○ 画像サイズ縮小(768-1024 → 256)
○ 本体をcropしてresize後のデータをPFIOをつかってキャッシュし、データの
読み込みを高速化
● 100回程度の評価が現実的に
● 得られたパラメータは大きいモデル・画像サイズやパイプライン改善後もうまく
動いたので最後までその値を使用
○ ある程度良いパラメータを求めるのには十分だった
○ 転移学習で調整し直すともっと性能が上がったかも(後述)
目的関数の軽量化
- 15. 15
● 分散最適化、プログラムの中断・再開が可能に
● Heartbeat機能によりFailしたtrialを検知可能
● RetryFailedTrialCallback.retried_trial_numberでpreemption対応も可能
RDBStorageを用いた分散最適化
storage = optuna.storages.RDBStorage(
url=rdb_url,
heartbeat_interval=60,
grace_period=120,
failed_trial_callback=optuna.storages.RetryFailedTrialCallback(),
)
study = optuna.create_study(storage=storage, ...)
- 17. 17
● PyTorch Lightning Integrationは、現在(v3.0.4)最新版のPyTorch Lightningに
対応していないので1.5.*以前のものを使用
○ 近々対応の予定(PR)
● study.enqueue_trialでデフォルトのパラメータなどを指定できる
● Samplerは以下の理由からTPEを採用
○ カテゴリカル変数にも対応
○ enqueue_trialの結果がその後の探索に使われる
○ cf. Sampler比較表: https://optuna.readthedocs.io/en/stable/reference/samplers/index.html
その他tips・注意点
- 19. 19
● TPEの引数の設定
○ multivariate: 変数間の相関を考慮
○ constant_liar: 並列最適化向けオプション
■ v3.1の修正で性能が向上
○ group: dynamic search spaceでグループごとに変数間の相関を考慮
● Warm Starting CMA-ES(スライド)
○ 似たようなタスクでの評価結果を転用する手法
■ ex. NNの訓練などの重いタスクでデータ数・モデルサイズなどを減ら
した結果を流用
■ ex. 設定を微妙に変えて最適化の試行錯誤を何度もする場合
コンペで使えばよかった機能
- 20. 20
● LightGBMTuner(ブログ記事)
○ Kaggle Grandmaster(smlyさん)の知見が詰め込まれた、LightGBM専用
のハイパラ最適化ツール
● Dynamic Search Space
○ 探索範囲の変更はかなり自由にできる
○ パラメータの追加・削除・範囲の変更・if文による分岐
○ categoricalのchoicesのみ変更不可
その他Kaggleで使えそうな機能1
- 21. 21
● [0, 1]の範囲の重み調整
○ アンサンブルの重み調整などに
● Pruning
○ 性能が悪化するケースもあるので注意して使う必要あり(v3でのベンチ
マーク結果)
● CMA-ES with Margin (~v3.1)
○ 離散的な探索空間(intなど)で局所解にハマりにくく
● JournalStorage (~v3.1)
○ SQLサーバーを建てられない環境・面倒な場合
● BruteForceSampler (~v3.1)
○ 同じインターフェースで全探索
その他Kaggleで使えそうな機能2