想入门强化学习(RL)却被“智能体”“Q值”“贝尔曼方程”劝退?别慌!这篇推文用最通俗的语言+完整代码,带你从0到1理解强化学习的核心逻辑,看完就能动手实践~

另外,我整理了强化学习经典论文+代码合集,需要的的话自取~

➔➔➔➔点击查看原文,获取更多机器学习干货和资料!https://mp.weixin.qq.com/s/LFzZtI4L4ig4ny4NQ1WweQ

三大分类

三大分类

一、先搞懂:什么是强化学习?

强化学习(Reinforcement Learning, RL)是让智能体(Agent) 在与环境(Environment) 的交互中,通过“试错”学习最优策略的机器学习方法。核心目标只有一个:最大化长期累积奖励

和其他机器学习的区别

学习类型 核心特点 数据需求 目标
监督学习 有标注数据(输入→正确输出) 大量标注样本 最小化预测误差
无监督学习 无标注数据 无标注样本 发现数据内在结构
强化学习 智能体与环境交互试错 无预设数据,靠交互生成 最大化长期累积奖励

适用场景

机器人控制、自动驾驶、游戏AI(如AlphaGo)、金融交易、资源调度等需要“动态决策”的任务。

二、强化学习的5个核心组成部分

强化学习系统就像“智能体在环境中闯关”,这5个部分缺一不可:

  1. 环境(Environment)
    智能体活动的“世界”,比如迷宫、游戏地图、机器人的物理空间。它定义了3个关键规则:

    • 状态空间:环境可能处于的所有状态(如迷宫中的位置)

    • 动作空间:智能体能执行的所有操作(如上下左右移动)

    • 奖励规则:智能体做动作后,环境给出的反馈(如找到出口得+10分,撞墙得-5分)

  2. 智能体(Agent)
    执行动作的“主角”(如机器人、游戏角色),核心任务是通过学习找到“最优策略”。

  3. 状态(State, s)
    环境在某一时刻的“快照”,比如“智能体在迷宫(2,3)位置”“机器人关节角度30°”。

  4. 动作(Action, a)
    智能体对环境的“操作”,比如“向左走”“抬高机械臂”。

  5. 奖励(Reward, r)
    环境给智能体的“反馈信号”,是学习的“指挥棒”:

    • 正奖励(+):鼓励正确动作(如通关、得分)

    • 负奖励(-):惩罚错误动作(如失败、碰撞)

强化学习简单示意图

强化学习简单示意图

三、必须掌握的4个关键概念

1. 策略(Policy, π)

策略是智能体的“决策规则”,定义了“在什么状态下做什么动作”,记作 a = π(s)。

  • 确定性策略:同一状态下必选同一动作(如s1状态必选a2)

  • 随机策略:同一状态下按概率选动作(如s1状态70%选a1,30%选a2)

2. 状态-价值函数(V(s))

衡量“从状态s出发,按策略π行动能获得的长期期望奖励”,公式如下:

  • :折扣因子(0≤γ≤1),控制“未来奖励的重要性”(γ=0只看即时奖励,γ=1重视长期奖励)

  • :按策略π行动的期望

3. 状态-动作值函数(Q-Value, Q(s,a))

比V(s)更具体:衡量“在状态s执行动作a后,按策略π继续行动的长期期望奖励”,公式:

Q值是强化学习的核心——智能体只要学会Q(s,a),就能通过“选Q值最大的动作”找到最优策略。

4. 贝尔曼方程(强化学习的“灵魂”)

描述了“当前价值”与“未来价值”的递归关系,是所有RL算法的数学基础。

  • Q值的贝尔曼方程: 含义:“当前状态s做动作a的Q值” = “即时奖励r” + “未来状态s'的最大Q值(乘以折扣因子)”

四、强化学习的3大算法分类

分类 核心思路 代表算法 适用场景
基于值迭代(Value-based) 学习Q值/状态值,再推导策略 Q-learning、SARSA、DQN 离散动作空间(如迷宫、小游戏)
基于策略(Policy-based) 直接学习策略,不显式求Q值 策略梯度(PG)、PPO、A2C 连续动作空间(如机器人控制)
基于模型(Model-based) 先学环境模型,再规划动作 Dyna-Q 环境变化慢、需减少试错的场景

五、实战!用Q-learning玩迷宫(完整可运行代码)

我们用经典的“网格迷宫”案例,实现Q-learning算法——让智能体学会从起点(S)走到终点(G),避开障碍(O)。

代码功能说明

  • 迷宫地图:5×5网格,S(0,0)为起点,G(4,4)为终点,O(1,1)、O(2,3)为障碍

  • 奖励规则:到达G得+100,撞墙/碰障碍得-10,其他动作得-1(鼓励快速通关)

  • 最终效果:智能体通过学习,能找到从S到G的最短路径

import numpy as np
import matplotlib.pyplot as plt

# --------------------------
# 1. 定义迷宫环境(Environment)
# --------------------------
class MazeEnv:
    def __init__(self):
        # 5x5迷宫:0=可走,1=障碍,2=起点,3=终点
        self.maze = np.array([
            [2, 0, 0, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 0, 1, 0],
            [0, 0, 0, 0, 0],
            [0, 0, 0, 0, 3]
        ])
        self.start_pos = (0, 0)  # 起点
        self.goal_pos = (4, 4)   # 终点
        self.obstacle_pos = [(1,1), (2,3)]  # 障碍
        self.action_space = [(-1,0), (1,0), (0,-1), (0,1)]  # 上、下、左、右
        self.state_space = (5, 5)  # 状态空间:(行, 列)
    
    # 获取当前状态(位置)
    def get_state(self, pos):
        return pos
    
    # 执行动作,返回新状态、奖励、是否结束
    def step(self, pos, action):
        # 计算新位置
        new_pos = (pos[0] + action[0], pos[1] + action[1])
        
        # 1. 边界检测(撞墙)
        if new_pos[0] < 0 or new_pos[0] >= 5 or new_pos[1] < 0 or new_pos[1] >= 5:
            return pos, -10, False  # 位置不变,负奖励,未结束
        
        # 2. 障碍检测
        if new_pos in self.obstacle_pos:
            return pos, -10, False  # 位置不变,负奖励,未结束
        
        # 3. 终点检测
        if new_pos == self.goal_pos:
            return new_pos, 100, True  # 新位置,正奖励,结束
        
        # 4. 正常移动
        return new_pos, -1, False  # 新位置,小负奖励(鼓励快速通关)
    
    # 重置环境到起点
    def reset(self):
        return self.start_pos

# --------------------------
# 2. 实现Q-learning算法(Agent)
# --------------------------
class QLearningAgent:
    def __init__(self, state_space, action_space, lr=0.1, gamma=0.9, epsilon=0.1):
        self.state_space = state_space  # (5,5)
        self.action_space = action_space  # 4个动作
        self.lr = lr  # 学习率:控制Q值更新幅度
        self.gamma = gamma  # 折扣因子:控制未来奖励权重
        self.epsilon = epsilon  # 探索率:控制“探索”与“利用”的平衡
        
        # 初始化Q表:state_space × action_space,初始值为0
        self.Q_table = np.zeros((state_space[0], state_space[1], len(action_space)))
    
    # 选择动作:ε-贪心策略(兼顾探索和利用)
    def choose_action(self, state):
        # 探索:以ε概率随机选动作(尝试新路径)
        if np.random.uniform(0, 1) < self.epsilon:
            return np.random.choice(len(self.action_space))
        # 利用:以1-ε概率选Q值最大的动作(走已知最优路径)
        else:
            return np.argmax(self.Q_table[state[0], state[1], :])
    
    # 更新Q表:根据贝尔曼方程
    def update_Q_table(self, state, action, reward, next_state):
        # 当前Q值
        current_Q = self.Q_table[state[0], state[1], action]
        # 下一个状态的最大Q值
        max_next_Q = np.max(self.Q_table[next_state[0], next_state[1], :])
        # 贝尔曼方程更新Q值
        new_Q = current_Q + self.lr * (reward + self.gamma * max_next_Q - current_Q)
        self.Q_table[state[0], state[1], action] = new_Q

# --------------------------
# 3. 训练与可视化
# --------------------------
def train_maze_qlearning(episodes=1000):
    # 初始化环境和智能体
    env = MazeEnv()
    agent = QLearningAgent(
        state_space=env.state_space,
        action_space=env.action_space,
        lr=0.1,    # 学习率
        gamma=0.9, # 折扣因子
        epsilon=0.1# 探索率
    )
    
    # 记录每轮的总奖励(用于可视化训练过程)
    total_rewards = []
    
    # 开始训练(多轮迭代)
    for episode in range(episodes):
        state = env.reset()  # 重置环境到起点
        done = False         # 是否到达终点
        total_reward = 0     # 本轮总奖励
        
        while not done:
            # 1. 选动作
            action_idx = agent.choose_action(state)
            action = env.action_space[action_idx]
            
            # 2. 执行动作,获取反馈
            next_state, reward, done = env.step(state, action)
            
            # 3. 更新Q表
            agent.update_Q_table(state, action_idx, reward, next_state)
            
            # 4. 更新状态和总奖励
            state = next_state
            total_reward += reward
        
        # 记录本轮总奖励
        total_rewards.append(total_reward)
        
        # 每100轮打印一次进度
        if (episode + 1) % 100 == 0:
            print(f"Episode: {episode+1:4d} | Total Reward: {total_reward:6.1f}")
    
    # --------------------------
    # 可视化1:训练过程中总奖励的变化(看是否收敛)
    # --------------------------
    plt.figure(figsize=(12, 5))
    
    plt.subplot(1, 2, 1)
    plt.plot(total_rewards, alpha=0.7)
    # 绘制滑动平均(更清晰看趋势)
    window_size = 20
    if len(total_rewards) >= window_size:
        moving_avg = np.convolve(total_rewards, np.ones(window_size)/window_size, mode='valid')
        plt.plot(range(window_size-1, len(total_rewards)), moving_avg, color='red', label=f'Moving Avg ({window_size})')
    plt.title('Total Reward per Episode (Training Process)')
    plt.xlabel('Episode')
    plt.ylabel('Total Reward')
    plt.legend()
    plt.grid(alpha=0.3)
    
    # --------------------------
    # 可视化2:测试训练好的智能体(走一次迷宫)
    # --------------------------
    plt.subplot(1, 2, 2)
    # 测试时关闭探索(只利用最优策略)
    agent.epsilon = 0.0
    state = env.reset()
    done = False
    path = [state]  # 记录走过的路径
    
    while not done:
        action_idx = agent.choose_action(state)
        action = env.action_space[action_idx]
        next_state, _, done = env.step(state, action)
        path.append(next_state)
        state = next_state
    
    # 绘制迷宫
    maze_vis = env.maze.copy()
    for (i, j) in path:
        maze_vis[i, j] = 4  # 用4标记路径
    maze_vis[env.start_pos] = 2  # 起点
    maze_vis[env.goal_pos] = 3   # 终点
    
    # 配色:0=白色(可走),1=黑色(障碍),2=绿色(起点),3=红色(终点),4=蓝色(路径)
    cmap = plt.cm.colors.ListedColormap(['white', 'black', 'green', 'red', 'lightblue'])
    plt.imshow(maze_vis, cmap=cmap)
    plt.title('Trained Agent Path in Maze')
    plt.xticks(range(5))
    plt.yticks(range(5))
    
    # 添加网格线(更清晰)
    for i in range(5):
        plt.axhline(y=i-0.5, color='gray', linewidth=0.5)
        plt.axvline(x=i-0.5, color='gray', linewidth=0.5)
    
    plt.tight_layout()
    plt.show()
    
    return agent, env

# --------------------------
# 4. 运行训练
# --------------------------
if __name__ == "__main__":
    # 训练1000轮(可根据需要调整)
    trained_agent, maze_env = train_maze_qlearning(episodes=1000)

六、代码运行指南

1. 安装依赖(若未安装)

pip install numpy matplotlib

2. 运行效果说明

  • 训练过程:每100轮打印一次“轮次+总奖励”,总奖励会逐渐上升(说明智能体在进步)

  • 可视化结果:
    • 左图:总奖励变化曲线(红色滑动平均曲线会逐渐上升并稳定,说明训练收敛) Total Reward per Episode (Training Process)

    • 右图:智能体的最优路径(蓝色线从绿色起点到红色终点,避开黑色障碍) Trained Agent Path in Maze

七、新手入门小贴士

  1. 先从简单案例入手:先玩懂网格迷宫、悬崖行走等小任务,再学复杂的DQN、PPO

  2. 理解Q值的意义:Q(s,a)本质是“状态s做动作a的长期价值”,更新Q值就是在“修正对动作价值的判断”

  3. 调参技巧
    • 学习率(lr):太大容易震荡,太小收敛慢(建议0.01-0.2)

    • 折扣因子(γ):短期任务选小(如0.7),长期任务选大(如0.9-0.99)

    • 探索率(ε):可以随训练轮次衰减(如从0.3降到0.01,前期多探索,后期多利用)

强化学习的核心是“交互中学习”,动手跑一遍上面的代码,你会对RL的理解更深刻!后续可以尝试修改迷宫地图、调整参数,甚至用RL玩简单的小游戏~

➔➔➔➔点击查看原文,获取更多机器学习干货和资料!https://mp.weixin.qq.com/s/LFzZtI4L4ig4ny4NQ1WweQ

Logo

更多推荐