【Grasshopper】Tunnyを使って最適化をやってみよう!

皆様こんにちは。
AMDlabの齋藤です。
今回はhironさんが作成されましたTunnyを使ってoptunaのブラックボックス最適化をやっていこうと思います。

今回のデータはこちらに挙げております。
https://github.com/AMDlab/TechBlog-Try-Tunny

インストール


まずはTunnyのインストールを行います。
food4rhinoもしくはRhinoのPackageManagerからインストールをします。

https://www.food4rhino.com/en/app/tunny

food4rhinoでのインストールは、上記URLを開き、ダウンロードを押すとGithubのページに飛びます。

このページの下に行くと以下のようになっています。

ここでAssetsの中の Tunny_v080.zip をクリックし、ダウンロードします。
ダウンロード後は他のghaと同じように、セキュリティを解除>zipの解凍>TunnyのフォルダをLibrariesフォルダに移動、させればインストールできます。

v081より前のバージョンでは次にpythonを入れます。
この処理はPackageManagerでのインストールでも必要です。
まず、サンプルファイルを開くか、Grasshopperを立ち上げ以下のようにGHを組みます。

そしてTunnyコンポーネントをダブルクリックすると、以下のようにPythonを自動でインストールしてくれます。

終わると以下のようにFinishと出ます。

終わったらインストールできているか確認します。
Librariesフォルダに入れたTunnyの近くに(PackageManagerの場合、 C:\Users\<ユーザーネーム>\AppData\Roaming\McNeel\Rhinoceros\packages\7.0\Tunny\0.8.0 に)
python-3.10.0-embed-amd64 のフォルダがあるかと思います。

その中の Lib\site-packages 内があるか確認してください。
無い場合は再度インストールするか、
python-3.10.0-embed-amd64\Scriptsに移動し、そこのパスをカレントディレクトリとしてcmdもしくはpowershellを起動し、
以下を入力します。

これを実行すれば、再度インストールが動きます。

※v081はpython自体を配布したため、上記が必要無くなりました。

最適化させたいGH


それでは最適化をさせたいGHを作っていきます。
今回はNurbs Surfaceをグリッド上で点を取ってラチスシェルを作り、その部材長が同じ長さになるように最適化をさせようと思います。

以下のGHを組みます。

順に説明します。

①Nurbs Surfaceの作成

まず、全体で10m(10,000mm)、4分割のグリッドをSquareで作ります。
次にMoveで今回の変数であるGenePoolの値分Z方向に動かします。
最後にSurface From PointsでNurbs Surfaceを作ります。
作成できると以下のようなデータができます。選択しているものは見やすいように別途作成したものです。

②ラチスシェルのグリッド

ラチスシェルのグリッドを作ります。
Nurbs Surfaceのグリッドと同様に今度は10分割します。
その後Nurbs Surfaceにその点を写すため、z方向へのLineに直しています。
作成できると以下のような低い線分がグリッドに並ぶデータができます。

③ラチスシェルの作成

ラチスシェルを作成します。
Surface|LineでSurface上にグリッドを写します。
そのあと、指定した節点を無理やりZ座標を移動させて固定します。これでラチスシェルの節点ができます。
次にPartition Listで節点を行列ごとにTreeに当てはめます。
あとは隣り合う節点をつなげて梁を作ります。
これでラチスシェルの梁ができました。
作成できると以下のようなSurface上に節点が置かれているラチスシェルができます。

④部材長一様化

最後に部材長が近ければ数値が低くなる関数を作成します。
今回は標準偏差を取って計算しました。

以上で最適化をさせたいGHができました!
では最適化をしてみましょう。

最適化


それでは最適化をします。
まず、TunnyにVarsが変数、Objsは目的関数へつなぎます。
つなげるものはできるだけ名前を付けてあげるとよいです。

そして保存を行います。
GHでの最適化でなくても、最適化では処理が重くなりやすく、さらに時間もかかる、パソコンが落ちる可能性もあるため、保存は大切です。
しっかり保存しましょう!

では、TunnyをダブルクリックしてFormを起動させます。

まず最適化をするSolver(Sampler)を決めます。
今回は単一目的であるため、 Evolution strategy(CMA-ES) を選択しました。

このあたりの選択はHironさんのFlow Chartを確認してください。

あとはStudy Nameを入れてRunOptimizeさせます。
押したあと少し時間が空いて動き始めます。

実行すると下側にあるタスクバーが動いて計算が回ります。

解析が終わると以下のダイアログが開きます。

OKを押して結果を確認してみましょう。

結果を見る


VisualizeタブのOpen Optuna-Dashboard(GHウインドウ上のTunnyからでもよい)を押して開きます。

するとブラウザが開きます。ここで先ほど名前を付けたStudy Nameを開きます。

するとこのような画面が表示されます。
このあたりはoptuna自体のビューになるため、具体的な説明はOptunaのDashBoardを調べてみてください。

一旦最適化を続けてみます。
Dashboardと同時に開かれたコマンドプロンプトを閉じず、Rhinoに戻ります。
Optimizeタブに戻り、Study NameのContinueにチェックを付けてExisting Studyを先ほどのStudy Nameにします。

あとは、再度解析を回します。
今回は追加で900回回して1000回にします。

解析が終わったらまたDashboardを確認してみます。

Historyではうまく最適化できているように見えます。

最後に結果を呼び出そうと思います。
最適な結果は解析が終わったあと自動的にその結果になります。
ですが今回、最適な結果を呼び出します。
Dashboardの下にあるBest Trialを見てみます。

number=919がより良い結果のようです。
それではそれを元に結果を呼び出します。
Tunnyフォームに戻り、OutputタブでTarget Studyを今回のStudyに設定します。

あとはUse Model Numberを919に設定して、Reflect the result on the slidersで結果を表示させます。
少し時間がかかりますが、ここで閉じてしまうと結果自体が開けなくなることもあるので、ゆっくり待ちましょう。
終わると以下のダイアログが開きます。

このように結果が見られました。

他にできること


最適化の初期値を入力できます。
Construct Fish Eggを使って行います。
以下のようにGHを組んでLayのボタンを押すと設定されます。
解除はClearで可能です。
あとは出力をTunnyのVarsに入れれば完了です。

Attributeを追加できます。
そこではGeometryで最適化中のGeometryをFish内に保存できます。
制約もかけることができます。Constraintに1つだけ0未満になるようにかけられます。

8/3 追記
v0.8.0からは複数の制約条件に対応できるようになったようです。
できる最適化が増えました!
https://twitter.com/hiron_rgkr/status/1686536311296180226

Attr~で数字も保存できます。Mergeコンポーネントと同じように入力を増やすことができます。
以下のようにつなげて使います。

Dashboard以外でも結果を表示できます。
今回はoptimization historyを表示させてみます。
VisualizeタブのTarget Study、Visualize Typeで見たいStudyとどういう結果を見たいかを設定し、Target Objectiveで今回の目的関数を指定し、
Showで表示します。

以下のようにブラウザで表示されます。

全ての結果を出すことができます。Target Studyで結果Studyを選択しAll trialsで結果を出します。

Fishesに結果が出ます。

あとはDeconstruct Fishで結果をみます。

おわりに


今回はTunnyを使ってみました。
ただ、使い方だけでかなり書いてしまったのでTunny-Optunaが得意とするベイズ最適化関連まで行けなかったです。
さらに0.8.0からHuman in the loopまで実装されていますが、こちらも入れられませんでした。
他最適化したいモデルが見つかったらそのあたりも記事にしようと思います。

参考

Tunny関連
v0.4.0時点のTunny

https://tunny-docs.deno.dev/
https://optuna.org/

最適化関連
この記事は以下を参考に作成しました。しかし、節点の算出方法等違う部分があります。
藤田 慎之輔, 大崎 純, パラメトリック曲面で定義されたラチスシェルの部材長一様化と剛性最大化を目的とした形状最適化, 日本建築学会構造系論文集, 2013, 78 巻, 685 号, p. 495-502, 公開日 2013/06/03, Online ISSN 1881-8153, Print ISSN 1340-4202, https://doi.org/10.3130/aijs.78.495https://www.jstage.jst.go.jp/article/aijs/78/685/78_495/_article/-char/ja

ARTICLES