CLOSE

Optunaの紹介(全2記事)

Pure Pythonで書かれた“Optuna”の仕組み ハイパーパラメーター自動最適化のフレームワーク

Optuna™は、オープンソースのハイパーパラメーター自動最適化フレームワークです。 「Optuna Meetup #1」では、Optunaのユーザー、導入を検討している方、また開発者を中心に、Optunaの様々な活用方法が共有されました。Yamazaki氏は、Optunaの開発のきっかけ、歴史、そして概要について発表をしました。全2回。後半は、コードの書き方とリリースや互換性に対する考えについて。前回はこちら。

「Optuna」ではどのようなコードを書くのか

Hiroyuki Vincent Yamazaki氏:では、コードをちょっと見てみましょう。

まず、Optunaのインストールですが、pipもしくはcondaでサクッと入るのがいいかなと思います。Optunaはpure Pythonなので、難しいコンパイラーのセットアップは一切必要ありません。簡単にインストールできると思います。

Optunaのコードを見ると、この1行がほぼ必ずと言っていいほど出てくると思います。この1行が何をしているかというと、先ほど出てきたStudyを作っています。特に引数を与えないで呼ぶと、メモリー上にStudyが作られて、すぐOptunaの実行ができます。

もう少し細かい設定を見てみましょう。

まず第1の引数として、Studyの名前を与えています。このStudyの名前は、Storageの中でユニークでなければいけません。identifier(識別子)の役割を果たしています。

最適化のアルゴリズムと、Pruningのアルゴリズムをここで指定します。いろいろなsamplerやprunerがあって、それぞれ引数で細かい挙動を制御できます。

storageに関しては、省くとメモリー上になりますし、このようにURIを指定するとRDBに接続できて、MySQLのデータベースがあれば接続も可能です。SQLiteのファイル名を指定すると、Optunaが自動的に作ってくれます。

こういうかたちの永続化も、特にRDBのセットアップは必要なくOptunaが自動的にやってくれるので、そんなに難しくはないかなと思います。

さらに、この問題が最大化もしくは最小化なのかをここで指定しています。それがdirectionです。

最後のload_if_existsは、Storageの中にmy-studyという名前のStudyがすでに存在している場合、例外にするか、もしくは例外にせずに読み込むかを制御する引数です。なんでこれが便利なのかは、のちほど共有します。

読み込むことによって、分析や続行ができると思ってもらえればいいかなと思います。

では、先ほど出てきた目的関数や探索空間をどうやってOptunaに渡すかというと、決して難しくはなくて、あるCallableをOptunaに渡してあげればよいです。こういうインターフェイスになっています。

Callableは、単純にTrialを1つ受け取ります。そして、目的関数の出力であるfloatを1つ出力します。多目的な場合は、floatを複数、例えばタプルで返すCallableを定義すればよいので、これぐらいの違いです。

まず、探索空間を定義します。探索空間をどのように定義するかというと、Trialのメソッドのsuggest_にfloat、categorical、intなどいろいろとハイパーパラメーターの種類によって使い分けて行います。最初のsuggest_floatは、先ほどの物体検出の閾値を、0から1の間で見つけたいと宣言しています。

例えばn_layersは、suggest_intでintが返って来るんですが、実際に返ってきたintをもとに、ここはn_channelsと動的に探索空間を定義することもOptunaだと簡単にできます。これが探索空間の定義の仕方です。

目的関数はどうかというと、これは学習のスクリプトみたいな、Optunaを導入する前にすでに使っていたものが考えられます。

なので、先ほどの学習の設定のハイパーパラメーターを呼び出しで渡して、それがどれだけよかったのかがわかればよいということになります。これを、Callableから返します。

ここまではStudyとその準備をしただけで、実際にTrialは回っていません。どのように回すかというと、Studyのoptimizeメソッドを呼びます。

これに先ほどのCallableを渡して、何回Trialを回すかをここでは指定します。そうすると、Trialが順番に1個ずつ、シークエンシャルに実行されていきます。

これが終了すると、StudyからTrialの履歴を引っ張ってきたり、一番よかったTrialをもって来たり、また一番よかったパラメーターをもってきたりが簡単にできます。

ちなみにこのbest_trialは、またobjectiveにそのまま渡せるので、再評価もできますし、パラメーターは普通にファイルにとっておいたり、これで再度モデルを学習し直したりなど、いろいろなケースが考えられると思います。

Optunaのもう1つ大きな特徴で、先ほどload_if_existsの話があったと思うのですが、あれをtrueにしておくと何が便利かというのがこちらです。

Optunaの分散実行についてお話しします。各Trialは独立していて、ロジックとしては独立しているということがあるので、Trialを1個ずつ回すのではなくて、同時に複数走らせることが考えられるかと思います。

先ほどのコードを1行も変えずに、Pythonの違うインタープリターのプロセスでキックするだけで、例えばRDBだったらRDBを介して情報のやり取りをしているので、分散の実行が簡単にできます。こういったかたちになっていて、これもOptunaの特徴の1つかなと思っています。

ここの仕組みがどうなっているか、今日はお話できるとおもしろいかなと思います。興味がある方はぜひ聞いてください。

これが、Optunaのとても簡単な概要です。

Optunaには、他にも機能がたくさんあります。今回は、含みきれないので、URLを貼っておくので、あとでよかったらスライドから辿って詳しく調べてください。

Optunaとしてがんばっているところが、結果の分析です。Optunaがよいというハイパーパラメーターを出力するのですが、どういう過程でよかったのか、目的関数の空間がどうなっているのか、みたいなのを目で確かめられます。

可視化の機能がたくさん入っていて、これをPythonのAPIから叩くことももちろんできますし、最近はOptunaのダッシュボードも開発されていて、こちらだとさらにインタラクティブにStudyの中身を分析できるので、よかったらぜひこちらもチェックしてください。

また「Ask-and-tell」という、わりと最近入ったAPIがあります。これは最適化を回す時に、Studyのoptimizeメソッドの代わりになるインターフェイスです。CallableでTrialを受け取るのではなくて、ユーザーが明示的にTrialを作ります。例えばハイパーパラメーターのsuggestだけをあるプロセスで呼んで、それをファイルに保存して、複雑な学習のパイプラインがあった時に、別のステップでそれを読み込んで評価したり、また別のステップでそれをOptunaに再度教えてあげたり、いろいろなパイプラインやプログラムに柔軟に対応できるインターフェイスになっています。

よかったら、こちらもぜひ見てみてください。

みなさんおわかりのとおり、ハイパーパラメーターは、日常的にいろいろな場面で出てきます。いろいろなライブラリを使っていても、出てきます。なので、頻出するパターンやライブラリに対しては、Optunaでは公式のユーティリティのような便利機能が複数あるので、自分が使っているライブラリがもしここにあったら、見てみてもいいかなと思います。

さらに、Optunaをインストールするとデフォルトでコマンドラインツールが入ります。これはStudyの操作やOptunaのバージョンを簡単にチェックできます。

あとは多種多様な公式のexampleもたくさんあるので、ここから入っていくのも入り口としてはいいかなと思います。ドキュメンテーションもみんながんばっているので、こちらもぜひ見てください。

今は、次のメジャーなアップデートであるv3のブレインストーミングをみんなでしているところです。こういう機能が欲しいとか、こういう改善をしてほしいとかがもしあれば、共有していただけると、考慮できるかもしれないなと思っています。

互換性はけっこう重要だと考えている

「そもそもv3ってどういう意味なの?」とか、「Optunaをプロダクションで使いたいんだけれども、バグがあった時に直してくれるの?」とか「急に互換性が壊れることはないのか?」という懸念もあると思います。今まではこういう話をあまりしたことがなくて、ドキュメンテーションにもあまりないと思うので、ちょっと共有させてください。リリースや互換性に対する考えです。

基本的には、Optunaはセマンティックバージョニングに従っていますというのが結論なのですが、今の最新のバージョンの2.8.0、2がMajor、8がMinor、0がPatchになります。

Patchは、Optunaはほぼ出しません。v1.0以降、たぶん1度も出していないと思います。本当に緊急性の高い修正などが考えられるかなと思います。

たぶん重要なのはMinorのほうで、今は定期的に約2ヶ月に1回リリースをするようにしています。なので、こういう周期でバグが修正されたり、新しい機能や改善が入って来ると思ってもらっていいかなと思います。

基本的にOptunaは、互換性はけっこう重要だと思っています。急に壊れるような変更は入れないようにしています。入れるとしても、Majorです。破壊的なエラーになってしまう変更や最適化の結果が変わってくる変更がこれに当たります。

このような破壊的な変更を入れる場合は、少なくとも早めに警告を出しつつ、Majorを1つ以上跨いで慎重に行っているので、急にみなさんのコードが壊れることはないと思います。ここは安心してもらっていいかなと思います。

逆に、実験的な機能は積極的に入れるようにしていて、主に研究や個人用途向けのものは、Experimentalの警告をコード、ないしはドキュメンテーションで言及しつつ入れているので、こういう機能が欲しいみたいなのは、どんどんPR出してもらえると、Experimentalとして早期導入できるかもしれません。

最後になりますが、Optunaは常にコントリビューションを歓迎しているので、ぜひPRやissueは構えずに出してください。すでに出してくれている方もいるかもしれません。引き続きよろしくお願いします。

具体的なステップは、Step-by-stepガイドを見てもらえるとありますし、例えば「PyCon」とかもあると思うのですが、そういうイベントにも積極的にみんなで出たいと思っているので、TwitterなどのSNSのアカウントもフォローしてもらえると、そういう情報もキャッチアップしやすいかなと思います。

Optunaの紹介は以上です。どうもご清聴ありがとうございました。

続きを読むには会員登録
(無料)が必要です。

会員登録していただくと、すべての記事が制限なく閲覧でき、
著者フォローや記事の保存機能など、便利な機能がご利用いただけます。

無料会員登録

会員の方はこちら

関連タグ:

この記事のスピーカー

同じログの記事

コミュニティ情報

Brand Topics

Brand Topics

  • 今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは

人気の記事

新着イベント

ログミーBusinessに
記事掲載しませんか?

イベント・インタビュー・対談 etc.

“編集しない編集”で、
スピーカーの「意図をそのまま」お届け!