ChatGPTに強化学習について聞いてみたの2回目です。
前回の記事はこちら
前回の最後に強化学習についての環境として、迷路ゲームを挙げていました。
そろそろ、具体的なコードで強化学習を理解したいと思い始めましたので、迷路ゲームのエージェントを強化学習で作成する方法についてChatGPTさんに教えてもらおうと思います。
質問をして迷路のコードを出力してもらいます。私はChatGPT Plusを契約しているので、今回はGPT-4を利用してみました。
質問
迷路ゲームにおけるQ学習をもちいた探索AIを作成したいと考えています。どのように実装したらいいでしょうか?なるべくステップバイステップで教えて下さい。
応答
迷路ゲームにおけるQ学習を用いた探索AIの実装方法について、以下のステップバイステップのガイドを参考にしてください。Pythonを使用した例を示します。
import numpy as np
import random
class MazeEnv:
def __init__(self, maze):
self.maze = maze
self.actions = ['up', 'down', 'left', 'right']
self.state = None
self.start = None
self.end = None
def reset(self):
self.state = self.start
return self.state
def step(self, action):
next_state = self._next_state(action)
reward = self._reward(next_state)
done = next_state == self.end
self.state = next_state
return next_state, reward, done
def _next_state(self, action):
# (row, col)の形式で現在の状態を取得
row, col = self.state
# 各アクションに対する移動先を定義
if action == 'up':
row -= 1
elif action == 'down':
row += 1
elif action == 'left':
col -= 1
elif action == 'right':
col += 1
# 移動先が迷路外または壁の場合、状態を変更しない
if (row < 0 or row >= len(self.maze) or
col < 0 or col >= len(self.maze[0]) or
self.maze[row][col] == 1):
return self.state
return (row, col)
def _reward(self, next_state):
if next_state == self.end:
return 100
else:
return -1
class QLearningAgent:
def __init__(self, env, alpha=0.1, gamma=0.99, epsilon=0.1):
self.env = env
self.alpha = alpha
self.gamma = gamma
self.epsilon = epsilon
self.q_table = np.zeros((len(env.maze), len(env.maze[0]), len(env.actions)))
def choose_action(self, state):
if np.random.uniform(0, 1) < self.epsilon:
return random.choice(self.env.actions)
else:
action_values = self.q_table[state[0], state[1]]
return self.env.actions[np.argmax(action_values)]
def learn(self, state, action, reward, next_state):
action_index = self.env.actions.index(action)
current_q = self.q_table[state[0], state[1], action_index]
next_max_q = np.max(self.q_table[next_state[0], next_state[1]])
self.q_table[state[0], state[1], action_index] = current_q + self.alpha * (reward + self.gamma * next_max_q - current_q)
# 迷路の定義 (0: 通路, 1: 壁, S: スタート, G: ゴール)
maze = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[1, 1, 1, 0, 1],
[0, 0, 0, 0, 'G']
]
# スタートとゴールの座標を取得
start = (0, 0)
end = (len(maze)-1, len(maze[0])-1)
# 迷路環境を作成
env = MazeEnv(maze)
env.start = start
env.end = end
# Q学習エージェントを作成
agent = QLearningAgent(env)
# 学習のエピソード数
num_episodes = 1000
for episode in range(num_episodes):
state = env.reset()
done = False
while not done:
action = agent.choose_action(state)
next_state, reward, done = env.step(action)
agent.learn(state, action, reward, next_state)
state = next_state
if (episode + 1) % 100 == 0:
print(f"Episode {episode + 1} completed.")
state = env.reset()
done = False
steps = 0
while not done:
action = agent.choose_action(state)
next_state, reward, done = env.step(action)
print(f"Step {steps}: {state} -> {action} -> {next_state}")
state = next_state
steps += 1
print(f"Goal reached in {steps} steps.")
これで、Q学習を用いた迷路ゲームの探索AIが作成できました。最初に迷路の環境とQ学習エージェントを定義し、その後学習を行い、学習したエージェントを使って迷路を解くことができます。この例では、迷路やパラメータは簡単なものにしていますが、実際の問題に合わせてカスタマイズしてください。
maze-q.pyというファイルを作成して、ChatGPTが生成したコードをコピペして動かしてみました。
❯ python maze-q.py
Episode 100 completed.
Episode 200 completed.
Episode 300 completed.
Episode 400 completed.
Episode 500 completed.
Episode 600 completed.
Episode 700 completed.
Episode 800 completed.
Episode 900 completed.
Episode 1000 completed.
Step 0: (0, 0) -> down -> (1, 0)
Step 1: (1, 0) -> down -> (2, 0)
Step 2: (2, 0) -> right -> (2, 1)
Step 3: (2, 1) -> right -> (2, 2)
Step 4: (2, 2) -> right -> (2, 3)
Step 5: (2, 3) -> down -> (3, 3)
Step 6: (3, 3) -> down -> (4, 3)
Step 7: (4, 3) -> right -> (4, 4)
Goal reached in 8 steps.
このコードでは1つの迷路を1000エピソード学習したあとに、実際に学習したQテーブルをもちいて、どんな行動をするとゴールまで行けるのかを出力しています。 実際にゴールまで行くような行動を学習できています。 ChatGPTから出てきたコードを修正せずにここまで動いたので驚いています。
次はコードのそれぞれの部分についての解説を聞いてみたいと思います。
質問
それぞれのステップについての詳細な解説が聞きたいです。 強化学習の初学者にもわかりやすく解説してください。
回答
それぞれのステップについて詳細な解説を行います。強化学習の初学者にもわかりやすく説明しましょう。
ここでは、numpyとrandomライブラリをインポートしています。numpyは数値計算を効率的に行うためのライブラリで、randomは乱数生成に使用します。
MazeEnvクラスを定義しています。このクラスは迷路の状態や行動を管理し、エージェントがどのように迷路を移動するかを定義します。主なメソッドは以下の通りです。
QLearningAgentクラスを定義しています。このクラスはQ学習のアルゴリズムを実装し、エージェントの行動選択や学習を管理します。主なメソッドは以下の通りです。
init: 初期化メソッド。環境オブジェクトとQ学習のハイパーパラメータ(α, γ, ε)を受け取り、Qテーブルを初期化します。
このステップでは、迷路の環境とQ学習エージェントをインスタンス化し、学習を実行します。まず、迷路の構造を定義し、スタートとゴールの座標を設定します。次に、迷路環境とQ学習エージェントをインスタンス化します。学習は、エピソード単位で行われます。各エピソードでは、エージェントはスタートからゴールまでの経路を探索します。エージェントは、選択した行動に対して報酬を受け取り、Qテーブルを更新していきます。
学習が完了したら、学習したエージェントを使って迷路を解きます。エージェントの状態をリセットし、ゴールに到達するまで行動を繰り返します。各ステップで、エージェントはQテーブルに基づいて最適な行動を選択し、環境に適用します。最終的に、エージェントがゴールに到達したら、そのステップ数が表示されます。
これらのステップにより、Q学習を用いた迷路ゲームの探索AIが実装できます。Q学習は、エージェントが環境と相互作用することで、行動価値関数Qを学習する強化学習のアルゴリズムです。Q学習は、価値ベースのアプローチであり、最適な行動価値関数Q*を見つけることを目指しています。これにより、エージェントはどの行動が最適であるかを判断し、迷路を効率的に解くことができます。
だいぶ詳しく書くメソッドについて説明してもらいました。完全に理解するためには、自分で一行づつコードを読んで理解しないとだめですが、ここまでヒントを貰えばだいぶ楽にコードを読めそうです。 自分がコードを読んだ感じではlearnメソッドがとても重要な感じでした。
最初の方のエピソードの学習ではchoose_actionメソッドのランダムな選択をもちいて、偶然ゴールに辿り着き、ゴールするとゴールに近い座標での行動に報酬が付与され、学習が進んでいくようなイメージなのかなと理解しました。
質問
Qテーブルの学習の進み方について、イメージというか比喩で例えたいのですが、良い例えはありますか?
回答
Qテーブルの学習の進み方をイメージする比喩として、「波が石を磨く」プロセスを考えることができます。
波が石を磨くプロセスでは、石の表面が最初はでこぼこしていますが、繰り返し波が押し寄せることで徐々に滑らかになります。最終的に、波の力によって石が最適な形状に磨かれます。
ソフトウェアエンジニア。趣味は競馬、写真、ゲーム。
お問い合わせはTwitterのDMでお願いします。