强化学习:Q-learning简单案例

Q-learning是一种无模型的强化学习算法,用于学习最优动作策略。它通过迭代更新动作价值函数$Q(s,a)$来优化决策,其中$s$表示状态,$a$表示动作。核心思想是使用贝尔曼方程来估计未来奖励的期望值。下面,我将通过一个简单的网格世界案例逐步解释Q-learning,并提供一个Python实现。

1. 案例描述:2x2网格世界
  • 环境:一个2x2的网格,包含四个状态:
    • 状态0: 左上角(起点)
    • 状态1: 右上角
    • 状态2: 左下角
    • 状态3: 右下角(终点)
  • 动作:智能体可以选择四个方向移动:上、下、左、右(分别用0,1,2,3表示)。如果移动导致撞墙(如从边界移出),则停留在原状态。
  • 奖励
    • 到达终点(状态3): +10
    • 撞墙或无效动作: -1
    • 其他有效移动: 0
  • 目标:学习从起点(状态0)到终点(状态3)的最优路径。
  • 参数设置
    • 学习率 $\alpha = 0.1$(控制更新步长)
    • 折扣因子 $\gamma = 0.9$(平衡即时和未来奖励)
    • 探索率 $\epsilon = 0.1$(用于$\epsilon$-greedy策略,以平衡探索和利用)
2. Q-learning算法原理

Q-learning的核心是更新$Q(s,a)$值,使用以下公式: $$ Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma \max_{a'} Q(s',a') - Q(s,a) \right] $$ 其中:

  • $r$ 是执行动作$a$后获得的即时奖励
  • $s'$ 是下一个状态
  • $\max_{a'} Q(s',a')$ 是在状态$s'$下选择最优动作的$Q$值估计

算法步骤:

  1. 初始化Q-table:创建一个表格,行表示状态,列表示动作,初始值全为0。
  2. 选择动作:使用$\epsilon$-greedy策略(以概率$\epsilon$随机探索,否则选择当前最优动作)。
  3. 执行动作:根据动作移动到新状态,并获得奖励$r$。
  4. 更新Q值:应用上述公式更新Q-table。
  5. 重复:进行多次迭代(episode),直到Q值收敛。
3. Python实现

下面是一个简单的Python代码实现上述网格世界案例。代码包括环境模拟、Q-learning更新和训练过程。

import numpy as np

# 定义环境参数
states = 4  # 4个状态:0,1,2,3
actions = 4  # 4个动作:0=上,1=下,2=左,3=右
alpha = 0.1  # 学习率
gamma = 0.9  # 折扣因子
epsilon = 0.1  # 探索率
episodes = 1000  # 训练轮数

# 初始化Q-table,全0
Q = np.zeros((states, actions))

# 定义奖励函数
def get_reward(state, action):
    next_state = state  # 默认不移动
    # 根据动作计算新状态(简单网格逻辑)
    if action == 0:  # 上:从状态0或1移动到无效(撞墙),状态2或3向上移动
        next_state = state - 2 if state in [2, 3] else state
    elif action == 1:  # 下:状态0或1向下移动,状态2或3无效
        next_state = state + 2 if state in [0, 1] else state
    elif action == 2:  # 左:状态0或2无效,状态1或3向左移动
        next_state = state - 1 if state in [1, 3] else state
    elif action == 3:  # 右:状态0或2向右移动,状态1或3无效
        next_state = state + 1 if state in [0, 2] else state
    
    # 计算奖励
    if next_state == 3:  # 到达终点
        return 10, next_state
    elif next_state == state:  # 撞墙或无效动作
        return -1, state
    else:  # 有效移动
        return 0, next_state

# Q-learning训练
for episode in range(episodes):
    state = 0  # 起点状态0
    done = False
    
    while not done:
        # ε-greedy策略选择动作
        if np.random.uniform(0, 1) < epsilon:
            action = np.random.randint(actions)  # 随机探索
        else:
            action = np.argmax(Q[state, :])  # 选择最优动作
        
        # 执行动作,获得奖励和下一个状态
        reward, next_state = get_reward(state, action)
        
        # 更新Q值
        old_value = Q[state, action]
        next_max = np.max(Q[next_state, :])
        new_value = old_value + alpha * (reward + gamma * next_max - old_value)
        Q[state, action] = new_value
        
        # 检查是否到达终点
        if next_state == 3:
            done = True
        state = next_state  # 更新状态

# 输出训练后的Q-table
print("训练后的Q-table:")
print(Q)

# 测试最优路径
state = 0
path = [state]
while state != 3:
    action = np.argmax(Q[state, :])
    _, state = get_reward(state, action)
    path.append(state)
print("最优路径:", path)

4. 代码解释
  • 环境模拟get_reward函数根据当前状态和动作计算奖励和新状态。例如,从状态0向右移动到状态1,奖励为0;从状态1向右无效(撞墙),奖励为-1。
  • 训练过程:循环1000轮(episodes),每轮从起点开始,直到到达终点。使用$\epsilon$-greedy策略平衡探索和利用。
  • Q值更新:核心部分应用公式$$ Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma \max_{a'} Q(s',a') - Q(s,a) \right] $$,逐步优化策略。
  • 结果:训练后,Q-table会显示每个状态-动作对的价值。例如,从状态0到状态1的动作(向右)可能有较高Q值。测试部分输出最优路径,如[0, 1, 3]。
5. 总结

在这个简单案例中,Q-learning成功学习了从起点到终点的路径。通过调整参数(如$\alpha$或$\gamma$),可以优化收敛速度。Q-learning易于实现,适合入门强化学习。实际应用中,可扩展到更大状态空间(如迷宫游戏),但需注意探索-利用权衡。

更多推荐