MATLAB ユーザーコミュニティー

MATLAB & Simulink ユーザーコミュニティー向け日本語ブログ

強化学習による制御設計

本日は、”toshi | Simulink の中の人” さんからの記事です。彼の記事はいつも教育的要素が満載なので楽しみにしています。


こんにちは。アプリケーションエンジニアリング部の toshi | Simulink の中の人です。以前は加速度センサーの物理について説明したり、Simulinkの新機能を紹介したりしましたが、今回は本業の制御設計のお話、しかも強化学習という先端AI技術を使ったお話になります。

概要

2021年9月8日にディープラーニングのセミナーシリーズとして、「強化学習を用いた実用的な制御設計」というセッションを担当させていただきました。その動画が以下になります。モデルも File Exchange / GitHub で公開しています。

このセミナーにて、倒立振子の実機を使って、強化学習の制御を検証する、ということを行いました。強化学習の制御検証については、シミュレーションのみで、実機で行われた例は少ないです。当社 MathWorks の中では、実は初とのことです。

この制御をどのように実現させたのかについて、動画では語られなかった裏側をご紹介します!

(注)事前に動画を見ていただいた方が、本記事の内容を理解しやすいかと思います。

強化学習とは

最初に、強化学習とは何かについて説明します。強化学習は機械学習の一種です。とてもざっくり分類すると、機械学習を「強化学習」と「それ以外の機械学習」の二つに分けることができます。そして、それぞれに対して深層ニューラルネットワークを使った”深層化”を行うことができます。呼び方はいろいろありますが、ここではそれぞれ「深層強化学習」と「通常の深層学習」と呼ぶことにします。

「通常の深層学習」は、例えば以下のようなことができます。

自動車の画像が入力された時、その画像が “Car” であることを判定し、その文字や番号を出力します。それに対して、「深層強化学習」は、以下のようになります。

強化学習は、常に環境との相互作用を行っています。環境から位置や角度の情報を得て、その状態における最適なアクセル量やステアリング角を出力します。そしてその出力は、環境にフィードバックされています。

従って、強化学習は常に環境と相互作用をしながら学習するアルゴリズムです。そして、学習後もこの相互作用を行う形で実装されます。この形は、まさにフィードバック制御器の構造そのものですよね。なので「強化学習は制御設計に使える!」という話になっているわけです。

物理モデリングとフィードバック制御設計

今回、その深層強化学習を制御に用い、実機検証まで行うことを目標にしました。実機は、Quanser 社の「QUBE – Servo 2」という倒立振子の装置を用います。制御ボードは「QFLEX 2 Embedded」を用い、「Raspberry Pi 3 Model B+」と接続し、制御を実行します。

「QUBE – Servo 2」の構造は、以下のようになっています。

入力するモータートルクは1箇所であり、回転する部分は2箇所あります。計測できる角度も、その2箇所になります。この構造は、制御工学の用語で言うと、劣駆動と言います。要するに、ちょっと難しいやつ、ということです。

制御設計を行うためには、まずはシミュレーションモデルが必要です。この振り子のモデルを Simscape Electrical™、Simscape Multibody™ を使ってモデル化しました。上記の画像はそのモデルの画像です。

そしてモデルの妥当性を確認するため、簡単なフィードバック制御を構成し、倒立状態を維持できるかどうかを確認しました。加えて、QUBE – Servo 2 と Raspberry Pi が正しく動作しているかを検証するためにも、この段階で確認しておく必要がありました。

完成までいろいろありましたが、問題なく倒立させることができました(今回は強化学習がメインなので、詳細は割愛します)。

「そもそも、実機があるのだから実機で学習させればいいのでは?」と思う方もいるかもしれません。しかし、それは現実的ではありません。

今回のデモを完成させるまでに、5万~10万回ほどのエピソード実行を繰り返しました。この間、倒立振子装置を激しく動かしますので、±150degの位置にあるストッパーに必ず激突します。装置の損耗は確実に進み、おそらくデモが完成する前に壊れていたことでしょう。従って、学習はなるべくシミュレーションで行うべきです。

強化学習による軌道生成制御

今回行いたい倒立動作は、真下に向いている振り子を真上に向け、その角度を維持することです。早速強化学習を設計し、シミュレーションで学習をさせました。ところが、やってもやっても、全然うまくいきません。なぜできないのか考え続けた結果、得られた結論は「本モデルの倒立タスクは難しすぎる」ということでした。

何が難しいのかというと、例えばこのシステムには局所解が存在しており、そこにハマってしまうことです。4足歩行ロボットと比べれば遥かにシンプルな構造である今回のモデルでも、局所解があります。逆に、世の中でよく行われている4足歩行ロボットのモデルなどは、局所解が発生しないように、強化学習に都合よく設計されている、というのが私の見解です。

このよくある4足歩行ロボットのテンプレモデルは、歩行の速度制御を行っていません。その点が気に入らなかった私は、速度指令値を入れて制御できるようにしてみたのですが、局所解にハマって全然学習してくれなかったことがありました。

他にも、強化学習が苦手とすることがあります。長くなりますので、別に用意しました。こちらで解説していますので、興味がありましたら読んでみてください。

最終的には、強化学習単体で制御することは諦め、「強化学習による軌道生成制御」というアイデアのもと「倒立タスク」を要素分解し、PID制御と強化学習を組み合わせてそれを達成しました。こちらの方が、実際の制御の現場で採用しやすいです。詳細は動画で説明していますので、是非ご確認ください。

ちなみに、PID制御は5ms、強化学習のポリシーは20ms周期で実行しています。

強化学習エージェント

強化学習の学習アルゴリズムと方策(ポリシー)のセットをエージェントと呼んでいます。日進月歩で新しいエージェントが考案されています。ここは MATLAB で使える中で最新のものを選びましょう(記事執筆時点では R2021a が最新バージョンです)。今回は PPO と SAC を選びました。

私は強化学習の専門家ではありませんので、完全には理解できていませんが、SAC は特にダイナミックで複雑な動作を学習することに長けていると思います。よって、今回は”振り上げ”に SAC、”モード選択”に PPO を用いることとしました。

エージェントの設計は MATLAB のスクリプトで簡単に作成できます。ちなみに R2021a から GUI アプリが使えるようになりましたが、慣れるとコマンドの方が早いです(笑)。

報酬関数の設計

報酬関数は Simulink で設計できます。報酬関数が、強化学習の制御性能を決める最も重要な要素です。絶対的な形はありません。ひたすらトライ&エラーで調整を進めることになります。

報酬の設計は”コスト関数”と”成功報酬”の組み合わせが最もポピュラーです。”コスト関数”は、状態量とその目標値との差分を評価しています。連続的で安定した評価値を得ることができます。”成功報酬”は、あるゴールに達成した時に報酬を与えるという形です。不連続であり、そのゴールに達しないと全く報酬が得られないので不安定です。しかし、ゴールを見つけることができれば、それに向かう強いインセンティブになります。

今回のデモでは、モーター角度と振り子の角度を0に近づけるように報酬を設定します。結構シンプルな式で倒立を実現できましたが、これはタスクを分解したおかげだと思います。

学習結果

学習の過程で報酬がどのように推移したか、については「強化学習エピソードマネージャー」というウィンドウで確認できます。例えば”振り上げ”の学習結果は以下のようになりました。

タスク分割をする前は、これの失敗画面を何度見たことか分かりません。そしてこの1回の試行に10時間以上かかったりします。正直、「トライ&エラーに時間がかかる」という所が強化学習の一番嫌な所です(;-;)

完成した倒立動作は以下です。綺麗に持ち上げることができました。

Cコード生成とPIL検証

学習済みポリシーを得ましたので、いよいよ実機に実装します。ただし、いきなり実機に実装するのではなく、まず実装が成り立つのかを確認しましょう。今回のモデルは動画で説明しました通り、問題なく実装できることが分かりました。

ところで、強化学習のポリシーは簡単な深層ニューラルネットワークで構成されています。具体的には、全結合層と活性化関数です。全結合層は、

Out = W * In + b

を計算します。Wは重み行列、bはバイアスベクトルです。問題はその大きさですが、今回は強化学習でよく使われている300や400と言った行列サイズで設計しました。量産マイコンではきついですが、Raspberry Pi であれば大丈夫です。1ステップ当たりの計算時間は約2.68ms、CPU負荷率としては約13%でしたので、余裕をもって実行できます。

活性化関数は ReLU や tanh などを使います。従って、計算式はとてもシンプルで分岐も無いため、常に計算量は一定にできます。これは、リアルタイム実行に適用しやすい、良い特徴です。ちなみに、そもそも Linux で動いている Raspberry Pi がリアルタイム実行できるのか、という問題があります。リアルタイム性は PIL では確認できません。リアルタイムおじさんである私は、一応オシロを使って確認しました。結構ちゃんとリアルタイムでした!

実機検証

実機実行した結果、以下のようになりました。

綺麗にできましたね。実は、成功率は5割程度なのですが…

真下に向いて静止している所から振り上げるのも、途中振動している所から振り上げるのも何度か試しましたが、同じように5割は失敗します。「失敗」というのは、モーター角度が150°以上回転してしまい、台座に付けられているストッパーにぶつかったということです。安全のため、そこまで回ってしまったら強制停止させています。

シミュレーションでは初期状態を変えても綺麗に倒立させることができるので、ここはプラントモデルの誤差が効いていると思われます。一方で、もっとロバストな強化学習を考案する余地もあると思います。

まとめ

MATLAB と Simulink の機能をフル活用すると、AI をモデルベース開発のフローに落とし込むことができます、というデモでした。それに加えて、強化学習の制御設計実用化に向けて、重要な点を説明した資料でもあります。

今回のように本気で何かを作ろうとするとよく分かりますが、MATLAB というのはどこまでいっても”ツール”でしかありません。MATLAB ライセンスを所有しているからといって、強化学習でも何でも設計できるようになるわけではありません。その技術を学び習得しなければ、それを設計することはできないのです。

もし強化学習について興味を持っていただけたのであれば、当社の無料オンライン学習コンテンツ「強化学習入門」から学ぶことができます。また、今回私が構築したモデルは丸ごと File Exchange / GitHub で公開しています。是非ご活用ください。

最後まで読んでくださり、ありがとうございました。

|
  • print

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.