目录

摘要

Abstract

1 马尔可夫决策过程

1.1 MDP的五元组

1.2 轨迹与累积奖励

2 策略梯度

2.1 参数化

2.2 策略梯度定理

2.3 REINFORCE 算法流程

3 Q-Learning 与值函数方法

3.1 状态-动作值函数

3.2 更新规则

3.3 深度Q网络(DQN)

4 课堂代码

5 总结


摘要

本周学习最后一节课程强化学习,这是机器学习中与监督、无监督并列的第三种学习范式。强化学习让智能体在环境中通过试错自主学会决策,广泛应用于游戏、机器人控制、推荐系统等领域。本周重点学习强化学习的数学框架和两种核心算法

Abstract

This week we will cover the final lesson on reinforcement learning, which represents the third learning paradigm in machine learning, alongside supervised and unsupervised learning. Reinforcement learning enables agents to learn how to make decisions on their own through trial and error within a given environment, and it is widely used in areas such as games, robot control, and recommendation systems. This week’s focus will be on the mathematical framework of reinforcement learning as well as two of its core algorithms.

1 马尔可夫决策过程

1.1 MDP的五元组

强化学习的问题被抽象为MDP,包含以下五个核心要素:

1、\mathcal{S}:状态集合
2、\mathcal{A}:动作集合
3、P(s'|s,a):状态转移概率,执行动作 a 后从状态 s 转移到 s' 的概率
4、R(s,a):即时奖励函数
5、\gamma \in [0,1):折扣因子,用于平衡短期与长期回报

1.2 轨迹与累积奖励

智能体在环境中执行策略 \pi,产生一条轨迹

\tau = (s_0, a_0, r_1, s_1, a_1, r_2, \dots, s_T)

该轨迹的累积折扣奖励为

G(\tau) = \sum_{t=0}^{T} \gamma^t r_{t+1}

强化学习的目标是找到一个最优策略 \pi^*,使得期望累积奖励最大化

\pi^* = \arg\max_\pi \mathbb{E}_{\tau \sim \pi}\left[ G(\tau) \right]

2 策略梯度

2.1 参数化

策略通常用一个神经网络参数化,记为 \pi_\theta(a|s),输出在状态 s 下执行各动作的概率。课程的目标就是优化参数 \theta 来最大化期望回报:

J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta}[G(\tau)]

2.2 策略梯度定理

J(\theta) 求梯度,需要处理期望里的采样。李宏毅老师在课堂上给出了一个简洁的推导,利用对数求导技巧。

一条轨迹的概率为:

p_\theta(\tau) = p(s_0) \prod_{t=0}^{T-1} \pi_\theta(a_t|s_t) P(s_{t+1}|s_t,a_t)

两边取对数:

\log p_\theta(\tau) = \log p(s_0) + \sum_{t=0}^{T-1} \left[ \log \pi_\theta(a_t|s_t) + \log P(s_{t+1}|s_t,a_t) \right]

注意到只有 \log \pi_\theta 项与参数 \theta 有关,因此:

\nabla_\theta \log p_\theta(\tau) = \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t|s_t)

现在对目标函数求导:
\nabla_\theta J(\theta) = \nabla_\theta \int G(\tau) p_\theta(\tau) d\tau
               = \int G(\tau) \nabla_\theta p_\theta(\tau) d\tau 
               = \int G(\tau) \, p_\theta(\tau) \nabla_\theta \log p_\theta(\tau) d\tau \quad 
               = \mathbb{E}_{\tau \sim \pi_\theta}\left[ G(\tau) \nabla_\theta \log p_\theta(\tau) \right]
               = \mathbb{E}_{\tau \sim \pi_\theta}\left[ G(\tau) \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t|s_t) \right]

上述计算过程即为策略梯度定理。它告诉我们要沿着使高奖励轨迹更可能发生的方向更新参数。在实际算法中,对于采样到的轨迹 \tau,更新参数:

\theta \leftarrow \theta + \eta \sum_{t=0}^{T-1} G(\tau) \nabla_\theta \log \pi_\theta(a_t|s_t)

由于 G(\tau) 是整条轨迹的累积奖励,直接这样使用会导致高方差。李宏毅老师随后介绍了引入基线(baseline) 来减小方差,即用当前状态的值函数估计 V(s_t) 作为基线,替换 G(\tau) 为优势函数 A_t = G(\tau) - V(s_t)。实际中更常用的是每一时刻使用“从该时刻起的累积奖励” G_t = \sum_{k=0}^{T-t} \gamma^k r_{t+k+1} 乘以该时刻的对数概率梯度,这其实是上面的完整形式从期望推导后的等价实用版本:

\theta \leftarrow \theta + \eta \sum_{t=0}^{T-1} G_t \nabla_\theta \log \pi_\theta(a_t|s_t)

2.3 REINFORCE 算法流程

1. 用当前策略 \pi_\theta 采样多条完整轨迹
2. 对每条轨迹的每个时间步计算 G_t
3. 计算梯度估计

\hat{\nabla} J = \frac{1}{N}\sum_{\tau} \sum_t G_t \nabla_\theta \log \pi_\theta(a_t|s_t)
4. 用梯度上升更新参数

3 Q-Learning 与值函数方法

3.1 状态-动作值函数

定义 Q 函数为在状态 s 采取动作 a 后,遵循策略 \pi 所能获得的期望累积奖励:

Q^\pi(s,a) = \mathbb{E}_\pi\left[ \sum_{k=0}^{\infty} \gamma^k r_{t+k+1} \mid s_t = s, a_t = a \right]

最优 Q 函数满足贝尔曼最优方程:

Q^*(s,a) = \mathbb{E}_{s' \sim P}\left[ R(s,a) + \gamma \max_{a'} Q^*(s',a') \right]

3.2 更新规则

基于以上方程,Q-Learning 通过与环境交互的数据来迭代更新 Q 值:

Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[ r_{t+1} + \gamma \max_{a} Q(s_{t+1}, a) - Q(s_t, a_t) \right]

其中 \alpha 是学习率。当状态和动作空间离散时,可以用表格存储 Q 值。

3.3 深度Q网络(DQN)

DQN 使用一个神经网络 Q(s,a; \theta) 来逼近最优 Q 值。损失函数基于贝尔曼方程的残差:

\mathcal{L}(\theta) = \mathbb{E}_{(s,a,r,s') \sim \mathcal{D}}\left[ \left( r + \gamma \max_{a'} Q(s',a'; \theta^-) - Q(s,a; \theta) \right)^2 \right]

4 课堂代码

李宏毅老师在课堂上用 Keras 和 OpenAI Gym 演示了简单的策略梯度算法解决 CartPole 问题:

import numpy as np
import gym
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam

env = gym.make('CartPole-v0')
model = Sequential([
    Dense(24, input_dim=4, activation='relu'),
    Dense(24, activation='relu'),
    Dense(2, activation='softmax')
])
model.compile(optimizer=Adam(lr=0.01), loss='categorical_crossentropy')

def train(episodes=1000):
    for e in range(episodes):
        state = env.reset()
        state = np.reshape(state, [1, 4])
        states, actions, rewards = [], [], []
        done = False
        while not done:
            # 根据策略采样动作
            action_prob = model.predict(state)[0]
            action = np.random.choice(2, p=action_prob)
            next_state, reward, done, _ = env.step(action)
            next_state = np.reshape(next_state, [1, 4])
            # 记录
            states.append(state)
            actions.append(action)
            rewards.append(reward)
            state = next_state
        # 计算每个时刻的回报
        Gt = 0
        discounted_rewards = np.zeros_like(rewards)
        for t in reversed(range(len(rewards))):
            Gt = rewards[t] + 0.99 * Gt
            discounted_rewards[t] = Gt
        # 标准化回报(稳定训练)
        discounted_rewards -= np.mean(discounted_rewards)
        discounted_rewards /= np.std(discounted_rewards)
        # 准备训练数据
        X = np.vstack(states)
        Y = np.zeros((len(states), 2))
        for t in range(len(states)):
            Y[t][actions[t]] = discounted_rewards[t]  # 伪标签 = 优势加权
        # 自定义损失?这里使用简单技巧:用交叉熵 + sample_weight
        # 伪代码示意,实际课堂中可能使用 Keras 的 sample_weight 参数:
        model.train_on_batch(X, Y, sample_weight=discounted_rewards)
        if e % 100 == 0:
            print(f"Episode {e} finished with total reward {sum(rewards)}")
train()

5 总结

经过本节课粗略的学习与了解,发现强化学习是区别于监督学习的通过与环境交互的学习方式,这种试错学习的方式更接近人类和动物,我理解了为什么这种学习方式在游戏、机器人领域被高频使用。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐