具身-Policy

2025-09-07

具身

Notation:

  • \(s_t\) state,环境&物体状态
  • \(o_t\) observation,观测(图片/点云)
  • \(a_t\) action,采取的策略
  • \(\pi_{\theta}(a_t|o_t)\):policy
  • \(\pi_{\theta}(a_t|o_t)\):fully observed 下的 policy,比较理想,在理论分析上能有简化

一些传统的算法可以作为一个 supervision 去 train policy.

当我们无法建立一个 optimal policy 的时候,无法使用 imitation learning 的时候就需要用 reinforcement learning.

Imitation Learning

可以采取一个 Markov 过程,只根据上一个状态做出决定. 但是实际上也是可以说去有一个记忆,根据历史的状态做出判断.

最基本的方案:behavioral cloning

Distribution Shift

这个方案很早就又提出了,但是有一个问题是 distribution shift:每一步都出一点小差错,然后最后就倒闭了. 这是因为你的 state 是由 action 决定的,于是 distribution 就会变得不同. 但在数据足够大的情况下,表现还是相当好的.

一个经典的方法是直接采取 teleoperation. 这个的好处是不存在 sim2real gap. 但是取而代之的是 real2real gap,比如如何做 generalization,因为环境变化非常小. 还可以在虚拟环境中进行摇操,这些 data 就会更加丰富一点.

为了消除 distribution shift,有两种方向:可以去让 \(p_{data}\) 更靠近真实情况,也可以让我们更好地去 fit 到专家的轨迹.

DAgger

DAgger: Dataset Aggregation:很暴力地将 \(p_{\pi_\theta}\) 加入数据集. 先按原来的数据去学 policy,然后用这个 policy 在环境中去探索,然后对于探索到的 state,再让人去 label,并入数据集. 不断这样循环往复,就得到了一个能够去适应 \(p_{\pi_{\theta}}\) 的数据集.

但是 human label 很难. 有两种思路:对于有传统 optimal solution 的东西(比如 navigation) 那么显然就可以直接自己 label. 第二种思路是 from a teacher policy. 比如我们假如已经有基于有完整信息时的开环的抓取策略,那么就可以用这个策略去训练一个基于 RGB 的闭环的抓取 policy.

Casual confusion

探讨为什么我们的策略会 fail to fit expert? 一个原因就是我们的 policy 是 non-markovian 的.

casual confusion:比如在开车,然后学到“刹车灯亮了就去踩刹车”. 而不是学到了一些环境因素才去踩刹车.

Multimodal behaviour

绕一棵树,然后一半数据是向左绕的,一半数据是向右绕的,然后 regression 的结果就会直接往中间撞上去. 一个方法是预测一个多峰的分布,比如使用 diffusion model,或者 autoregressive discretization(依次autoregressive 地去求解每个维度的概率分布)

Multitask training

很多个目标一起去 train. 具体而言,就是将 goal 和 state 一起作为 condition 加进去,这样就能很多个 task 一起学,让所有 task 都学的更好. 当然这也会带来一定的挑战 ,就是没见过的 goal 带来的 distribution shift.

Reinforcement Learning

Intro

强化学习也 assume markovian policy

Markov Decision Process (MDP): \(S\) 为状态空间,\(A\) 为动作空间,\(T\) 为状态转移,\(r\)\(S\times A\to r\) 的奖励函数.

但是我们观测到的可能并不是整个环境. 于是有 partially observed MDP:令 \(O\) 为 observation space,\(\varepsilon\) 为 emission probability \(p(o_t|s_t)\):在状态下观测到 \(o\) 的概率.

我们的目标就是,首先我们有 MDP 的分布:\(p(s_1,a_1,\dots,s_T,a_T)=p(s_1)\prod \pi_{\theta}(a_t|s_t)p(s_{t+1}|s_t,a_t)\). 然后我们就能算出奖励 \(E_{\tau\sim p_{\theta}(\tau)} \sum r(s_t,a_t)\). 目标就是最大化这个期望奖励.

显然我们是不知道 \(p(s_{t+1}|s_t,a_t)\) 的. 有些方法会去学这些,称为 model-based. 下面讲的是不去学这个的,即 model-free.

reward 函数不连续,所以不可导. 但是之后的期望收益是连续的. 所以这个期望其实很重要.


Gradient

怎么对奖励导呢?首先 先把期望写作积分的形式:\(\int r(\tau)p_{\theta}(\tau) d\tau\). 然后我们希望求导后的积分中还有项 \(p(\tau)\)(这样才能重新转化回期望). 由于 \(p_{\theta}(\tau)\nabla_\theta \log p_{\theta}(\tau)=\nabla_\theta p_{\theta}(\tau)\),所以我们对积分求导就可以直接变换成 \(\int p_{\theta}(\tau)\nabla_\theta r(\tau)\log p_{\theta}(\tau)=E[\nabla_\theta \log p_{\theta}(\tau)r(\tau)]\).

对这个 \(\log p_{\theta}(\tau)\) 求个导,乘法变成了加法,然后 \(\theta\) 无关项也没了,只剩下 \(\sum \log \pi_{\theta}(a_t|s_t)\) 了. 于是就变成了 \(E_{\tau}[\left(\sum \nabla_{\theta}\log \pi_{\theta}(a_t|s_t)\right)(\sum r(s_t,a_t))]\)

期望显然不大好算. 于是直接 Monte Carlo,采 \(n\) 条 trajectory 即可.

我们对比一下和模仿学习的. 模仿学习其实就是一条好的轨迹给出来,然后 gradient 就是 \(\sum \nabla_\theta \log \pi_{\theta}(a_t|s_t)\). 所以本质上就是所有 reward 都是 1.

模仿学习是 offline policy. 强化学习是一种 online policy. online policy 又分为 on policy 和 off policy. on policy 严格要求 gradient 由当前 policy 生成,而 off policy 则可以根据 old policy 进行更新. 上面的 RL 就是一种 on policy. 这是因为 policy 变了,你的 trajectory state 就完全变了,你的 training data 的分布也就变了.


Example: Gaussian Policy

如果我们每一步的 \(p\) 看作一个 gaussian,神经网络计算出来的 policy 是 \((f,\sigma)\),那么 \(\log p(a_t|s_t)\) 就是一个常数加上 \(||a_t-f(s_t)||_{\Sigma}\) ,于是取 gradient 得到 \(-\frac{1}{2}\Sigma^{-1} (f(s_t)-a_t)\frac{df}{d\theta}\).

这个和 L2 Loss 的模仿学习差不多. 但是不同点就在于一个 training data 和你的 Policy 息息相关,不同的 policy 对应的 data 的分布都是不同的.

这是最 naive 的 algo,称为 REINFORCE algo(全大写).

但这也带来一个问题,就是 sample efficienty 太低了.

其实设定上我们还没提到之前提到的 partial observability. 但是实际上,带上那个,重新推导一下,发现只需要把 \(p(a_t|s_t)\) 换成 \(p(a_t|o_t)\) 就行了,还是一样的.


Reward

\(\frac{1}{N}\sum \nabla_{\theta} \log p_{\theta}(\tau)r(\tau)\) 的问题:首先这个 \(r\) variance 很大;其次实际上应该只有 \(r\) 的相对值有关系,而不是绝对值(有时候环境给的奖励也不是很好控制).

reduce variance

首先一个方法是,原本 \(\nabla p(a_i,s_i)\) 的权重都是 \(\sum_{i=0}^{T} r(a_i,s_i)\),但是实际上我们根本不应该关心之前的 \(r\). 所以应该替换成 \(\sum_{j=i}^{T}r(a_j,s_j)\),即 "reward to go". 这也符合我们的 Markov Decision Process.

baseline

即我们要取一个 \(b\),然后所有 \(r(\tau)\) 都减去 \(b\),使得所有 \(r\) 的均值取在 \(0\).

\(b=\frac{1}{N}\sum_{i=1}^{n} r(\tau_i)\). 这个 monte carlo sample 出来的 baseline 估计是无偏的. 效果上还不错.

当然也可以通过求导来算出最好的 baseline,但是一般也不那么做.

Value Function Fitting

但是实际上一个更好的 reward to go 是要考虑这一步之后所有可能的路径的 expectation \(Q^{\pi}_{\theta}(s_t,a_t)=\sum_{i=t}^{T}E[r(s_i,a_i)|s_t,a_t]\) 而不是单单这一条 trajectory 的 reward.

我们还可以定义状态的价值 \(V^{\pi}_{\theta}=\sum_{i=t}^{T}E[r(s_i,a_i)|s_t]=E_{a_t\sim \pi_{\theta}(a_t,s_t)}[Q(s_t,a^t)]\). 这个价值其实就很适合作为 baseline.

也就是说我们直接把最原本式子中的 \(r\) 替换成 \(Q-V\) 看上去就很好. 称之为 Value Function Fitting.

定义函数 \(A^{\pi}(s_i,a_i)=Q^{\pi}(s_i,a_i)-V^{\pi}(s_i)\). 我们把 \(Q\)\(V\) 来表示,就是 \(Q^{\pi}(s_i,a_i)=r(s_i,a_i)+E_{s_{i+1}\sim p(s_{i+1}|s_i,a_i)} [V^{\pi}(s_{i+1})]\). 我们暴力一点,直接把 \(E\) 删掉,得到 \(A^{\pi}(s_i,a_i)=r(s_i,a_i)+V^{\pi}(s_{i+1})-V^{\pi}(s_i)\).

实际上,我们会用一个神经网络去学习 \(V^{\pi}(s_i)\). 为什么呢?因为 monte carlo 得到的原本的 \(V\) 噪声太大了,用一个神经网络去 fit 可以显著降低这种噪声. 我们使用的训练数据就是 \((s_{i,t},y_{i,t}=r(s_i,a_i)+\sum_{j=t+1}^T r(a_j,s_j))\). 令这个网络参数是 \(\phi\),我们就得到 \(\hat V_{\phi}(s_t)\).

这样噪声还是很大. 我们不如直接用上一次训练出来的 \(\hat V_{\phi}(s_{t+1})\) 直接代替掉 monte carlo 得到的 \(\sum_{j=t+1=}^{T}r(a_j,s_j)\). 这样能够继续减小 variance.

discount factor

改为 \(y_{i,t}=r(s_{i,t},a_{i,t})+\gamma V_{\phi}(s_{i},t+1)\). 即时间离得远的 reward 要打一个 discount.

\(\gamma\) 称为 discount factor. 取 \(0.99\) 挺好.

并且这个天然地会去鼓励模型尽早完成任务

同时,\(A\) 也要改为 \(r(a_t,s_t)-V(s_t)+\gamma V(s_{t+1})\).

Actor-critic algo

有两种,一种是 batch,一种是 online.

batch / episodic 就是,先 sample 一些 trajectory,然后再据此做后面的部分.

online 的话,就是每个环境走一步,然后用 \(N\) 个环境得到的\(N\) 个步去更新一下后面的部分.

实际训练中,我们更多地使用 online,因为这样效率就会比较高,一边走一边也在训练.

actor 就是 \(\theta\),critic 就是 \(\phi\). critic 能够帮助 actor 的训练.

actor 和 critic 可以 share 一些参数.

Asynchronous Advantage Actor-Critic:(?)可以节省时间.

一般的 actor critic 长这样:

  • sample \(a\sim \pi_{\theta}(a|s)\),得到一组 \((s,a,s',r)\).
  • \((s,r+\gamma \hat V^{\pi}_{\phi}(s'))\) 更新 \(\phi\).
  • 计算 \(A^{\pi}(s,a)\).
  • \(\nabla_{\theta} \log \pi_{\theta}(a|s) A^{\pi}(s,a)\) 做梯度更新.
Generalized advantage estimation

这有一个问题,就是直接用 \(\hat V^\pi_{\phi}(s)\) 会有 bias,但是只用 monte carlo 又有巨大的 variance.

一个方法是,monte carlo \(n\) 步(使得这 \(n\) 步 variance 不会很大),然后再用 \(\hat V^\pi_{\phi}(s_{t+n})\). 大概 \(n=2\) 或者 \(n=4\) 什么的.

但是我们也可以搞一个类似 discount factor 的东西. 取一个 discount factor \(\lambda\),然后令 \(\delta_{t'}=r(s_{t'},a_{t})-V(s_{t'})+\gamma V(s_{t'+1})\),并取 \(A(s_t,a_t)=\sum_{t'} (\gamma\lambda)^{t'-t}\delta_{t'}\).


实际训练的时候,RL 的 gradient 的 variance 特别大,很 noisy.

一个视觉 observation 要过一个 encoder 得到 feature 之后再 RL,一般需要把 encoder 训好了,freeze 了再训 RL,否则这个 encoder 就会训不好.

调 learning rate 很难.

off policy

on policy 的一个问题是 太 inefficient 了. 而且有 curse of dimension:维度大的时候,很容易走好都没有什么正样本,全是负样本.

off-policy actor-critic:维护一个 replay buffer,记录之前最近一段时间见过的一些 \((s,a,s',r)\) 的 tuple. 然后这些 tuple 都可以去当作训练的 data,大幅度提升了效率.

如何使用这些 off-policy 的数据呢?直接用肯定是错的,所以需要进行修正. 显然旧的 \((s,a,s',r)\) 对于新的应该全是错的,所以我们需要容忍一些错误,修正一些错误. 需要注意我们其实主要是想减少通过 \((s,a)\) 计算出 \(s'\) 的这一个步骤,通过 \(s\) 计算 \(a\) 倒无所谓.

首先看这一步:“用 \((s,r+\gamma \hat V^{\pi}_{\phi}(s'))\) 更新 \(\phi\)”. 我们考虑 \(V(s')\) 是从 \(\hat Q^{\pi}(s,a)\) 来的. 所以我们不妨用新 policy 跑出一个 \(s\) 对应的新的 \(a^{\pi}\),然后用 \(\hat Q^{\pi}(s,a^{\pi})\) 来代替. 这就要求我们不用去 fit \(V\),而是去 fit \(\hat Q^{\pi}(s,a)\). 每次用 \(r(s,a^{\pi})+\gamma \hat Q^{\pi}(s,a^{\pi})\) 去更新 \(\hat Q^{\pi}\). 于是解决了 \(a,s',r\) 的问题.

然后是这一步:"用 \(\nabla_{\theta} \log \pi_{\theta}(a|s) A^{\pi}(s,a)\) 做梯度更新". 这里的 \(\log \pi_{\theta}(a|s)\) 肯定不能用老的. 所以我们还是去跑一个新的 \(a^{\pi}\),然后用 \(\log \pi_{\theta}(a^{\pi}|s)\). 然后一点就是 \(A^{\pi}(s,a)\) 由于没有 \(V\) 了所以有点不好求. 所以我们直接使用 \(\hat Q^{\pi}(s,a^{\pi})\). 兜兜转转最后回到了 \(Q\).

所以现在唯一的问题只有 \(s\) 的分布. 但是其实 \(s\) 的分布只是比以前更广,所以也不是个坏事,反而可能更 robust 了.

当然如果能有更高的 interactive sample efficiency 的话,还是更多的 on-policy 会更有针对性.

Importance Sampling

\[ E_{x\sim p(x)}[f(x)]=\int p(x)f(x)dx=\int q(x)\frac{p(x)}{q(x)}f(x)=E_{x\sim q(x)}[\frac{p(x)}{q(x)}f(x)] \]

所以我们可以从旧的分布中 sample,然后用上面这个式子得到其在新的分布中的信息. \[ \frac{p_{\theta}(\tau)}{\bar p(\tau)}=\frac{\prod \pi_{\theta}(a_t|s_t)}{\prod \bar \pi(a_t|s_t)} \] 带入那个 \(\nabla_{\theta'}\) 的式子会发现还是有这样一个很难受的乘积. 注意到其本质等于 \(\frac{\pi_{\theta'}(s_t)}{\pi_{\theta(s_t)}}\frac{\pi_{\theta'}(a_t|s_t)}{\pi_{\theta}(a_t|s_t)}\). 当 \(s\) 的分布差的不多的时候,所以直接不管前面这项了.

所以就变成了对于 old policy \(\theta_k\),我们的 new policy 的优化目标是 \[ L_{\theta_k,\theta}=E_{s,a\sim \pi_{\theta_k}}[\frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)} A^{\pi_{\theta_k}} (s,a)] \] 但是如果分布差的太多那么就完蛋了.

TRPO

TRPO 的工作在于,找到 \(L_{\theta_k,\theta}\) 的最小的,并满足 \(D_{KL}(\theta||\theta_k)<\delta\)\(\theta\).

数学思想是,对 objective 和 constriant 做泰勒展开,然后取低阶项. 然后针对这个低阶项做拉格朗日乘子法.

PPO

TRPO 有点变态而且用的也比较少. 用的比较多的是 PPO.

PPO follow TRPO 的 intuition,但是方法改成了给 KL Penalty 和 clipped surrogate objective. 这是种 soft constraint.

clipped surrogate:如果 \(A\) 正,则将 \(\frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}\) clip 到对 \(1+\epsilon\) 取 min;否则 clip 到 对 \(1-\epsilon\) 取 max.

adaptive KL Penalty:即加上 \(\beta KL(\pi_{\theta_{old}},\pi_{\theta})\) 的惩罚项. 这个 adaptive 是指,令 \(d=KL\),设一个 \(d_{targ}\),如果 \(d>1.5d_{targ}\) 就让 \(\beta=\beta\times 2\),如果 \(d<d_{targ}/1.5\) 就让 \(\beta=\beta/2\).

并且采用 Generalized Advantage Estimation.

PPO 训练时候的方法:每轮新采数据,但是每次采完数据之后,做 \(k\) 个 epoch 的 update,每个 epoch 的 update 都使用这轮采的全部数据. 和之前完全 on-policy(\(k=1\))相比效率提升很多,但是 \(k\) 也不能太大(不然分布就差太多了).

PPO 的 number of environments 有 \(16384\) 个,mini-batch size 设为 \(512\)\(k\) 设为 \(5\). \(\epsilon\) 设为 \(0.2\). 反正超参数很多.

一些 trick:对于一个 minibatch 对 \(A\) 做一个 normalization(使得 center at \(0\)),然后对 state 做 normalization(和 batchnorm 类似,要记录 running mean 什么的然后 test time 要用这个 running mean),然后对 reward 做 scaling. Initialization 和 Activation 什么的也有研究.

RL 需要调整很多超参!