学习资料:
1、李宏毅强化学习
视频链接:https://www.bilibili.com/video/BV1jiqoB1EPi?spm_id_from=333.788.videopod.episodes&vd_source=c87e83a3ffcd7880aa0b0bc420d3a334&p=5
2、DPO:
五道口纳什。
视频链接:https://www.bilibili.com/video/BV1pM4m1U75K/?spm_id_from=333.1391.0.0&vd_source=c87e83a3ffcd7880aa0b0bc420d3a334
3、GAE,PPO代码:
东川路第一可爱猫猫虫
视频链接:https://www.bilibili.com/video/BV1KxSTBpEiW?spm_id_from=333.788.videopod.sections&vd_source=c87e83a3ffcd7880aa0b0bc420d3a334
对应代码:https://github.com/DLR-RM/stable-baselines3
4、KL散度的蒙特卡洛估计:
http://joschu.net/blog/kl-approx.html

李宏毅课程学习+网络学习

RL的三要素:reward(即时奖励)与value(长期奖励),actor,environment
分类:

  • Actor
  • Critic
  • Actor-Critic

Actor- based模型: Policy Gradient

从玩游戏出发,一条轨迹 τ = { s 1 , a 1 , r 1 , s 2 , a 2 , r 2 , ⋯   , s T , a T , r T } \tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\cdots,s_T,a_T, r_T\} τ={s1​,a1​,r1​,s2​,a2​,r2​,⋯,sT​,aT​,rT​}
actor模型是一个NN,负责玩游戏,判断面对每个状态 s s s的下一步动作是什么,actor可以看成是有限的下一步动作的分类器,如 π θ ( s ) \pi_{\theta}(s) πθ​(s),执行T步后奖励 R = ∑ t = 1 T r t R=\sum_{t=1}^Tr_t R=∑t=1T​rt​。
显然 玩游戏的目的是为了最大化所有可能情况的奖励之和 = ∑ τ R ( τ ) P ( τ ∣ θ ) = E τ ∼ π θ R ( τ ) =\sum_{\tau}R(\tau)P(\tau|\theta)=\mathbb{E}_{\tau\sim\pi_{\theta}}R(\tau) =∑τ​R(τ)P(τ∣θ)=Eτ∼πθ​​R(τ)。
参考监督学习,最小化loss可以用梯度下降,同理最大化奖励可以用梯度上升。问题转为了怎么求所有情况奖励之和的梯度。
定义 R θ ˉ = E τ ∼ π θ R ( τ ) \bar{R_{\theta}}=\mathbb{E}_{\tau\sim\pi_{\theta}}R(\tau) Rθ​ˉ​=Eτ∼πθ​​R(τ)表示每次采样的轨迹的总奖励的期望值,可以衡量actor的好坏。
我们需要求 ∇ R θ ˉ \nabla\bar{R_{\theta}} ∇Rθ​ˉ​ 推导如下
∇ R θ ˉ = ∇ ∑ τ R ( τ ) P ( τ ∣ θ ) = ∑ τ R ( τ ) ∇ P ( τ ∣ θ ) \begin{array}{rl} \nabla\bar{R_{\theta}} =& \nabla\sum_{\tau}R(\tau)P(\tau|\theta) \\ =& \sum_{\tau}R(\tau) \nabla P(\tau|\theta) \end{array} ∇Rθ​ˉ​==​∇∑τ​R(τ)P(τ∣θ)∑τ​R(τ)∇P(τ∣θ)​
注意,根据已有知识 ∇ log ⁡ f ( x ) = 1 f ( x ) ∇ f ( x ) \nabla \log f(x)=\dfrac{1}{f(x)}\nabla f(x) ∇logf(x)=f(x)1​∇f(x) ,所以把f(x)换成P得到: ∇ P ( τ ∣ θ ) = P ( τ ∣ θ ) ∇ log ⁡ P ( τ ∣ θ ) \nabla P(\tau|\theta) = P(\tau|\theta)\nabla \log P(\tau|\theta) ∇P(τ∣θ)=P(τ∣θ)∇logP(τ∣θ)
继续推导
∇ R θ ˉ = ∑ τ R ( τ ) ∇ P ( τ ∣ θ ) = ∑ τ R ( τ ) P ( τ ∣ θ ) ∇ log ⁡ P ( τ ∣ θ ) = E τ R ( τ ) ∇ log ⁡ P ( τ ∣ θ ) ≈ 1 N ∑ n = 1 N R ( τ n ) ∇ log ⁡ P ( τ n ∣ θ ) = 1 N ∑ n = 1 N R ( τ n ) ∇ log ⁡ [ P ( s 1 n ) P ( a 1 n ∣ s 1 n , θ ) P ( r 1 n , s 2 n ∣ s 1 n , a 1 n ) ⋯ P ( a T n ∣ s T n , θ ) P ( r T n , s T + 1 n ∣ s T n , a T n ) ] = 1 N ∑ n = 1 N R ( τ n ) [ ∇ log ⁡ P ( s 1 n ) + ∑ t = 1 T n ∇ log ⁡ P ( a t n ∣ s t n , θ ) + ∑ t = 1 T n ∇ log ⁡ P ( r t n , s t + 1 n ∣ s t n , a t n ) ] \begin{array}{rl} \nabla\bar{R_{\theta}} =& \sum_{\tau}R(\tau) \nabla P(\tau|\theta) \\ =& \sum_{\tau}R(\tau) P(\tau|\theta)\nabla \log P(\tau|\theta) \\ =& \mathbb{E}_{\tau}R(\tau) \nabla \log P(\tau|\theta)\\ \approx & \dfrac{1}{N}\sum_{n=1}^N R(\tau^n) \nabla \log P(\tau^n|\theta) \\ =& \dfrac{1}{N}\sum_{n=1}^N R(\tau^n) \nabla \log \left[ P(s_1^n) P(a_1^n|s_1^n,\theta)P(r_1^n,s_2^n|s_1^n,a_1^n) \cdots P(a_T^n|s_T^n,\theta)P(r_T^n,s_{T+1}^n|s_T^n,a_T^n) \right]\\ =&\dfrac{1}{N}\sum_{n=1}^N R(\tau^n) \left[ \nabla \log P(s_1^n)+ \sum_{t=1}^{T^n}\nabla \log P(a_t^n|s_t^n,\theta)+ \sum_{t=1}^{T^n}\nabla \log P(r_t^n,s_{t+1}^n|s_t^n,a_t^n) \right] \end{array} ∇Rθ​ˉ​===≈==​∑τ​R(τ)∇P(τ∣θ)∑τ​R(τ)P(τ∣θ)∇logP(τ∣θ)Eτ​R(τ)∇logP(τ∣θ)N1​∑n=1N​R(τn)∇logP(τn∣θ)N1​∑n=1N​R(τn)∇log[P(s1n​)P(a1n​∣s1n​,θ)P(r1n​,s2n​∣s1n​,a1n​)⋯P(aTn​∣sTn​,θ)P(rTn​,sT+1n​∣sTn​,aTn​)]N1​∑n=1N​R(τn)[∇logP(s1n​)+∑t=1Tn​∇logP(atn​∣stn​,θ)+∑t=1Tn​∇logP(rtn​,st+1n​∣stn​,atn​)]​
注意 我们是对actor的参数 θ \theta θ求梯度,而初始状态 s 1 s_1 s1​不是actor可控的、是环境决定的,给定状态和动作后的奖励、下一个动作也是环境决定的。所以去掉和 θ \theta θ无关的项后继续推导
∇ R θ ˉ = 1 N ∑ n = 1 N R ( τ n ) [ ∇ log ⁡ P ( s 1 n ) + ∑ t = 1 T n ∇ log ⁡ P ( a t n ∣ s t n , θ ) + ∑ t = 1 T n ∇ log ⁡ P ( r t n , s t + 1 n ∣ s t n , a t n ) ] = 1 N ∑ n = 1 N R ( τ n ) ∑ t = 1 T n ∇ log ⁡ P ( a t n ∣ s t n , θ ) = 1 N ∑ t = 1 T n ∑ n = 1 N R ( τ n ) ∇ log ⁡ P ( a t n ∣ s t n , θ ) \begin{array}{rl} \nabla\bar{R_{\theta}} =&\dfrac{1}{N}\sum_{n=1}^N R(\tau^n) \left[ \nabla \log P(s_1^n)+ \sum_{t=1}^{T^n}\nabla \log P(a_t^n|s_t^n,\theta)+ \sum_{t=1}^{T^n}\nabla \log P(r_t^n,s_{t+1}^n|s_t^n,a_t^n) \right]\\ =&\dfrac{1}{N}\sum_{n=1}^N R(\tau^n) \sum_{t=1}^{T^n}\nabla \log P(a_t^n|s_t^n,\theta)\\ =&\dfrac{1}{N}\sum_{t=1}^{T^n}\sum_{n=1}^N R(\tau^n) \nabla \log P(a_t^n|s_t^n,\theta)\\ \end{array} ∇Rθ​ˉ​===​N1​∑n=1N​R(τn)[∇logP(s1n​)+∑t=1Tn​∇logP(atn​∣stn​,θ)+∑t=1Tn​∇logP(rtn​,st+1n​∣stn​,atn​)]N1​∑n=1N​R(τn)∑t=1Tn​∇logP(atn​∣stn​,θ)N1​∑t=1Tn​∑n=1N​R(τn)∇logP(atn​∣stn​,θ)​

而 ∇ log ⁡ P ( a t n ∣ s t n , θ ) \nabla \log P(a_t^n|s_t^n,\theta) ∇logP(atn​∣stn​,θ)就是正常的分类器的梯度。
训练过程就是

  1. 采样N条轨迹,计算梯度
  2. 更新模型参数,然后转回1

存在的问题:
奖励都是正数,各个操作都被鼓励了。理想情况下,虽然每个操作都被鼓励了,但是因为奖励值是不一样的,鼓励的程度不同,仍然可以使得学到倾向于去做高奖励的动作。
但是实际情况下,我们的公式中是通过采样来近似期望的,采样过程可能会漏掉一些操作,由于其他被采样的操作都被鼓励的,对比下漏掉的操作就被排斥了,而漏掉的操作有可能是高奖励的操作。所以这里会出现问题。

解决办法:
为奖励值设置一个baseline值, R ( τ ) new = R ( τ ) − baseline R(\tau)_{\text{new}} = R(\tau)-\text{baseline} R(τ)new​=R(τ)−baseline,从而使得奖励有高有低。
baseline是期望的奖励值(相当于中等水平的奖励),鼓励做超过期望的操作轨迹,排斥做低于期望的操作轨迹。

Critic-based模型:DQN和Q-Learning

Actor-based模型学习的是Actor,学面对某个状态下应该做哪个下一步操作。
而Critic-based模型学习的是Value, V π ( s ) V^{\pi}(s) Vπ(s)表示actor为 π \pi π时的状态价值,是从状态 s s s到操作轨迹结束的奖励之和 的期望,即状态 s s s的长期累积期望奖励。
我们可以用 G ( t ) G(t) G(t)表示从时刻t开始的累积奖励。
实际上,考虑到不同时刻的奖励的重要性不同,G(t)是累积折扣奖励 G t = r t + 1 + γ r t + 2 + γ 2 r t + 3 + ⋯ G_t=r_{t+1}+\gamma r_{t+2}+\gamma^2r_{t+3} +\cdots Gt​=rt+1​+γrt+2​+γ2rt+3​+⋯

学习value函数

怎么学习V函数?有两种方法:

  1. 蒙特卡洛 Monte Carlo, MC。
  2. 时序差分

蒙特卡洛求解V:
V π ( s ) = E [ G t ∣ S t = s ] V^{\pi}(s)=\mathbb{E}\left[G_t|S_t=s\right] Vπ(s)=E[Gt​∣St​=s],即状态s下的期望奖励=任意时刻t并且状态为s下的累积奖励 的期望
实际操作就是,采样N条操作轨迹,对每个轨迹从最后一步开始逆向遍历计算G(t)并把G值加入到对应s的桶里,最后每个s的桶里取G值平均,得到 V π ( s ) V^{\pi}(s) Vπ(s)

但是存在一个问题:一条轨迹里可能出现多次同一个状态s
所以有两种方案:
1、First-Visit MC:一条轨迹里逆向遍历,每个状态只考虑第一次遇到时的贡献
2、Every-Visit MC:逆向遍历,每次遇到都算贡献

逆向遍历是因为 G t G_t Gt​有递推关系: G t = r t + 1 + γ G t + 1 G_t=r_{t+1}+\gamma G_{t+1} Gt​=rt+1​+γGt+1​
这样N条长度为T的轨迹,处理完的复杂度就是 O ( N T ) O(NT) O(NT)。
如果正向遍历,每条轨迹的每一步都要统计一遍到最后的累积折扣奖励,复杂度就是 O ( N T 2 ) O(NT^2) O(NT2)

此外还有一个问题,如果轨迹特别大的时候也不方便,所以拿到一个新G值后可以增量更新均值:
N bucket ( s ) = N bucket ( s ) + 1 V bucket ( s ) = V bucket ( s ) + 1 N bucket ( s ) [ G − V bucket ( s ) ] \begin{array}{rl} N_{\text{bucket}}(s)=&N_{\text{bucket}}(s)+1\\ V_{\text{bucket}}(s)=&V_{\text{bucket}}(s)+\dfrac{1}{N_{\text{bucket}}(s)}\left[G - V_{\text{bucket}}(s)\right] \end{array} Nbucket​(s)=Vbucket​(s)=​Nbucket​(s)+1Vbucket​(s)+Nbucket​(s)1​[G−Vbucket​(s)]​


EasyR1代码阅读

学习资料:
1、官方代码:
https://github.com/hiyouga/EasyR1
2、代码走读:
https://zhuanlan.zhihu.com/p/1921972845669492319

config配置:https://verl.readthedocs.io/en/latest/examples/config.html#ppo-trainer-yaml-for-rl-fsdp-backend
代码运行入口:EasyR1/examples/xxx.sh
参考配置文件:EasyR1/examples/config.yaml

配置文件

配置文件分为4个部分:
1、data
rollout_batch_size:等价verl的data.train_batch_size
mini_rollout_batch_size:等价verl的data.gen_batch_size

运行过程

1、执行入口:EasyR1/verl/trainer/main.py

  • 读取了默认PPO的配置+cli参数。
  • 初始化Ray分布式框架,ray运行了自定义类Runner,运行PPO任务。
  • 类Runner中:
    • 读取文本分词器tokenizer和多模态处理器processor
    • 分配资源
    • 定义Reward
    • 读取训练集和验证集
    • 构建Trainer
    • 开始训练

2、训练:EasyR1/verl/trainer/ray_trainer.py

  • 验证函数:def _validate(self) -> dict[str, Any]

其他学习记录

学习2-系列
学习1
强化学习,需要agent不断地在环境中进行交互实验,通过环境给予的反馈(奖励)来不断优化(状态-行为)的对应关系,目标一般是追求最大回报

强化学习四要素:

  1. 策略(policy):给定状态(环境状态+智能体状态),策略能判断下一个行为是什么。策略本身可以是具体的映射也可以是随机的分布。
  2. 奖励(reward):在每个时间步骤内,环境返回的标量值即为奖励,能表征在某一步智能体的表现如何。
  3. 价值(value):与奖励的即时性不同,价值函数是对长期收益的衡量。它可以评估状态的好坏。价值函数的计算需要对状态之间的转移进行分析
  4. 环境/模型(model):并非所有的强化学习系统都需要有一个模型,因此会有基于模型(Model-based)、不基于模型(Model-free)两种不同的方法,不基于模型的方法主要是通过对策略和价值函数分析进行学习。模型可以预测环境下一步的表现(即,状态和奖励)。

基于策略和价值的分类,分为三类:
基于价值的方法(Value Based):没有策略但是有价值函数
基于策略的方法(Policy Based):有策略但是没有价值函数
参与评价方法(Actor Critic):既有策略也有价值函数
基于环境的分类,分为两类:
无模型的方法(Model Free):有策略和价值函数,没有模型
基于模型的方法(Model Based):有策略和价值函数,也有模型

探索(Exploration)和利用(Exploitation)

一方面,为了从环境中获取尽可能多的知识,我们要让agent进行探索。
另一方面,为了获得较大的奖励,我们要让agent对已知的信息加以利用。
鱼与熊掌不可兼得,我们不可能同时把探索和利用都做到最优,因此,强化学习问题中存在的一个重要挑战即是如何权衡探索-利用之间的关系。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐