はじめに
Project Bonsaiについて調べてみましたの3回目です。
過去の内容はこちら。
1回目は「Bonsaiを触ってみる」
2回目は「Bonsaiをいじってみる」
前回は、教育カリキュラムをいじってみたので、今回はシミュレータを触ってみたいと思います。
Bonsaiって何?
Microsoftが提供している自律システム向け機械教示サービスです。(現在はPublic Preview)
産業制御システムに焦点を当てた汎用ディープ強化学習プラットフォームのようです
Bonsaiのシミュレータ
Cartpoleのチュートリアルは、すでにシミュレータも用意されていますが、基本的には自分で用意する必要があります。
サポートされているソフトウェア
- MATLAB Simulink
- AnyLogic
- VP Link
- Docker でコンテナー化されたカスタムのコンテナー
APIによるPythonやRESTのサポートもあるようですが、一からの作成だとなかなかお手軽にできる感じではありません。
実は、Cartpoleのシミュレータのソースコードは、公開されています。
今回は、このソースコードを、ローカル上で動かすアンマネージシミュレータを試してみたいと思います。
ローカル環境でシミュレータを動かす
今回チェックをした環境及び、使用したソフトは以下の通りです。
- Windows10 Pro 21H1
- Visual Studio Community 2019 version 16.9.6
BonsaiのIDとキーの取得する
BonsaiのWorkspcaeIDと、AccessKeyを取得します。
BosnsaiのWebページの右上にあるアカウント情報をクリックし、メニューから、「Workspace info」を選択します。
Workspace Infoが表示されたら、WorkspaceIDをメモします。
AccessKeyは、右下にある「+ New access key」をクリックすると画面上に表示されます。
セキュリティ上、AccessKeyは、一度だけしか表示されません。もしキーを紛失した場合は、再度発行処理を行ってください。
シミュレータのソースコードを取得する
BosnsaiAPIのGitHubページからソースコードを取得します。
CSharpやJava、Pythonなどのサンプルがありますが、今回はCSharpを使用します。
BonsaiのIDとキーを設定する
取得してきたソースコードの中にある「Microsoft.Bonsai.Api.Samples.Cartpole.sln」ファイルをVisual Studioで開きます。
メニューより、プロジェクトのプロパティを開き、環境変数の項目に以下を追加します。
名前 | 値 |
---|---|
SIM_WORKSPACE | Bonsaiで取得したWorkspcaeID |
SIM_ACCESS_KEY | Bonsaiで取得したAccess key |
ここまで出来たら準備万端です。
「F5」を押すか、メニューから「デバッグの開始」を選択します。
実行すると「コマンドプロンプト」が表示され、Bonsaiからの指示待ち状態になります。
※赤線の部分は、Bonsaiのシミュレータ画面の名称の一部として表示されます。
Cartpole学習の準備をする
ローカルシミュレータの連携確認
プロジェクトを実行すると、BonsaiのSimulatorsの一覧に「Cartpole-CSharp-Unmanaged」 が追加されます。
赤線の部分は、「コマンドプロンプト」の起動時に表示されたものと同じ内容が表示されます。
もし、表示されていない場合は、WorkspcaeIDや、AccessKeyが間違っていないか確認してください。
教育カリキュラムを作る
ローカルシミュレータを使用するCartpole用教育カリキュラム作成します。
「+ Create Brain」を選択し、チュートリアル用のCartpoleを追加します。
作り方は「Bonsaiを触ってみる」を参照ください
今回は、「Cartpole Trial Unmanaged」という名前で作成しています。
シミュレータの変更
そのまま使うと、チュートリアルのシミュレータと連携するので、ローカルのシミュレータに接続できるように教育カリキュラムを修正します。
source simulator (Action: SimAction): SimState {
package "Cartpole"
}
source simulator (Action: SimAction): SimState {
}
使用するシミュレータのpackageを削除します。
削除することで、学習開始時にシミュレータを選択することが可能になります。
学習を開始する
「Train」をクリックすると、シミュレータを選択するポップアップが表示されるので、「Unmanaged simulators Cartpole-CShape」をクリックします。
選択すると、学習が開始されます。
この後は、基本的にチュートリアルの学習時度の動作と同じです。
チュートリアルと大きく違うのは、実行速度です。
ローカルで実行しているためシミュレータ数が1個になります。
実行速度も1秒間に5回程度となり、かなり遅いです。
※チュートリアルだと、35インスタンスで、1秒間に300回程度実行されていました。
同じ結果になるか、気長に待つとします。
まさかのエラー
6時間近くシミュレータ動かしてたのに。。ひどすぎる。。
課金の額を見るのが怖いのに。。
シミュレータをデバッグする
コノヤロー!ってことで、終わってもよかったのですが、
原因が知りたいのでデバッグしてみます。
Bonsaiには、シミュレータをデバッグする仕組みが用意されているようなので、少し試してみます。
デバッグ画面は、Simulatorsから、Cartpole-CSharpを開き、Debuggerタブを選択することで表示されます。
デバッグ画面で使用するのは、4つです。
- デバッグのタイムライン
- タイムラインの操作パネル
- シミュレータへの送信情報
- シミュレータからの受信情報
デバッグのタイムライン
4つのEventTypeを組み合わせて、学習動作を再現します。
Startと、Finish、Unregisterの登録は必須です。
Unregisterは、Finish後の設定が一般的な様です。
Stepは、一回の学習を意味します。
補足)Unregisterは、無くても動作しています。Unregisterの実行後にローカルシミュレータとの接続がきれるので無いほうがデバッグしやすいかも。。
「+」ボタンを押すことで、タイムライン上に項目を追加し、EventTypeのラジオボタンを選択することで、種類を変更することができます。
今回は、「Start」「Step」「Finish」「Unregister」を登録します。
ちなみに削除したいときは、タイムラインの項目を選んで、Backspaceです。
タイムラインの操作パネル
タイムラインの実行や、ステップ実行、リセットなどの動きを操作することができます。
シミュレータへの送信情報
シミュレータへ送信するJSON形式の情報を設定することができます。
「Start」では、シミュレータのSimConfigにあたる設定、Stepでは、SimActionのあたる値の設定可能です。
今回は、Stepの項目を以下のように修正します。
{
"type": "EpisodeStep",
"episodeStep": {
"action": {}
}
}
{
"type": "EpisodeStep",
"episodeStep": {
"action": {
"command:"1
}
}
}
「右にcommand:1で進めろ」という命令を設定しています。
シミュレータからの受信情報
Bonsai側からの操作に対するレスポンスの情報が表示されます。
Stepの場合は、シミュレータの実行結果になります。
###デバッグを実行
準備ができたので、デバッグを開始します。
まず、ローカルのシミュレータと接続するために、「Start session」をクリックします。
接続ができた場合は、ボタンが「End session」に変わり、Simulator StatusがIdleに変わります。
次に、タイムライン上の「-R」を選択します。
選択すると、「Reset」や、「Step」、「Run」が選択可能になります。
「Step」は、タイムライン上の項目を一つずつ実行、「Run」は、連続で実行します。
「Run」ですべて実行してみます。
エラーが発生。。
エラーがでましたが、問題のエラーと違いますね。。
※前回は通信系のエラーだったけど、今回はParseに失敗してる系?
動作ログを見ると、EpisodeStep
までログが出てるので、Finish
で失敗していることがわかります。
System.AggregateException: One or more errors occurred. (Unable to deserialize the response.)
Exceptionの内容を確認すると、Deserializeに失敗している事が見えます。
Exceptionログをもとに、Visual Studioでブレイクポイントを張って詳しくデバッグしていきます。
ローカルなので、細かくチェックできるのは便利です。
原因発覚
原因がわかりました。
タイムライン上で追加されるFinishのJSONの入力値が問題でした。
仕様を確認してみると、EpisodeFinish
なんて無いじゃないですか。。
{
"type": "EpisodeFinish",
"episodeFinish": {
"reason": "EpisodeComplete"
}
}
{
"type": "EpisodeFinish",
"episodeFinish": {
"reason": "LessonChanged"
}
}
パラメータに説明がないので、とりあえずLessonChanged
に変えます。
再度実行!
修正後、再度デバッグを実行しました。
今回は無事成功、コマンドプロンプトには各操作のログが表示され、エラーは出てないです。
ってことは、シミュレータの問題ではなくて、やっぱり通信が原因だったんでしょうか・・(ログ残してたらよかった・・)
まとめ
とりあえず、自分でシミュレータを用意して動かす&予想外のデバッグまで試してました。
学習時のエラー(たぶんタイムアウト系・・?)と、デバッグでのエラーは違うと思いますが、デバッグのやり方を理解できたのでよしとします。
再度動作の確認をしたいのですが、ちょっと時間とコストが割に合わないです・・。
今回は、Visual Studioから直接実行しましたがDockerのコンテナにすることで、スケーリング可能なマネージドのシミュレータとしてBonsaiに登録できるそうなので、それをしないと使い物にならないかなと思います。