ヒューリスティクスを用いた強化学習やってみた
はじめに
強化学習において、エージェントが環境を学習する際に報酬設計は非常に重要です。特に、ヒューリスティクス(経験則)を用いた報酬設計は、学習を加速する可能性があります。しかし、適切に設計しないと、局所最適解に陥ったり、学習が進まなかったりする問題も発生します。
そこで今回は、ヒューリスティクスを用いた Q 学習を利用して迷路を探索するプログラムを実装し、学習の過程を可視化してみました。
実装の概要
このプログラムでは、Python の tkinter を用いて迷路を可視化しながら、エージェントが Q 学習を通じてゴールを目指す様子をシミュレートします。
主な機能
迷路の自動生成
エージェントの Q 学習による探索
ヒューリスティクスを用いた報酬設計
迷路探索の可視化
学習結果のプロット
迷路の生成
迷路は Maze クラスで生成します。ここでは 壁(1)と通路(0)を持つ 2 次元配列 を用いて迷路を作成し、tkinter.Canvas を用いて可視化しています。
class Maze:
def __init__(self, row=10, col=10, canvas=None, root=None):
self.maze = np.array(maze)
self.goal = np.array([row*2-1, col*2-1])
self.initPos = np.array([1, 1])
self.position = self.initPos.copy()
self.row = row
self.col = col
self.canvas = canvas
self.root = root
self.maze = self.create_maze()
ヒューリスティクスを利用した報酬設計
ヒューリスティクスとして 「ゴールとのマンハッタン距離」 を用いて、よりゴールに近づく行動を促すような報酬設計を行いました。
def huristics(self):
return -(abs(self.maze.position[0]-self.maze.goal[0]) + abs(self.maze.position[1]-self.maze.goal[1]))
また、以下のように ゴール到達時の報酬 と 壁にぶつかった際のペナルティ を設定しました。
def reward(self, state, flag):
if flag:
return -10
if state ==self.maze.goal[0]*col+self.maze.goal[1]:
return 100
else:
return 0
基本的には、前回のプログラムにヒューリスティクスとε-greedy法を加えたのみ
ここでは、プログラムの説明をこの記事よりやっていると思います。
[Python]強化学習で迷路問題を解いてみた|Y.H
結果
ヒューリスティックスの影響を強くしたとき
2000回ほど、学習させたときの結果です。
横軸が何周目かを表しており、縦軸が迷路を完成させるときにかかったステップ数となります。
学習の前半では、色んな所に散らばっているのが見えます。

今回の2000回迷路探索を行った結果、まだばらつきがあるので、もっと収束させるために探索回数を増やしてみます。
補足:今回のステップ数は平均123回です。

あら。。。
局所最適に陥って、ヒューリスティックスのせいで、Qテーブルが変になっちゃったんでしょう。
平均ステップ数は、1126でした。
ヒューリスティックの効果を下げた時

平均ステップ数は、130回でした。
変わりませんね(笑)
迷路はランダムに作られているので、それを考慮するとヒューリスティックスの強度別に何十回か何百回か行ってみて、有意差があるのか調べると差があるかどうか分かるかもしれないですね。
回数を増やすと、下のようになりました。
やはり、Qテーブルは狂うんですね(笑)
でも、ヒューリスティックスの値が高い時と比べて、8000系付近でも、小さな値でゴールに着いていますね。
こっちの方が、設定が良かったんでしょう。

ヒューリスティクスをなくしたとき
ヒューリスティクスがあるときと比べて、収束が遅い気がしますね(笑)
ヒューリスティクスがあった方が、速くなるのかもしれないです。
よく見ると、探索回数がゼロ付近にでは、ヒューリスティクスが高い方がステップ数が小さくなっていますね
まあ、何回か実行した方が良いのかもしれないですけど

回数を増やしたとき
バグっていませんね(笑)

終わりに(ソースコード)
今回使ったプログラムは以下に置いています.