Robocodeはプログラマブルな戦車ゲーム
IBM社が開発した、Javaで戦車を自動コントロールするバトルゲームです。
https://robocode.sourceforge.io/
基本的には相手の戦車を倒すことを目的としますが、この記事では、そのrobocodeの独自の問題を設定し、AIについて学ぶことを目的とします。
問題設定:上下運動する戦車に弾を当てる
この動画の右側の戦車を作成します。左側の戦車は上下運動をしていて、それに対して弾を当てるのが右側の戦車の目的です。
robocodeの仕様から、戦車などに対する情報は、次のものを取得することができます。相手の戦車の情報は、グルグルと回しているレーダーに相手の戦車が引っかかったときに得られる情報です。
- 自分の戦車の位置
- 自分の戦車の向き
- 相手の戦車位置への自分の戦車からの相対的な方向
- 相手の戦車までの距離
- 相手の戦車の向き
- 相手の戦車の速度
詳細は、robocode apiのRobotクラス、ScannedRobotEventクラスを参照してください。
ここからまず、相手の戦車の絶対位置を求められます。
AIは次の情報を使って、相手の戦車に弾を当てようとします。
- 絶対位置
- 向き
- 速度
AIを使わない解法例(数学による解法)
敵戦車は移動し続けているので、レーダに相手の戦車が引っかかったときに、その場所に弾を撃っても当たりません。
そこで次の式を使って、戦車の移動先を予測します。このような予測方法を、線形予測と呼びます。
この予測によって作成された戦車は、上の問題設定のところで示した動画の戦車です。
命中精度
約0.21です。つまり100発撃つと、21発が当たることになります。
数学による解法の問題点
この線形予測だけだと、次の点に問題があります。
- 線形予測は、速度一定を想定しているので、相手の戦車が加速しているときは弾を当てられない。
- 相手の戦車が上下で回転しているときは、線形予測が出来ずに当てられない。
数学による解法も、もっといろいろとできると思うのですけど、ここら辺で次のAIによる解法に移ります。
AIによる解法
次のようにAIを学習させます。
- 相手の戦車の情報(位置、向き、速度)と、弾を撃つ方向、そしてその弾が当たったかどうかを記録する。これを学習データと呼ぶ。
- この記録から、分類学習を行う。
命中精度
約0.49です。数学による解法の0.21よりは向上しましたが、あまり高い数値ではありません。
この時点でのAIによる解法の問題点
学習データを、数学による解法の戦車を用いて作っていたことに問題がありました。
- 数学による解法は、相手戦車の状態を入力とした関数だとしたときに、入力に対して100%同じ答えを返す。
- よって、弾を当てられるときは必ず当て、逆に言うと、当てられないときは必ず当てられない。
- そのために数学による解法の戦車が当てられないときに、どこに撃てばあたったのか、という情報は、学習データに一切入っていない。
学習データの改善
次のように学習データを作り直しました。
- ランダムに弾を撃つ戦車によって学習データを作る。
命中精度(改)
機械学習手法をIB11としたときのAIです。
これでも100%の命中精度とならない理由は、robocodeは、戦車の砲塔の向きを変えるのにも微小ですけど時間がかかるようになっているため、例えば、前に撃った砲塔の向きから、次に打ちたい砲塔の向きへの移動時間がAIによる学習では考慮されていないためだと思われます。
人を超えるAIの作り方
学習データの作り方によって次の特徴が明らかとなりました。学習速度とは、AIが学習データをある程度理解するまでの時間です。
学習データを作る戦車 | 学習速度 | 命中精度 |
---|---|---|
数学による解法 | 速い | 低い |
ランダムに撃つ | 遅い | 高い |
これまでのAIは、人の知識をいかにAIに実装するかが1つの主流な考え方でした。それは、学習するための時間が、昔のコンピュータでは膨大にかかりすぎるためだったからです。よって学習速度の速い、数学による解法のような人の知識を実装するような手法が取られてきました。
近年は、AIが発達し、人の能力を部分的に超えるようになってきました。そのポイントは、このrobocodeの例でいうと、ランダムに撃つを取り入れたことです。
ここから、次のことが言えるかと思います。
人を超えるAIは、人がやらないことをやらないといけない。
-
D. Aha, D. Kibler (1991). Instance-based learning algorithms. Machine Learning. 6:37-66. ↩