Optuna(TPE)のアルゴリズム理解 ー Part 1 ー

2019/2/13

Qiita初投稿です．

---
[追記]
英語ですが，より詳しい説明を[arXiv](https://arxiv.org/pdf/2304.11127.pdf)にUploadしました．

長くなってしまったので，投稿を分離しました．

[Part2](https://qiita.com/nabenabe0928/items/8a325ec8d0b73c9bdf85)
[Part3](https://qiita.com/nabenabe0928/items/c895d96c0ff7a499d733)

Optunaのアルゴリズムは追ってみたいが，コード長過ぎるよ．．．
という人が参照すべきコード．冗長なコードを簡潔にし，変数名の統一性が取れるようにリファクタリングしました．行数はOptunaと比較してだいぶ減っています．
[自作したTPE](https://github.com/nabenabe0928/tpe)

**注意**: 以前に加えた性能向上のための変更により，本記事の説明とは異なる多変量のモデルに関する実装コードでかつ突然変異のHeuristicsが入っています．

---

Prefered Networks(PFN)から発表された[Optuna](https://research.preferred.jp/2018/12/optuna-release/)が利用しているモデル([TPE](https://www.lri.fr/~kegl/research/PDFs/BeBaBeKe11.pdf))の[コード](https://github.com/pfnet/optuna)を読んでみたので自分の持つ知識内でまとめてみました．[枝刈](https://medium.com/@tomoto/optuna%E3%81%AEpruning%E3%81%8C%E6%8A%B1%E3%81%88%E3%82%8B%E8%AA%B2%E9%A1%8C-1a1c9dd870df)の部分については記載していません．Optunaでは[Successive Halving](http://probabilistic-numerics.org/assets/pdf/NIPS2016/talks/AmeetTalwalkar.pdf)という手法を使用していますが，現在は[学習曲線の予測](https://ml.informatik.uni-freiburg.de/papers/17-ICLR-LCNet.pdf)の研究も各所で行われているので，今後それらの内容が導入されてくるのでは，と思っています．

<font color="Red">

[2020年9月10日追記]
学習曲線予測モデルのPRを投稿しました．

</font>

ちなみにOptunaの元は[Hyperopt](https://github.com/hyperopt/hyperopt)でその論文が[こちら](https://www.lri.fr/~kegl/research/PDFs/BeBaBeKe11.pdf)と[こちらが続報](http://proceedings.mlr.press/v28/bergstra13.pdf)．
TPEのアルゴリズムはOptunaとHyperoptでほぼほぼ変わってないです．
最近は開発が進み新たな機能がどんどん追加されており，細かな実装は異なってきています．ただし，メインで使われているアルゴリズム自体は変わっていません．

手法を説明しているその他のページ
・[hyperoptって何してんの？](https://qiita.com/kenchin110100/items/ac3edb480d789481f134)

なお，使用方法に関しては以下のリンクを参照にしてください．
・[GridSearchCVはもう古い！Optunaでサポートベクターマシンもラクラクチューニング](https://qiita.com/koshian2/items/1c0f781d244a6046b83e)
・[Optunaでハイパーパラメータチューニング](https://www.hellocybernetics.tech/entry/2018/12/22/160349)
・[optunaによるrandom forestのハイパーパラメータ最適化](https://note.mu/utaka233/n/ne71851e1d678)

# ハイパパラメータ最適化
機械学習等では学習率，重み減衰率，慣性項等事前に設定すべきパラメータがあり，それらをハイパパラメータと呼ぶ．一般的にハイパパラメータの数の指数オーダーで探索すべき空間が増えるため，特に専門家でない方にとってはハイパパラメータを決定することが難しい．その課題を解決する手段を提案するのがハイパパラメータ最適化．
## ハイパパラメータ最適化の代表例
### グリッドサーチ ・ ランダムサーチ
[最も有名な手法](http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf)として上の2つがある．問題点は探索に時間がかかることで，特にグリッドサーチは引用先が示している通り，性能に対してあまり影響を及ぼさない変数に対しても真面目に探索するため時間がかかりすぎるという問題点がある．
### CMA-ES
[進化計算の一種](https://pdfs.semanticscholar.org/4d2b/c872cee4e5f2770af70729983ec0db016a6f.pdf)で昨今の進化計算モデルでは最も性能が良いとされている．ただし，ハイパパラメータ最適化の界隈ではベイズ最適化ほどの人気はない．個人的には進化計算が直感的にうまく行きそうな気がしているが，画像認識では[あまり結果が出ていない](https://ipsjcva.springeropen.com/track/pdf/10.1186/s41074-017-0030-7)らしい．(手法自体のハイパパラメータ調整が難しいから？)
### Nelder-Mead法
[画像認識に対して有効な手法](https://ipsjcva.springeropen.com/track/pdf/10.1186/s41074-017-0030-7)としてNelder-Mead法がある．[こちらの論文](http://www.diva-portal.org/smash/get/diva2:1223709/FULLTEXT01.pdf)では以下で説明するTPEよりも良い性能を出す可能性があることを示唆している．ただし，TPEとの違いは幾何学的な探索なのでcategoricalやconditionalなハイパパラメータの探索に弱い．

### ベイズ最適化
最適化界隈で熱い手法．多くの論文はこれに関するもの(2019年1月現在)．観測点から確率的に良質な点を予測する手法で，確率的な予測を何によって行うかがこの手法のカギを握っている．現状，[Gaussian Process(ガウス過程：GP)](https://www.ism.ac.jp/~daichi/lectures/H26-GaussianProcess/gp-lecture2-daichi.pdf)が広く用いられている．ガウス過程はざっくり言うと探索空間内のある点の平均値と分散を今までの観測点から決定し，その点では評価値がその平均と分散に従った正規分布に従うというもの．空間内の候補点(主にCMA-ESを用いて決める)の内，獲得関数の値が良いものを選択し実際に予測を行う．(詳しくは他のページを参照してください．)

# TPE (Tree-Structured Parzen Estimator)
## TPEのすごさ
出典に示されている論文によると最近のハイパパラメータ探索手法の中では最も良い結果を出している(1つ目の図)．また，12回の探索を通して平均的に結果が良く，結果のばらつきが少なかったのがTPE(2つ目の図)．一方でばらつきを考慮すると最高の結果を出したのは[Nelder-Mead法](http://www.scholarpedia.org/article/Nelder-Mead_algorithm)だったりする．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/355593/cd95a72f-7f84-4678-222f-0fe12d2be385.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/355593/f98691e3-cc92-ebdb-7cca-fa48649ca102.png)
出典：[A Comparative Study of Black-box
Optimization Algorithms for Tuning of
Hyper-parameters in Deep Neural Networks](http://www.diva-portal.org/smash/get/diva2:1223709/FULLTEXT01.pdf)

## アルゴリズム概説
Optunaで用いられているTPEもベイズ最適化の一種．観測点から確率的に良質な点を探索するという考え方は変わらない．しかしながら，ガウス過程のときはハイパパラメータ同士の相関関係を考慮して関数をモデル化しているが，こちらのモデルでは全てのハイパパラメータに対して独立を仮定して確率密度関数の推定を行う．

評価値の最小化の場合
1．観測点を上位 $\gamma$ ％の評価値を基準として2つの集合 $G$(greater), $L$(lower)に分割する

2．G,Lそれぞれの集合に対して，ハイパパラメータごとに $G$ に属する確率密度関数 $g(x)$，$L$に属する確率密度関数 $l(x)$ をカーネル密度推定する

3．ハイパパラメータごとにLの確率密度関数に従った疑似乱数を生成し，その疑似乱数に対して獲得関数を変形した関数 $\frac{l(x)}{g(x)}$ の値を求め，良い値のときの引数 $x$ を採択する

## 手法名の由来
一応，[論文](https://www.lri.fr/~kegl/research/PDFs/BeBaBeKe11.pdf)から名前の意図を読み取ると，
・Tree-structured
Introductionによると，
>"In this work we restrict ourselves to tree-structured configuration spaces. Configuration spaces are tree-structured in the sense that some leaf variables (e.g. the number of hidden units in the 2nd layer of a DBN) are only well-defined when node variables (e.g. a discrete choice of how many layers to use) take particular values."

とのことなので，選ばれたハイパパラメータによって，評価する必要のないハイパパラメータが生じ，TPEではこのようなConditionalなハイパパラメータを木構造空間で管理する．

・Parzen Estimator
[カーネル密度推定](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E5%AF%86%E5%BA%A6%E6%8E%A8%E5%AE%9A)のことを指している．観測点から各ハイパパラメータの確率密度関数をカーネル密度推定で推定する．