Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健

7,025 views

Published on

2019年9月27日のPyData.Tokyo Meetup #21での発表資料です。
Optuna (https://github.com/pfnet/optuna) の使い方やソフトウェアデザイン、LightGBM向けの新機能について紹介しています。

Published in: Technology
  • Be the first to comment

PyData.Tokyo Meetup #21 講演資料「Optuna ハイパーパラメータ最適化フレームワーク」太田 健

  1. 1. Optuna ハイパーパラメータ最適化フレームワーク Preferred Networks 太田 健 (Takeru Ohta) 2019 年 9 月 27 日 PyData.Tokyo Meetup #21
  2. 2. ● ハイパーパラメータ最適化フレームワーク ○ 2018/12にv0.4.0を公開 (現在はv0.16.0) ○ https://github.com/pfnet/optuna ● 特徴: ○ Define-by-Run ○ 枝刈り ○ 分散最適化 2
  3. 3. ● 社内外のいろいろなプロジェクトで活用 ● パブリックな事例だと、 ○ Kaggle: Open Images Challenge 2018 (二位) ■ Object Detection Track ■ 物体の重複検出抑制パラメータ(NMW Threshold)を最適化 ○ KDD Cup 2019: AutoML Track (五位) ■ LightGBMのハイパーパラメータを最適化 ■ https://research.preferred.jp/2019/09/kddcup2019automl/ 3
  4. 4. 目次 • ハイパーパラメータ最適化 • Optuna入門 • 発展的な使い方 • 新機能: LightGBMTuner 4
  5. 5. ハイパーパラメータ最適化
  6. 6. ハイパーパラメータとは? 6 ● 機械が自動で学習: パラメータ ○ 訓練データから学習 ● 人手で設定が必要: ハイパーパラメータ From: https://lightgbm.readthedocs.io/en/latest/Features.html 訓練データ ハイパーパラメータを指定 num_leaves, max_depth, ... パラメータ(具体的な木の形状)を学習 LightGBMモデル
  7. 7. ハイパーパラメータの重要性 物体検出モデルの例: • どちらも同じ学習済みモデルを使用 • 推論時のハイパーパラメータだけが異なる 7 ×不適切なハイパーパラメータ 〇適切なハイパーパラメータ 画像は PASCAL VOC2007データセット より引用
  8. 8. ハイパーパラメータ探索(手動) まずは、このハイ パーパラメータを試 そう: learning_rate: 0.1 num_leaves: 30 … 学習完了! AUC: 0.6 Trial 1 次は、これでどうだろ う? learning_rate: 0.01 num_leaves: 20 … 学習完了! AUC: 0.5 Trial 2 なるほど、これくらい が良いかな? learning_rate: 0.05 num_leaves: 50 … 学習完了! AUC: 0.8 Trial 3 8 LightGBM LightGBM LightGBM
  9. 9. ハイパーパラメータ探索(手動) まずは、このハイ パーパラメータを試 そう: learning_rate: 0.1 num_leaves: 30 … 学習完了! AUC: 0.6 Trial 1 次は、これでどうだろ う? learning_rate: 0.01 num_leaves: 20 … 学習完了! AUC: 0.5 Trial 2 なるほど、これくらい が良いかな? learning_rate: 0.05 num_leaves: 50 … 学習完了! AUC: 0.8 Trial 3 9 LightGBM LightGBM LightGBM ● 時間が掛かり面倒 ● 職人芸
  10. 10. ハイパーパラメータ探索(自動) まずは、このハイ パーパラメータを試 そう: learning_rate: 0.1 num_leaves: 30 … 学習完了! AUC: 0.6 Trial 1 次は、これでどうだろ う? learning_rate: 0.01 num_leaves: 20 … 学習完了! AUC: 0.5 Trial 2 なるほど、これくらい が良いかな? learning_rate: 0.05 num_leaves: 50 … 学習完了! AUC: 0.8 Trial 3 10 LightGBM LightGBM LightGBM
  11. 11. Optuna入門
  12. 12. インストール 12 • Python 2.7, Python3.5+をサポート • pipでインストール可能 $ pip install optuna
  13. 13. コードの基本的な構成 13 import optuna def objective(trial): return evaluation_score study = optuna.create_study() study.optimize(objective, n_trials= ) 最適化対象のコード トライアル数 目的関数の 定義 最適化実行
  14. 14. 簡単な例: 3x4 - 2x3 - 4x2 + 2 の最小化 14
  15. 15. 3x4 - 2x3 - 4x2 + 2 の最小化 15
  16. 16. 3x4 - 2x3 - 4x2 + 2 の最小化 16 trialオブジェクトを引数に取る関数を定義
  17. 17. 3x4 - 2x3 - 4x2 + 2 の最小化 17 次に評価するハイパーパラメータの値を取得 (Suggest API)
  18. 18. 3x4 - 2x3 - 4x2 + 2 の最小化 18 ハイパーパラメータの評価スコアを返す
  19. 19. 3x4 - 2x3 - 4x2 + 2 の最小化 19 最適化処理を管理するstudyオブジェクトを生成
  20. 20. 3x4 - 2x3 - 4x2 + 2 の最小化 20 目的関数と試行回数を指定して、最適化を実行
  21. 21. 実行 21 ハイパーパラメータの値を変えつつ、目 的関数を繰り返し評価して、 最適値(最小値)を探索
  22. 22. ベストトライアル 22
  23. 23. デフォルトの最適化アルゴリズム 23 ● TPE: Tree-structured Parzen Estimator ○ ベイズ最適化の一種 ○ 過去の評価履歴から、次に探索すべき点を推測 探索地点が最適解付近に収 束
  24. 24. LightGBMの例: 二値分類のaccuracy最大化 24 最適化対応前のコード
  25. 25. LightGBMの例: 二値分類のaccuracy最大化 25 最適化対応前のコード ハイパーパラメータは決め打ち
  26. 26. 最適化対応 26
  27. 27. 最適化対応 27
  28. 28. 最適化対応 28
  29. 29. 最適化対応 29
  30. 30. 特徴: Define-by-Run 30 Define-by-Run: 探索空間を目的関数の実行時に定義
  31. 31. 特徴: 枝刈り (Pruning) • 見込みの薄いトライアルを自動で中断 • LightGBMPruningCallbackを追加するだけで利用可能 31 lgb.cv()にも対応済み! Iterations
  32. 32. 特徴: 分散最適化 • 複数のトライアルを並列・分散して実行可能 • study_nameとstorageを指定し、複数プロセスから実行 32
  33. 33. 完成コード 33 探索空間定義 (define-by-run) 枝刈り対応 分散最適化対応
  34. 34. 入門用ドキュメント ● 公式ドキュメント ○ チュートリアル: https://optuna.readthedocs.io/en/stable/tutorial ○ FAQ: https://optuna.readthedocs.io/en/stable/faq.html ● Colabハンズオン ○ 英語: https://bit.ly/optuna-quick-start ○ 日本語: https://bit.ly/optuna-quick-start-ja ● Examples ○ https://github.com/pfnet/optuna/tree/master/examples 34
  35. 35. 発展的な使い方
  36. 36. Optunaの構成要素 36
  37. 37. Optunaの構成要素 37 ここまでの話ここからの話
  38. 38. Optunaの構成要素: Storage 38
  39. 39. Optunaの構成要素: Storage 39 ● Study/Trialの情報の格納先 ● 分散実行時はストレージを通して情報共有 ● 用途に応じて切り替え可能
  40. 40. ストレージの種類 ● InMemoryStorage ○ デフォルトで使用されるメモリ上のストレージ ○ optuna.create_study() ● RDBStorage ○ RDBをバックエンドにしたストレージ ○ SQLAlchemyがサポートするRDBが使用可能 ■ E.g., MySQL, PostgreSQL, SQLite ■ SQLiteはファイルベースのRDB (標準ライブラリに組み込み) ○ optuna.create_study(storage=RDB_URL) 40
  41. 41. ストレージの使い分け ● とりあえずOptunaを動かしてみたい ⇒ InMemoryStorage ● 分散最適化! ⇒ SQLite以外のRDBStorage (e.g., MySQL, PostgreSQL) ※ SQLiteは、NFSと相性が悪く、スケールもしないので注意 ● Studyを中断・再開したり、後から結果を分析したい ⇒ RDBStorage 「とりあえずSQLiteに保存」という習慣をつけておくと便利 41
  42. 42. RDBストレージの活用: Studyの中断・再開 42
  43. 43. RDBストレージの活用: Pandasで分析 43
  44. 44. RDBストレージの活用: Visualization 44 Visualization PRs: ● learning_curve: #511 ● optimization_history: #513 ● parallel_coordinate: #531 ● contour_plot: #539 ● slice_plot: #540
  45. 45. Optunaの構成要素: Sampler 45
  46. 46. Optunaの構成要素: Sampler 46 ● 次の探索パラメータを決定 ● ストレージから過去の探索履歴を取得 ● A.k.a. Black-box最適化アルゴリズム
  47. 47. 利用可能なSampler ● TPESampler (TPE) ● RandomSampler (ランダムサーチ) ● SkoptSampler (Gaussian Process ※ 変更可能) ○ https://github.com/scikit-optimize/scikit-optimizeのラッパー ● CmaEsSampler (CMA-ES) ○ https://github.com/CMA-ES/pycmaのラッパー ● ユーザ定義Sampler 47
  48. 48. なぜ色々なSamplerがあるの? 48 関数グラフはhttp://infinity77.net/global_optimization/genindex.htmlより引用 SkoptSamplerが強い CmaEsSamplerが強い TPESamplerが強い タスクによって最適な Samplerは変わる
  49. 49. Samplerの選択指針は? アルゴリズムの詳細は? https://speakerdeck.com/nmasahiro/ji-jie-xue-xi-niokeru-haihaharametazui-shi-hua-falseli-lun-toshi-jian 49 ● 時間の関係上、今回は割愛🙇 ● PyConJP 2019での野村さんの発表が参考になります
  50. 50. Optunaの構成要素: Pruner 50
  51. 51. Optunaの構成要素: Pruner 51 ● トライアルの各ステップで、枝刈りの必要性を判定 ● ストレージから、他のトライアルの情報を取得
  52. 52. 利用可能なPruner • MedianPruner (デフォルト) • PercentilePruner ※ MedianPrunerの一般化 • SuccessiveHalvingPruner • ユーザ定義Pruner 52
  53. 53. ベンチマーク結果 53 The transition of average test errors of simplified AlexNet for SVHN dataset From: https://arxiv.org/pdf/1907.10902.pdf (optuna paper) ハイパーパラメータ探索空間
  54. 54. MedianPruner ● 各ステップでの評価値(ベスト)を他のトライアルと比較 ○ 中央値よりも悪いなら枝刈り ○ 実行中および枝刈り済みのトライアルは、比較対象から除外 ● Pros: ○ 挙動が直感的 ● Cons: ○ そこそこの枝刈り効率 54 枝刈り圏内 10個のトライアルの学習曲線
  55. 55. SuccessiveHalvingPruner ● 「トライアル数が1/Nになるように枝刈り」⇒「生き残ったものにはN倍のリソース を割り当て」の繰り返し (右上の図) ※ かなり簡略化した説明および図 ● Pros: ○ 高い枝刈り効率 ○ 分散最適化と相性が良い ■ 実行中・枝刈り済みトライアルも考慮 ○ 学習曲線以外にも応用が効く ■ E.g., データサイズを変えつつ枝刈り (右下の図) ● Cons: ○ 現状ではハイパーパラメータに敏感 ■ min_resourceの適切な指定が必要 ■ E.g., min_resource = num_iterations/100 55 Halve! N=2, min_resource=2 1/100のデータで評価&枝刈り 1/10のデータで... 完全なデータで評価
  56. 56. Tips: 枝刈り時のトライアル回数はどうすべきか ● n_trialsを変更せずに、単純に枝刈りを有効にすると、 ⇒ 最適化結果は悪くなる ※ 所要時間は短縮される ● n_trialsを増やすと良い? ○ 枝刈りがあると、一回のトライアルに掛かる時間が不規則になる ⇒ 適切なn_trialsの値を推測するのが難しい ● timeout指定がお勧め ○ 時間が許す範囲内で、出来るだけ多くのトライアルを実行 ○ E.g., study.optimize(objective, timeout=600) # 10分間最適化 56
  57. 57. Tips: 枝刈りとlearning_rate(LR)の最適化 ● 枝刈りとLR最適化の組み合わせには注意が必要 ○ LRが小さいものほど、初期段階で刈られやすくなる傾向がある ● LightGBM向けの現状での対応策(一案) ○ フェーズを分ける ○ 最初は、LRを固定して、 それ以外のパラメータを枝刈りありで最適化 ○ 最後は、LRだけを枝刈りなしで最適化 ● 将来的にはPrunerを改良予定 ○ E.g., 学習曲線予測、Hyperband 57 From: https://medium.com/@tomoto/1a1c9dd870df ここで刈られてしまう
  58. 58. ここまでのまとめ 58 いろいろとカスタマイズできるので、 是非試してみてください
  59. 59. 新機能: LightGBMTuner
  60. 60. LightGBMTuner 60 • Optunaは便利 ○ ハイパーパラメータを自動で探索してくれる ○ ただ、探索空間はユーザが指定する必要がある ⇒ 一種のハイパーパラメータ • 理想 ○ ユーザに何も意識させずに勝手に最適化してくれる ⇒ LightGBMTuner!
  61. 61. 使い方 インストール (before v0.17.0): $ pip install git+https://github.com/smly/optuna@lgbm-autotune LightGBM互換インタフェース: 61 修正箇所は一行
  62. 62. Stepwise Tuning ● 重要なハイパーパラメータを、順々にOptunaで最適化 ○ E.g., feature_fraction, num_leaves, bagging_fraction ● Stepwise Tuning: ○ 一度に全パラメータを探索すると空間が巨大になってしまう ■ 一つずつ探索することで効率化 ○ 経験的に良いチューニング手法であることが知られている: ■ CPMP's talk in Kaggle Days Paris ■ Chang's comment in Kaggle forum 62 一度に探索: X*Y Stepwise: X+Y
  63. 63. ベンチマーク結果 63 ● Kaggle: DonorsChoose.org Application Screening ● LightGBM and Tf-idf StarterカーネルのLightGBM部分をLightGBMTunerに置換 ○ See: https://gist.github.com/smly/367c53e855cdaeea35736f32876b7416 ● オリジナルスコア: ○ Validation: 0.77910 ○ Private: 0.78470 ○ Public: 0.79516 ● Tunedスコア: ○ Validation: 0.77993 (0.00083 up) ○ Private: 0.78622 (0.00152 up) ○ Public: 0.79535 (0.00019 up) Stepwise Tuningの経過 (from: https://github.com/pfnet/optuna/pull/549) ※ 赤線はオリジナルのスコア ※ チューニング中(右の図)はLRを高めに設定しているため、左のスコアの値とは若干ズレがある
  64. 64. LightGBMTuner独自のlgb.train()引数 ● best_params: ○ ベストパラメータを格納 ● tuning_history: ○ チューニング履歴を格納 ● time_budget: ○ 制限時間を指定 ● sample_size: ○ サンプリングを有効化 64
  65. 65. 絶賛開発中! ● 検討中の機能: ○ 枝刈り ○ lgb.cv()対応 ○ レジューム対応 ● フィードバックは大歓迎! ○ https://github.com/pfnet/optuna/pull/549 65
  66. 66. まとめ ● Optunaでハイパーパラメータが簡単に最適化可能 ● 特徴: ○ Define-by-Run ○ 枝刈り ○ 分散最適化 ● Storage/Sampler/Prunerは用途に応じてカスタマイズ可能 ● LightGBMTunerがもうすぐリリース 66
  67. 67. Need Your Feedback and Contribution! 67

×