Grasshopper (.ghx) 最適化
本節では、Grasshopper 定義ファイル(.ghx)を使った最適化の実行方法を紹介します。
Tunny Dashboard は最適化結果の分析だけでなく、最適化の実行そのものにも対応しています。 変数や目的関数を Tunny コンポーネントに接続し、Tunny で最適化を実行できる状態にした Grasshopper 定義であれば、.ghx 形式で保存して Dashboard にドロップするだけで実行できます。 Dashboard がサンプラーで変数の値を提案し、Rhino.Compute を通じて 1 トライアルずつ評価する最適化ループを回します。 実行時に Python や Optuna のインストールは不要です。 結果は Optuna 互換の journal ファイルとして書き出されるため、ライブ更新やすべての分析ウィジェットを、ほかの Study と同じようにそのまま使えます。
以下のような流れで最適化を実行します。
- 変数と目的関数を Tunny コンポーネントに接続し、最適化可能な状態の定義を .ghx 形式で保存
- Rhino.Compute を準備
- .ghx を Dashboard にドロップし、設定モーダルで最適化を設定
- 最適化を実行し、結果をライブ更新で確認
必要な環境
Grasshopper 定義の評価には、Rhino.Compute を使用します。 Rhino.Compute は Rhino の機能を HTTP 経由で呼び出せるサーバーで、Windows 上での動作が前提です。 Dashboard は定義の読み込みと最適化ループを自前で行うため、Dashboard を動かすマシンに Rhino 本体は不要です。
Rhino.Compute をもっとも簡単に入手する方法は、Grasshopper のパッケージマネージャから Hops をインストールすることです。 Hops と一緒に Rhino.Compute の実行ファイル一式もインストールされ、次のパスに配置されます。
%AppData%\McNeel\Rhinoceros\packages\<Rhino のバージョン>\Hops\<Hops のバージョン>\rhino.compute\rhino.compute.exe後述する Launch EXE 方式では、このパスをそのまま指定できます。
接続方法は次の 2 つから選べます。
- Launch EXE:rhino.compute.exe のパスを指定し、実行時に Dashboard が起動と停止を行う
- Server URL:起動済みの Rhino.Compute の URL(デフォルト
http://localhost:6500)へ接続する
Launch EXE を選ぶと、Dashboard は指定されたポート(デフォルト 6500)で Rhino.Compute を起動します。 起動後は応答が返るまで最大 180 秒待ってから、最適化を始めます。 最適化の終了時には、起動した Rhino.Compute を自動で停止します。
なお、このパイプラインは Rhino 8.31 の Rhino.Compute と Hops 0.17 の組み合わせで動作検証されています。 検証に使われた .ghx は、Grasshopper 1.0 で保存されたものです。
Grasshopper 定義の認識ルール
Dashboard は .ghx の XML を直接読み取り、Tunny コンポーネントへの配線から最適化問題を抽出します。 名前やニックネームに「tunny」を含むコンポーネントを Tunny コンポーネントとして検出し、その入力ごとに次の要素を認識します。
| 入力 | 認識される要素 |
|---|---|
| Variables | Number Slider(1 つで 1 変数)と Gene Pool(遺伝子 1 つで 1 変数) |
| Objectives | 配線されたパラメータ(NickName が目的関数名になる) |
| Attributes | Construct Fish Attribute コンポーネント経由の Constraint 入力(制約)と Attribute 入力(属性) |
つまり、Grasshopper 上で Tunny による最適化を通常どおり設定してあれば、特別な命名規約やコンポーネントの追加なしにそのまま実行できます。 逆に言うと、Tunny コンポーネントがキャンバスに置いてあるだけでは実行できません。 Variables 入力に Number Slider(または Gene Pool)が、Objectives 入力にパラメータが 1 つも接続されていない定義は、ドロップ時にエラーになります。 ドロップする前に、その .ghx が Grasshopper 上の Tunny で最適化を開始できる状態になっていることを確認してください。
変数の範囲と桁数は Number Slider の設定(Min / Max / Digits)から取得し、Digits が 0 のスライダーは整数変数として扱います。
制約は Tunny と同じソフト制約の規約に従い、すべての制約値が 0 以下のときにそのトライアルを実行可能(feasible)とみなします。 制約を満たさないトライアルも評価と記録は行われ、違反量が NSGA-II の探索を実行可能領域へ誘導するために使われます。 Attribute 入力に配線した値はトライアルごとのユーザー属性として記録され、ユーザー属性に対応するウィジェットで確認できます。
注意点として、目的関数の最小化と最大化の方向は .ghx から読み取れません。 Tunny コンポーネント内部の方向設定には、安定したシリアライズ形式がありません。 そのため Dashboard はすべての目的をいったん Minimize として表示し、設定モーダルでの編集に委ねています。 最大化したい目的がある場合は、実行前に必ず方向を変更してください。
設定モーダル
.ghx ファイルをウィンドウへドラッグ&ドロップするか、Open ダイアログで選択すると、「Grasshopper Optimization」モーダルが開きます。 モーダルには抽出された問題の内容が表示され、次の項目を設定できます。
- Objectives:目的ごとに Minimize / Maximize を選択
- Rhino.Compute:接続方式(Launch EXE / Server URL)、ポート、API key、並列数(Max parallel、1〜16、デフォルト 4)
- Sampler:サンプラーの種類と設定、乱数シード(デフォルト 42)
- Output:journal ファイルの保存先と Study 名
変数と制約、属性の一覧は読み取り専用です。 内容が想定と違う場合は、Grasshopper 側の定義を修正して保存し直してください。 抽出時に問題があった要素は、モーダル上部に警告として表示されます。
API key を入力すると、リクエストの RhinoComputeKey
ヘッダーとして送信されます。 認証を設定していない Rhino.Compute
へ接続する場合は、空欄のままでかまいません。
journal の保存先は、デフォルトで .ghx と同じフォルダの <ファイル名>_optuna.log
になります。 Study 名には、ファイル名と実行時刻から生成した名前が入ります。
サンプラーの選択
Sampler セクションの Method で、次の 3 つから選択します。
| サンプラー | 設定項目 | 向いている場面 |
|---|---|---|
| NSGA-II(デフォルト) | Population(デフォルト 16)、Generations(デフォルト 10) | 単目的・多目的の全般、制約付き問題 |
| Random | Trials(デフォルト 50) | ベースラインの取得、探索空間の把握 |
| Adaptive (surrogate) | 初期トライアル数、バッチサイズ、反復回数、早期停止 | 1 評価が重い問題で評価回数を抑えたい場合 |
NSGA-II を選ぶと、Population と Generations から計算した総評価数が「Total evaluations」として表示されます。 評価 1 回にかかる時間と掛け合わせることで、実行前におおよその所要時間を見積もれます。
Adaptive (surrogate) は、いわゆるアダプティブサンプリング(ベイズ最適化)に相当するサンプラーです。 まずランダムサンプリングで初期トライアル(最低 10 件)を評価し、その結果に目的関数ごとのサロゲートモデルを自動選択でフィットします。 その後は獲得関数(単目的は EI、多目的は EHVI)が提案する候補をバッチ単位で評価し、モデルの再フィットを繰り返すことで、少ない評価回数で有望な領域へ探索を集中させます。 「Stop early on convergence」を有効にすると、指標の改善が指定した割合を下回る状態が連続したときに、反復回数を残していても自動で停止します。
実行と結果の確認
Run を押すとモーダルが閉じ、画面右下に進捗オーバーレイが表示されます。 Study は実行開始と同時に journal へ作成され、ライブ更新が自動で有効になるため、トライアルが完了するたびに結果がダッシュボードへ流れ込みます。 Optimization History や Pareto Scatter などのウィジェットを配置しておくことで、最適化の進み具合をリアルタイムで確認できます。
進捗オーバーレイの Cancel ボタンで、実行を途中で中止できます。 キャンセルは実行中の Rhino.Compute 呼び出しの完了を待ってから反映され、キャンセルされたトライアルは journal に記録されません。 完了すると、成功と失敗のトライアル数がオーバーレイに表示されます。
実行後の分析の進め方は、分析ワークフローを参照してください。
Rhino.Compute に送信される定義の確認
実行時に Dashboard
は、変数の注入口(RH_IN)と結果の取り出し口(RH_OUT)を組み込んだ定義のコピーを生成します。
このコピーは、journal と同じ場所へ <journal 名>.compute.ghx
として保存されます。 Rhino.Compute
で実際に評価されるのはこのファイルのため、意図しない結果が出たときは、このファイルを
Grasshopper で開いて配線を確認できます。
なお Gene Pool は、Rhino.Compute
からの値の注入に対応していないため、内部的に通常の Number
パラメータへ置き換えられます。 .compute.ghx を開くと Gene Pool
が別のパラメータになっていますが、これは意図した動作です。
注意点
- バイナリの .gh は非対応:Grasshopper で「Save As」から .ghx(Grasshopper XML)形式を選んで保存し直す。.gh をドロップすると案内メッセージが表示される
- 1 トライアルのタイムアウトは 300 秒:これを超える評価は失敗として記録される
- 評価値が数値でない場合は FAIL:出力が空、NaN、無限大のトライアルは失敗として記録され、最適化は継続する
- 名前の重複は自動リネーム:変数・目的・制約・属性の名前が重複すると
_2、_3のような接尾辞が付く - ポートの競合:Launch EXE で Rhino.Compute が起動直後に終了する場合は、指定ポートが使用中でないか、実行ファイルのパスが正しいかを確認する
- 並列実行時の負荷:Max parallel を上げると評価は速くなるが、Rhino.Compute 側のメモリと CPU 負荷も増える
まとめ
本節では、.ghx ファイルを使った Grasshopper 定義の最適化を紹介しました。
- ドロップするだけで実行:Tunny の標準的な設定をそのまま認識し、追加の作業は不要
- 実行環境は Rhino.Compute:Dashboard 側に Rhino や Python は不要
- 結果は Optuna 互換 journal:ライブ更新と全分析ウィジェットが最適化中から使える
- サンプラーは 3 種類:NSGA-II、Random、Adaptive (surrogate) を問題に応じて選択
最適化の実行から結果の分析までを 1 つのアプリケーションで往復できることで、「実行して、分析して、次の最適化を設計する」というサイクルを短く回せます。 Grasshopper を使わない外部ツールを同じ仕組みで最適化する方法は、外部ツールの最適化で紹介します。