RL 简介
(1) 定义
强化学习(Reinforcement Learning)是一种机器学习方法,用于解决需要在一定环境下通过与环境交互来学习最有行为策略的问题。其核心思想是通过试错和奖励机制来指导智能体(Agent)学习如何在不同情境下采取行动,以最大化长期累积奖励
(2) 强化学习流程
强化学习中的 agent 用来表示做决策的机器,相比于传统的模型,agent 可以感知周围的环境并通过做决策来直接改变这个环境。一般来说,在经典的强化学习中 agent 的实现可以用一些简单的 MLP、RNN、CNN 等神经网络实现,与现在流行的 LLM-based Agent 有区别
最终目标是:找到一个策略,这个策略根据当前观测到的环境状态和奖励反馈,来选择最佳的动作
(3) 强化学习的独特性
一般的有监督学习任务,目标是找到一个最优的模型函数,使其在训练数据集上最小化一个给定的损失函数;相比之下,强化学习的最终优化目标是最大化智能体策略在和动态环境交互过程中的价值。策略的价值可以等价转换成奖励函数在策略的占用度量(这里简单理解策略的占用度量就是策略的分布即可)上的期望
二者优化的途径是不同的,有监督学习直接通过优化模型对于数据特征的输出来优化目标,即修改目标函数而数据分布不变;强化学习则通过该改变策略来调整智能体与环境交互数据的分布,即修改数据分布而目标函数不变(一个学模型,一个学策略)
(4) 强化学习的分类
- 以数据来划分:
- Online:agent 一边与环境交互收集轨迹样本一边学习策略
- Offline:agent 学习用到的轨迹样本是提前收集好的,作为一个 offline dataset 提供给 agent,学习策略过程不涉及环境交互
- 以采样策略和更新策略划分
- On-Policy:用来采样的行为策略和用这些数据更新的目标策略是同一个策略,例如 SARSA
- Off-Policy:用来采样的行为策略和用这些数据更新的目标策略不是同一个策略,例如 Q-learning
- 以需不需要环境动态划分
- Model-based:环境动态已知,可以得到环境状态转移方程、奖励函数的模型,Agent 不需要真正的和环境交互学习策略
- Model-free:环境动态未知,不需要学习状态转移,通过 Agent 与环境交互学习策略
- 以如何学习策略划分(Value-based and Policy-based 见后述)
RL 基础概念
(1) 马尔可夫决策过程
强化学习解决实际问题的第一步就是把实际问题抽象成一个 Markov Decision Process(MDP)
马尔可夫决策过程由五元组 \(\) 构成,其中 \(S\) 是状态的集合,\(A\) 是智能体动作的集合,\(P(s'|s,a)\) 是状态转移函数在状态 \(s\) 执行动作 \(a\) 之后转移到状态 \(s'\) 的概率,\(r(s,a)\) 是即时奖励函数取决于状态和动作,\(\gamma\) 是折扣因子(未来第 t 步的奖励需要乘上 \(\gamma^t\) 来降低影响)
策略用 \(\pi\) 表示,其相当于在输入状态情况下采取不同动作的概率。当一个动作是确定性策略时,它在每个状态时只输出一个确定性的动作;当一个策略是随机性策略时,它在每个状态的输出是关于动作的概率分布,然后根据该分布进行采样就可以得到一个动作
(2) 价值函数
- 状态价值函数 \(V(s)\):从一个 state 出发,对各个 trajectory 的回报求期望。公式为 \(v_\pi(s)=E(G_t|S_t=s)\),其表示从状态 \(s\) 出发,遵循策略 \(\pi\) 时,未来所有回报的期望总和
- 状态动作价值函数 \(Q(s,a)\):状态-动作值函数评估的是在给定策略下,在某个状态 s 执行某个动作 a 后未来所有回报的期望总和
当且仅当某时刻的状态只取决于上一时刻的状态时,一个随机过程被称为具有马尔可夫性质
(3) 价值估计方法
- 贝尔曼方法:\(Q^*(s,a)=\sum_{s'}P(s'|s,a)[R(s,a,s')+\gamma \ max_{a'}Q^*(s',a')]\)
这里 \(*\) 表示最优的,\(P(s'|s,a)\) 表示状态转移概率,因为环境可能是随机的,我们需要考虑所有的可能性,所以我们需要对所有可能的下一个状态 \(s'\) 进行加权求和,\(R(s,a,s')\) 表示即时奖励,它表示状态 \(s\) 执行动作 \(a\) 并且转移到状态 \(s'\) 之后可以立刻获得的回报;最后的 \(max_{a'}Q^*(s',a')\) 是方程的精髓,其表示了下一个状态的最大未来价值
一句话总结:在状态 \(s\) 选择动作 \(a\) 的奖励 = 你马上能获得的奖励+未来所有可能的新状态 \(s'\) 的最大价值,并根据其出现概率和折扣因子进行加权
- 蒙特卡洛方法:蒙特卡洛方法也被称为统计模拟方法,是一种基于概率统计的数据计算方法。等一次完整过程结束后,计算整条路径的真实回报,对于每个状态,MC 算法在 MDP 上采样很多条策略最后求期望值(只要足够多就逼近真实)
基础学习方法
(1) 动态规划方法
动态规划是一种 model-based 方法,要求事先知道环境的状态转移函数和奖励函数,即 MDP 过程已知,这种情况下 Agent 并不需要与环境真正交互,直接利用 DP 就可以求解最优策略
- 策略迭代算法:分为两步,一是策略评估,先固定一个策略,基于贝尔曼方法计算当前策略的价值函数(需要遍历每一个状态,经过多轮迭代之后状态价值函数收敛);二是策略改进,在当前价值函数下选择回报最大的动作。然后循环往复,直至选择最佳策略
- 价值迭代算法:值迭代就是解贝尔曼方程的算法,在每一个状态贪心的选择动作价值函数最大的动作来得到改进后的策略(遍历动作选最大动作价值函数)
知道 MDP 与环境动态,奖励会从终点向前传播
(2) 时序差分方法
实际交互,一般只考虑实际的一步动作的奖励
时序差分是一种 model-free 方法啊,此时写不出 MDP 的状态转移方程,只能通过 agent 与环境交互采样得到的数据来学习策略(实际中大多数环境的状态转移方程都写不出来,所以 model-free 方法应用多)
时序差分方法和蒙特卡洛的相似之处在于可以从样本数据中学习,不需要事先知道环境;和动态规划的相似之处在于根据贝尔曼方程的思想,利用后续状态的价值估计来更新当前状态的估计
SARSA 算法:SARSA 是一种在线(on-policy)学习算法。在更新 Q 函数时,它使用了智能体实际采取的下一个动作 \(a'\) 的动作价值:\(Q_t(s', a')\)。这意味着 SARSA 在学习过程中会考虑智能体当前的策略。因此,SARSA 学到的策略与智能体在训练过程中实际执行的策略密切相关
SARSA-\(\lambda\) 算法:考虑多步时序差分(传统是只考虑一步)
\(\epsilon-greedy\) 算法:选择动作,兼顾探索和利用,使用一个探索率小量 \(\epsilon\) 来控制利用和探索的比例:生成一个 0-1 的随机数,如果小于 \(\epsilon\) 就在所有可能动作中随机选择一个,不然就选择 \(Q\) 最大的
(5) Q-learning 算法(时序差分的一种,很重要所以单列)
在一些真实的场景中我们一开始完全不知道状态转移概率 \(P\) 和奖励函数 \(R\) 的完整分布,但 Q-learning 不需要知道 \(P,R\),而是在环境中实际探索、采样来学习
它会按照以下公式来更新 \(Q\) 的估计值:
\(Q(s,a)\leftarrow Q(s,a)+\alpha(r+\gamma \ \max_{a'}Q(s',a')-Q(s,a))\)
公式说明:
具体而言,他做了一个非常关键的简化,不计算期望,而是用实际观测到的样本来代替它。当智能体从 \(s\) 执行 \(a\) 得到一个具体的 \(r\) 和 \(s\) 时,这个组合 \((s,a,r,s')\) 就是对环境真实动态的一次采样。然后 Q-learning 用这个样本更新 Q 值,与贝尔曼公式相比,其中 \(r\) 是对 \(R(s,a,s')\) 的一次采样,\(max_{a'}Q(s',a')\) 是对 \(max_{a'}Q^*(s',a')\) 的当前估计
可以看到在更新公式中,左边是旧知识,右边是新知识。\(\alpha\) 表示学习率,如果 \(\alpha\) 很小,智能体学习的比较慢,更相信过去的经验;反之
其核心是维护一个 Q-table,该表格记录了在每个状态 s 之下执行每个可能得动作 a 之后能够获得的可能的未来奖励的期望值。Agent 在执行任务的时候只需要查询 Q-table,选择在当前状态下 Q 值最大的那个动作执行- class QLearning: def __init__(self, ncol, nrow, alpha, gamma, n_action=4): self.Q_table = np.zeros([nrow*ncol, n_action]) self.n_action = n_action self.alpha = alpha self.gamma = gamma self.epsilon = epsilon def take_action(self, state): if np.random().random() < self.epsilon: action = np.random.randint(self.n_action) else: action = np.argmax(self.Q_table[state]) return action def best_action(self, state): Q_max = np.max(self.Q_table[state]) a = [0 for _ in range(self.n_action)] for i in range(self.n_action): if self.Q_table[state, i] == Q_max: a[i] = 1 return a def update(self, s0, a0, r, s1): td_error = r + self.gamma * max(self.Q_table[s1]) - self.Q_table[s0, a0] self.Q_table[s0, a0] += self.alpha * td_error
复制代码 DQN
(1) 概念
前面讲到 Q-learning 算法使用表格来记录每个状态动作对的 Q 值,然后每次更新表格中对应位置的值就行了。但是如果状态动作空间非常大或者连续变量,那表格法就不能使用了。这个时候就可以用参数化的神经网络来拟合 Q 值函数,由此诞生了 DQN
DQN 使用参数为 w 的神经网络近似 Q 函数,表示为 \(Q_w(s,a)\),我们需要让 Q 值网络的输出与 TD 目标接近,因此可以使用均方误差(无监督学习经常用到,MSEloss)作为损失函数,形式如下:
\(L_{DQN}=\frac{1}{2N}\sum_{i=1}^{N}[Q_w(s_i,a_i)-(r_i+\gamma \ \max_{a'}Q(s',a'))]^2\)
(2) 经验回放
维护一个 Replay Buffer,其中存储 \( |