Primary About Development

ChatGPTに強化学習について聞いてみた2(Q学習で迷路ゲームのエージェント作成)

2023-04-05

ChatGPTに強化学習について聞いてみたの2回目です。

前回の記事はこちら

前回の最後に強化学習についての環境として、迷路ゲームを挙げていました。

そろそろ、具体的なコードで強化学習を理解したいと思い始めましたので、迷路ゲームのエージェントを強化学習で作成する方法についてChatGPTさんに教えてもらおうと思います。

迷路のコードを出力してもらう

質問をして迷路のコードを出力してもらいます。私はChatGPT Plusを契約しているので、今回はGPT-4を利用してみました。

質問

迷路ゲームにおけるQ学習をもちいた探索AIを作成したいと考えています。どのように実装したらいいでしょうか?なるべくステップバイステップで教えて下さい。

応答

迷路ゲームにおけるQ学習を用いた探索AIの実装方法について、以下のステップバイステップのガイドを参考にしてください。Pythonを使用した例を示します。

ステップ1: 必要なライブラリをインポート

import numpy as np
import random

ステップ2: 迷路の環境を定義

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

ステップ3: Q学習エージェントを定義

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)

ステップ4: 迷路の環境と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.")

ステップ5: 学習したエージェントを使って迷路を解く

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から出てきたコードを修正せずにここまで動いたので驚いています。

コードの解説をしてもらう

次はコードのそれぞれの部分についての解説を聞いてみたいと思います。

質問

それぞれのステップについての詳細な解説が聞きたいです。 強化学習の初学者にもわかりやすく解説してください。

回答

それぞれのステップについて詳細な解説を行います。強化学習の初学者にもわかりやすく説明しましょう。

ステップ1: 必要なライブラリをインポート

ここでは、numpyとrandomライブラリをインポートしています。numpyは数値計算を効率的に行うためのライブラリで、randomは乱数生成に使用します。

ステップ2: 迷路の環境を定義

MazeEnvクラスを定義しています。このクラスは迷路の状態や行動を管理し、エージェントがどのように迷路を移動するかを定義します。主なメソッドは以下の通りです。

  • init: 初期化メソッド。迷路の構造を受け取り、状態や行動を初期化します。
  • reset: エピソード開始時に呼び出され、エージェントの状態をスタート位置にリセットします。
  • step: エージェントが行動を選択し、環境に適用する際に呼び出されます。報酬と終了フラグを返します。
  • _next_state: 与えられた行動によって、次の状態を計算します。
  • _reward: 与えられた状態に対して報酬を計算します。

ステップ3: Q学習エージェントを定義

QLearningAgentクラスを定義しています。このクラスはQ学習のアルゴリズムを実装し、エージェントの行動選択や学習を管理します。主なメソッドは以下の通りです。

init: 初期化メソッド。環境オブジェクトとQ学習のハイパーパラメータ(α, γ, ε)を受け取り、Qテーブルを初期化します。

  • choose_action: 現在の状態に基づいて行動を選択します。ε-greedy法を使用して、ランダムな行動を選択するか、Qテーブルに基づいて最適な行動を選択します。
  • learn: Qテーブルを更新するために、現在の状態・行動・報酬・次の状態を使って学習を行います。

ステップ4: 迷路の環境とQ学習エージェントを作成し、学習を実行する

このステップでは、迷路の環境とQ学習エージェントをインスタンス化し、学習を実行します。まず、迷路の構造を定義し、スタートとゴールの座標を設定します。次に、迷路環境とQ学習エージェントをインスタンス化します。学習は、エピソード単位で行われます。各エピソードでは、エージェントはスタートからゴールまでの経路を探索します。エージェントは、選択した行動に対して報酬を受け取り、Qテーブルを更新していきます。

ステップ5: 学習したエージェントを使って迷路を解く

学習が完了したら、学習したエージェントを使って迷路を解きます。エージェントの状態をリセットし、ゴールに到達するまで行動を繰り返します。各ステップで、エージェントはQテーブルに基づいて最適な行動を選択し、環境に適用します。最終的に、エージェントがゴールに到達したら、そのステップ数が表示されます。

これらのステップにより、Q学習を用いた迷路ゲームの探索AIが実装できます。Q学習は、エージェントが環境と相互作用することで、行動価値関数Qを学習する強化学習のアルゴリズムです。Q学習は、価値ベースのアプローチであり、最適な行動価値関数Q*を見つけることを目指しています。これにより、エージェントはどの行動が最適であるかを判断し、迷路を効率的に解くことができます。

ここまででわかったこと

だいぶ詳しく書くメソッドについて説明してもらいました。完全に理解するためには、自分で一行づつコードを読んで理解しないとだめですが、ここまでヒントを貰えばだいぶ楽にコードを読めそうです。 自分がコードを読んだ感じではlearnメソッドがとても重要な感じでした。

最初の方のエピソードの学習ではchoose_actionメソッドのランダムな選択をもちいて、偶然ゴールに辿り着き、ゴールするとゴールに近い座標での行動に報酬が付与され、学習が進んでいくようなイメージなのかなと理解しました。

質問

Qテーブルの学習の進み方について、イメージというか比喩で例えたいのですが、良い例えはありますか?

回答

Qテーブルの学習の進み方をイメージする比喩として、「波が石を磨く」プロセスを考えることができます。

波が石を磨くプロセスでは、石の表面が最初はでこぼこしていますが、繰り返し波が押し寄せることで徐々に滑らかになります。最終的に、波の力によって石が最適な形状に磨かれます。

プロフィール写真

Soraef

ソフトウェアエンジニア。趣味は競馬、写真、ゲーム。

お問い合わせはTwitterのDMでお願いします。