ニューラルネット(NNSYSID / NNCTRL)でシステム同定 + 制御

TKK (ヘルシンキ工科大)で取ったゼミのテーマ。日本で僕の周りだとニューラルネットは分野によっては時代遅れ? みたいな話も聞かないではなかったけど、制御の分野では実用面で重要な地位を占めてるみたいです。何よりも実際に学習が進んでシステム同定や制御出来るのは楽しいです。
しかしこの分野、ブラックボックスにデータをほいっとつっこめば同定できる訳ではないのがやや面倒なところ。パラメーター選択には勘と経験と先人の知恵が必要です。そしてこのへんが一番のウィークポイントだと思います…
(徹夜でレポート出したけどいちお起きている方がいいと思うので、覚えているうちに書けるだけ書いてみる。)

ニューラルネットで何ができる!?

ニューラルネットとは、ニューロンのネットワークです。ニューロンとは…いくつかの入力を持って、一つの出力を持つ関数です。ネットワークというのは、出力と入力がつながっているという意味です。一つ一つのニューロンは主にシグモイド関数と呼ばれる関数で出来ています。これは実に単純なものです。あとネットワークのそれぞれの線には重みと呼ばれる値がついています。ではこれをつなぐと何が起こるのか… 元々は単純な関数だったニューロンですが、たくさん接続することで世の中の様々な関数を近似できるのです。しかも、その近似の方法が割と簡単に計算できます。そこで、 とすると、色々面白いことが出来ます。分かりやすく言えば、元々あったデータをコンピューターに「学習させる」ことが出来るわけです。学習といってもコンピューターがいきなりピアノを弾いたり話したりできるようになるわけではなく、「あるデータを見せると、それにちょうどいい値を答える」のが基本。例えば二足歩行だったら、今の位置と体の色んな場所の速度と加速度が決まれば、そのときに取るべき体の動かし方が決まります。(右斜め前に10度かがむ、とか) これを前もって学習させておくと、どんな体勢になっても立ち続けるロボットを作ることが出来ます(というか、出来るはずです) これが20年ほど前に一大AIブームを作った!?(そのへんの事情はよく知りません。違ってたらごめんなさい)

しかし、ニューラルネットは今のところそんな夢のような方法ではないことが分かっています。先ほど「どんな関数でも近似できる」と言いましたが、これは逆に言うとすごく自由度が高いということです。そんな自由度が高いシステムを学習させて、一つの学習結果に定まるのかというと…定まりません。往々にして学習の結果は毎回違うバラバラなものになります。というか適当にニューロンを並べて「さあ学習」とやっても、目指す関数が得られる可能性はほぼ0です。そこで、何らかの前提知識を導入する必要が生じます。「このシステムはこのくらいの複雑さだからここにこのニューロンを配置して…」学習の際にも、状況によっていろいろなパラメータをチューニングする必要が生じます。…めんどい。それに前提知識を大量に使うなら、初めからその知識をロボットなり機械なりに組み込んだらよかったのかも…

というわけでやや下火になった感もあるニューラルネットですが、ある程度類似していて、かつ毎回同じ関数を使い回すわけにはいかないような問題では実用的に使われています。無限の可能性を生かすのは大変でも、ある程度限られた用途であれば楽に使えます。
今回は制御理論でニューラルネットを使う試みを説明します。制御理論それ自体も複雑で面白い分野なのですが、僕は授業さぼり気味だったのであまり分かってない。でも古典的な制御理論は直接使うわけではないので無問題…のはず。ちょっとしたセンスが欲しいことはしばしばあるけど。

制御の基本

制御とは、何か入力があって出力があるとき、入力を「うまく」決めることで希望の出力を得るものです。制御は何かを生み出す作業ではなく、「あるものをうまく使えるようにする」ものです。だから、制御というのは本質的にシミュレーションに向いています。そこにあるのは抽象的な「入力」の数値と、「出力」の数値だけだからです。だから、制御理論をやっている人は実際の機械を始終相手にしているわけではありません。実際にやっているのは、実際の機械から取ってきたデータを元に「こうしたらどうなるだろう」「これはどうだろう」と数字をいじっています。たぶん。なぜかというと、実際のシステムは動かすのがまず大変だし、測定するのはもっと面倒だからです。机(パソコン)の上で一生懸命計算して、準備万端整ってからはじめて実際の機械やシステムに当てはめます。そのときちゃんと実際の機械で動かなければ、そのデータをちゃんと測定して「うーん」と悩みます。その繰り返し。
…何か抽象論になってしまいました。いやそうではなくて、制御理論は入力があって出力がある関数だ、ということが言いたかったのです。制御の基本はフィードバックです。これは、希望する値と実際の値の差を元に、次の制御信号を決めるものです。(もちろん他の要素も考えには入れます) この方法は基本的にうまくいくのですが、理想の信号から「ずれ」ないと追従してくれません。つまり、100%目標に沿った制御は不可能なのです。
でも、予め操作するシステムとか目標の信号が分かっていれば、わざわざずれを用いなくても最適な制御ができるはずです。そのためには実際のデータをもとにシステムがどのような性質を持っているのかを知る必要があります。そうすると、概念的に言うとコンピューターの中にそのシステムを完全にシミュレートすることがてきます。そうすると、次にどういう入力を入れたら目標値にぴったり沿うのか分かります。これが最適制御などと呼ばれる、ちょっと新しい制御の方法です。
この最適制御を行うためには、予めシステムのモデルを知る必要があります。これが「システム推定」と呼ばれる問題で、実験によって得られた入力と出力の組を元に中身の関数を推測します。ここにニューラルネットが使えないかな? というのが今回のテーマ。あと、制御自体にもニューラルネットを使ってしまいます。

何をするのかちょっとまとめ

ちょっと問題を整理してみます。
ここに何かシステムがあります。例えば、ヒーター(電圧と室温)とかエンジン(燃料の量と出力)リニアカー(浮上距離と電磁石の電圧)とか。ここでやりたいことは、室温とか浮上距離とかを目標値に定めることです。(以下、ヒーターの場合に絞って話します) そのために電圧を制御したい。でも実際に実験できる機会は限られている。そこで適当に電圧を動かして、温度の変化を記録します。この時の電圧の動か方は、発散したりずっと一緒とかでなければ適当で大丈夫です。このデータを元に、ヒーターと部屋を合わ1せたシステムを数式で表してみる。そうすると、「30秒100Vかけて、20秒止めたら室温は何度になるか」みたいなのが計算で求まります。逆に言うと、室温を25度に保ちたければこうする、というのも計算できます。これが最適制御です。
というわけで仕事をまとめると、以下のようになります。 このような目的に使えるソフトウェアとして、今回は NNSYSIDNNCTRLを用いました。 Matlab用に書かれています。 どちらもよくまとまっていますが、Matlabのバージョン違いとかで時々エラー出します。 下位互換性とか考えてくれないのかなぁ…

NNSYSIDでシステム推定

まずはインストールです。どちらも同時にしちゃいましょう。 先ほどのページから圧縮ファイルを落としてきて解凍して、適当なディレクトリに解凍します。どちらもバージョン2.0を用いました。そのあと、NNSYSID20ディレクトリ、NNCTRL20ディレクトリ、NNCTRL20/CTRLTOOLディレクトリにパスを通します。パスの設定はmatlabのメインウィンドウの左上のメニューをクリックしたら見つけられました。この設定はmatlabコマンドを起動したディレクトリのpathdef.mに保存されるので、次回も同じ場所からmatlab起動するようにしましょう。(Widowsの事情はちょっと分かりませんが、起動ディレクトリというものは意識しなくていいと思う) この状態でtest1とかtest2って打つと、システム推定のデモが動くはずです。同様にinvtestとかopttestとか打つとシステム制御のデモが動きます。
このスクリプトの実体はNNCTRL20/CTRLDEMOとかにあります。