Last updated on December 22, 2025 12:15 AM
紧急预习用的,比较草,有 AIGC,自用。
REINFORCE
之前的类似 DQN 的方法是对价值函数用神经网络来近似,这里考虑直接对策略用网络。
我们的目标是,找到最佳的参数 θ ∗ \theta^* θ ∗ :
θ ∗ = arg max θ E τ ∼ p θ ( τ ) [ ∑ t r ( s t , a t ) ] \theta^* = \arg\max_{\theta} E_{\tau \sim p_{\theta}(\tau)} \left[\sum_t r(s_t, a_t)\right]
θ ∗ = arg θ max E τ ∼ p θ ( τ ) [ t ∑ r ( s t , a t ) ]
即最大化服从 p θ ( τ ) p_\theta (\tau) p θ ( τ ) 的轨迹 τ \tau τ 的轨迹回报的期望(J ( θ ) J(\theta) J ( θ ) )。
这个东西显然算不了,可以考虑 MC 近似,一次采样 N N N 条轨迹:
J ( θ ) = E τ ∼ p θ ( τ ) [ ∑ t r ( s t , a t ) ] ≈ 1 N ∑ i ∑ t r ( s i , t , a i , t ) J(\theta) =E_{\tau \sim p_{\theta}(\tau)} \left[\sum_t r(s_t, a_t)\right] \approx \frac 1N \sum_i \sum_t r(s_{i,t}, a_{i,t})
J ( θ ) = E τ ∼ p θ ( τ ) [ t ∑ r ( s t , a t ) ] ≈ N 1 i ∑ t ∑ r ( s i , t , a i , t )
对数恒等式:
p θ ( τ ) ∇ θ log p θ ( τ ) = p θ ( τ ) ∇ θ p θ ( τ ) p θ ( τ ) = ∇ θ p θ ( τ ) p_\theta (\tau) \nabla_\theta \log p_\theta (\tau) = p_\theta (\tau) \frac{\nabla_\theta p_\theta (\tau)}{p_{\theta}(\tau)} = \nabla_\theta p_\theta (\tau)
p θ ( τ ) ∇ θ log p θ ( τ ) = p θ ( τ ) p θ ( τ ) ∇ θ p θ ( τ ) = ∇ θ p θ ( τ )
利用这个可以把 ∇ θ p θ ( τ ) \nabla_\theta p_\theta (\tau) ∇ θ p θ ( τ ) 这个没法算的东西拆开。
从积分的角度推导 J θ J_\theta J θ :
J ( θ ) = E τ ∼ p θ ( τ ) [ ∑ t r ( s t , a t ) ] = ∫ p θ ( τ ) r ( τ ) d τ J(\theta) =E_{\tau \sim p_{\theta}(\tau)} \left[\sum_t r(s_t, a_t)\right] = \int p_\theta (\tau) r(\tau) \mathrm{d} \tau
J ( θ ) = E τ ∼ p θ ( τ ) [ t ∑ r ( s t , a t ) ] = ∫ p θ ( τ ) r ( τ ) d τ
求梯度:
∇ θ J ( θ ) = ∫ ∇ θ p θ ( τ ) r ( τ ) d τ = ∫ p θ ( τ ) ∇ θ log p θ ( τ ) r ( τ ) d τ = E τ ∼ p θ ( τ ) [ ∇ θ log p θ ( τ ) r ( τ ) ] \begin{aligned}
\nabla_\theta J(\theta) &= \int \nabla_\theta p_\theta (\tau) r(\tau) \mathrm{d} \tau\\
&= \int p_\theta (\tau) \nabla_\theta \log p_\theta(\tau) r(\tau) \mathrm{d} \tau\\
&= E_{\tau \sim p_\theta (\tau)} \left[\nabla_\theta \log p_\theta(\tau) r(\tau) \right]
\end{aligned}
∇ θ J ( θ ) = ∫ ∇ θ p θ ( τ ) r ( τ ) d τ = ∫ p θ ( τ ) ∇ θ log p θ ( τ ) r ( τ ) d τ = E τ ∼ p θ ( τ ) [ ∇ θ log p θ ( τ ) r ( τ ) ]
我们看一下 p θ ( τ ) p_\theta (\tau) p θ ( τ ) ,发现对于一个轨迹 { s 1 , a 1 , ⋯ , s T , a T } \{s_1,a_1,\cdots, s_T, a_T\} { s 1 , a 1 , ⋯ , s T , a T } ,我们知道
p θ ( τ ) = p ( s 1 ) ∏ t = 1 T π θ ( a t ∣ s t ) p ( s t + 1 ∣ s t , a t ) p_\theta (\tau) = p(s_1) \prod_{t=1}^T \pi_\theta (a_t | s_t) p(s_{t+1}| s_t,a_t)
p θ ( τ ) = p ( s 1 ) t = 1 ∏ T π θ ( a t ∣ s t ) p ( s t + 1 ∣ s t , a t )
其中 π θ ( a t ∣ s t ) \pi_\theta (a_t | s_t) π θ ( a t ∣ s t ) 为模型输出的“在 s t s_t s t 下选择 a t a_t a t 的概率”,p ( s t + 1 ∣ s t , a t ) p(s_{t+1}|s_t,a_t) p ( s t + 1 ∣ s t , a t ) 是环境动力学,与 θ \theta θ 无关 。两边取对数,再关于 θ \theta θ 求梯度:
log p θ ( τ ) = log p ( s 1 ) + ∑ t = 1 T ( log π θ ( a t ∣ s t ) + log p ( s t + 1 ∣ s t , a t ) ) ∇ θ log p θ ( τ ) = ∇ θ log p ( s 1 ) + ∑ t = 1 T ( ∇ θ log π θ ( a t ∣ s t ) + ∇ θ log p ( s t + 1 ∣ s t , a t ) ) = ∑ t = 1 T ∇ θ log π θ ( a t ∣ s t ) \begin{aligned}
\log p_\theta(\tau) &= \log p(s_1) + \sum_{t=1}^T \left(\log \pi_\theta(a_t|s_t) + \log p(s_{t+1}|s_t,a_t) \right)\\
\nabla_\theta\log p_\theta(\tau) &= {\color{gray}{\nabla_\theta\log p(s_1)}} + \sum_{t=1}^T \left(\nabla_\theta\log \pi_\theta(a_t|s_t) + {\color{gray}{\nabla_\theta\log p(s_{t+1}|s_t,a_t)}} \right)\\
&= \sum_{t=1}^T \nabla_\theta \log \pi_\theta (a_t|s_t)
\end{aligned}
log p θ ( τ ) ∇ θ log p θ ( τ ) = log p ( s 1 ) + t = 1 ∑ T ( log π θ ( a t ∣ s t ) + log p ( s t + 1 ∣ s t , a t ) ) = ∇ θ l o g p ( s 1 ) + t = 1 ∑ T ( ∇ θ log π θ ( a t ∣ s t ) + ∇ θ l o g p ( s t + 1 ∣ s t , a t ) ) = t = 1 ∑ T ∇ θ log π θ ( a t ∣ s t )
标灰色的部分因为和 θ \theta θ 无关,所以求梯度的时候都被消掉了。
于是我们最终得到
∇ θ J ( θ ) = E τ ∼ p θ ( τ ) [ ∇ θ log p θ ( τ ) r ( τ ) ] = E τ ∼ p θ ( τ ) [ ( ∑ t = 1 T ∇ θ log π θ ( a t ∣ s t ) ) ⋅ ( ∑ t = 1 T r ( s t , a t ) ) ] \begin{aligned}
\nabla_\theta J(\theta) &= E_{\tau \sim p_\theta (\tau)} \left[\nabla_\theta \log p_\theta(\tau) r(\tau) \right]\\
&= E_{\tau\sim p_\theta (\tau)}\left[\left(\sum_{t=1}^T \nabla_\theta \log \pi_\theta (a_t | s_t) \right) \cdot \left( \sum_{t=1}^T r(s_t,a_t) \right) \right]
\end{aligned}
∇ θ J ( θ ) = E τ ∼ p θ ( τ ) [ ∇ θ log p θ ( τ ) r ( τ ) ] = E τ ∼ p θ ( τ ) [ ( t = 1 ∑ T ∇ θ log π θ ( a t ∣ s t ) ) ⋅ ( t = 1 ∑ T r ( s t , a t ) ) ]
这个强大之处在于:
Model free :不需要知道环境是怎么运作的;
奖励不需要可导 :完全不需要对奖励求导,只需要采样累计回报就可以了;
通过对数导数技巧允许我们将“求整个概率分布变化的梯度 ”这样一个不可能完成的任务,转化成了“在玩游戏过程中,看看哪些动作带来了高分,就增大那个动作的概率对数 ”这样一个可以通过代码实现的任务。
所以得到最简单的策略梯度算法 REINFORCE:
REINFORCE 算法:
从 π θ ( a t ∣ s t ) \pi_\theta(a_t|s_t) π θ ( a t ∣ s t ) 中采样 τ i {\tau^i} τ i (run episodes)
∇ θ J ( θ ) ≈ ∑ i ( ∑ t ∇ θ log π θ ( a t i ∣ s t i ) ) ( ∑ t r ( s t i ∣ a t i ) ) \nabla_\theta J(\theta) \approx \sum_i (\sum_t \nabla_\theta \log \pi_\theta(a_t^i|s_t^i))(\sum_t r(s_t^i|a_t^i)) ∇ θ J ( θ ) ≈ ∑ i ( ∑ t ∇ θ log π θ ( a t i ∣ s t i ) ) ( ∑ t r ( s t i ∣ a t i ) )
θ ← θ + α ∇ θ J ( θ ) \theta \leftarrow \theta + \alpha \nabla_\theta J(\theta) θ ← θ + α ∇ θ J ( θ )
Python 的直观实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import torchimport torch.optim as optimimport numpy as npdef train_one_episode (env, policy_net, optimizer ): states, actions, rewards = [], [], [] state = env.reset() done = False while not done: probs = policy_net(torch.tensor(state)) dist = torch.distributions.Categorical(probs) action = dist.sample() log_prob = dist.log_prob(action) next_state, reward, done, _ = env.step(action.item()) rewards.append(reward) policy_net.saved_log_probs.append(log_prob) state = next_state R = sum (rewards) policy_loss = [] for log_prob in policy_net.saved_log_probs: loss = -log_prob * R policy_loss.append(loss) final_loss = torch.stack(policy_loss).sum () optimizer.zero_grad() final_loss.backward() optimizer.step()
和 Behavior Cloning 的不同在于,BC 平等对待每个 ( s , a ) (s,a) ( s , a ) 对(人家干啥你就干啥),RL 的话会对于 r ( τ ) r(\tau) r ( τ ) 加权,对带来更高回报的进行更大加权。
BC:数据太好也不行,太差也不行
RL:几乎没法在真机上做。
REINFORCE 可能遇到的问题:
虽然是无偏 的,但是方差可能很高
采样效率很低:必须要 roll 很多 episodes
严格 on-policy ,回合更新且数据利用率低(只能用当前 policy 跑出来的轨迹,之前的全被丢掉了)
用一局的总回报更新每个动作:一开始好但后面坏掉的局面
而且只有 reward 的相对值 有价值,绝对值不太有价值。如果 r r r 全部大于 0,不是什么好事。而如果一个“好”的轨迹的 reward 是 0 那就更坏事了。
降低方差
Reward to go
考虑因果性 ,后面的策略不影响前面的:
∇ θ J ( θ ) = E τ ∼ p θ ( τ ) [ ( ∑ t = 1 T ∇ θ log π θ ( a t ∣ s t ) ) ⋅ ( ∑ t ′ = t T r ( s t ′ , a t ′ ) ) ] \nabla_\theta J(\theta) = E_{\tau\sim p_\theta (\tau)}\left[\left(\sum_{t=1}^T \nabla_\theta \log \pi_\theta (a_t | s_t) \right) \cdot \left( \sum_{t'=t}^T r(s_t',a_t') \right) \right]
∇ θ J ( θ ) = E τ ∼ p θ ( τ ) [ ( t = 1 ∑ T ∇ θ log π θ ( a t ∣ s t ) ) ⋅ ( t ′ = t ∑ T r ( s t ′ , a t ′ ) ) ]
可以证明这个也是无偏 的。
Baseline
取 N N N 条轨迹 reward 的平均值:
b = 1 N ∑ i = 1 N r ( τ i ) b = \frac 1N \sum_{i=1}^N r(\tau_i)
b = N 1 i = 1 ∑ N r ( τ i )
然后:
∇ θ J ( θ ) ≈ 1 N ∑ i = 1 N ∇ θ log p θ ( τ ) ( r ( τ ) − b ) \nabla_\theta J(\theta) \approx \frac 1N \sum_{i=1}^N \nabla_\theta \log p_\theta(\tau) (r(\tau) - b)
∇ θ J ( θ ) ≈ N 1 i = 1 ∑ N ∇ θ log p θ ( τ ) ( r ( τ ) − b )
合法性源于 E [ ∇ θ log p θ ( τ ) b ] = 0 E[\nabla_\theta \log p_\theta (\tau) b] = 0 E [ ∇ θ log p θ ( τ ) b ] = 0 ,证明依旧利用那个对数:
E [ ∇ θ log p θ ( τ ) b ] = ∫ p θ ( τ ) ∇ θ log p θ ( τ ) b d τ = ∫ ∇ θ p θ ( τ ) b d τ = b ∇ θ ∫ p θ ( τ ) d τ = b ∇ θ 1 = 0 E[\nabla_\theta \log p_\theta (\tau) b] = \int p_\theta(\tau) \nabla_\theta \log p_\theta(\tau) b\mathrm{d}\tau = \int \nabla_\theta p_\theta(\tau) b \mathrm{d}\tau = b \nabla_\theta \int p_\theta(\tau) \mathrm{d} \tau = b \nabla_\theta 1 = 0
E [ ∇ θ log p θ ( τ ) b ] = ∫ p θ ( τ ) ∇ θ log p θ ( τ ) b d τ = ∫ ∇ θ p θ ( τ ) b d τ = b ∇ θ ∫ p θ ( τ ) d τ = b ∇ θ 1 = 0
所以加减常数是完全不影响正确性的。
基于将方差表达为关于 b b b 的函数可以求出一个最优的 b b b 。具体推导比较复杂,但实践中这通常不是特别有必要。
Actor-Critic
引入
直觉:策略梯度中的 reward-to-go 式子只是一条轨迹的,肯定方差是比较大的。 那么如果我们能用 Q Q Q 函数来替代,方差肯定会减小了,注意到这也是无偏的。具体证明使用重期望公式,这里不展开了。
定义 Q Q Q 函数
Q π ( s t , a t ) : = ∑ t ′ = t T E π θ [ r ( s t ′ , a t ′ ) ∣ s t , a t ] Q^{\pi} (s_t, a_t) := \sum_{t' = t}^T E_{\pi_\theta} [r(s_{t'}, a_{t'}) | s_t, a_t]
Q π ( s t , a t ) : = t ′ = t ∑ T E π θ [ r ( s t ′ , a t ′ ) ∣ s t , a t ]
补充定义价值函数 V V V :
V π ( s t ) : = ∑ t ′ = t T E π θ [ r ( s t ′ , a t ′ ) ∣ s t ] = E a t ∼ π ( a t ∣ s t ) [ Q π ( s t , a t ) ] V^\pi(s_t) := \sum_{t' = t}^T E_{\pi_\theta} [r(s_{t'}, a_{t'}) | s_t] = E_{a_t \sim \pi(a_t | s_t)}[Q^\pi(s_t, a_t)]
V π ( s t ) : = t ′ = t ∑ T E π θ [ r ( s t ′ , a t ′ ) ∣ s t ] = E a t ∼ π ( a t ∣ s t ) [ Q π ( s t , a t ) ]
注意到减去一个 baseline 也是无偏的,所以直接考虑减去 V π ( s t ) V^\pi(s_t) V π ( s t ) (可以理解为平均回报)来评估 a t a_t a t 这个动作的优势 。定义优势函数
A π ( s t , a t ) = Q π ( s t , a t ) − V π ( s t ) A^\pi(s_t, a_t) = Q^\pi (s_t, a_t) - V^\pi (s_t)
A π ( s t , a t ) = Q π ( s t , a t ) − V π ( s t )
但是我们总不可能通过真的从 s t s_t s t 开始继续 roll out 那么多条轨迹来进行评估 V V V 和 Q Q Q ,怎么办呢?使用神经网络来拟合 。但是拟合三个网络还是有点蠢了而且没必要,所以我们利用 Bellman 方程给的近似关系只拟合价值函数 V V V 。
我们发现,Q π ( s t , a t ) ≈ r ( s t , a t ) + V π ( s t + 1 ) Q^\pi (s_t, a_t) \approx r(s_t, a_t) + V^\pi (s_{t+1}) Q π ( s t , a t ) ≈ r ( s t , a t ) + V π ( s t + 1 ) ,$A(s_t, a_t) = Q^\pi(s_t, a_t) - V^\pi(S_t) \approx r(s_t, a_t) + V^\pi(s_{t+1}) - V^\pi (s_t) $,所以只用一个 V V V 就 OK 了。
于是整个算法的大致流程如下:actor 玩一把/几把游戏 -> critic 网络拟合 V π V^\pi V π -> 进行策略提升。
如何求价值函数
考虑在状态 s i , t s_{i,t} s i , t 最终拿到了总分 y i , t y_{i,t} y i , t 。然后就用监督学习,输入是状态 s i s_i s i ,标签是跑出来的总回报 y i y_i y i ,用 V ^ ϕ π \hat{V}_\phi^\pi V ^ ϕ π 来最小化预测误差。这个本质上就是 N = 1 N=1 N = 1 的 Monte Carlo 估计,虽然无偏但是训练非常不稳定。
为了降低方差,引入 Bootstrapping 方法(自己拽着自己往前跑),利用 Critic 对下一步状态的估计来更新当前对 s t s_t s t 的估计,target 变成
y i , t ≈ r ( s i , t , a i , t ) + V ^ ϕ π ( s i , t + 1 ) y_{i,t} \approx r(s_{i,t}, a_{i,t}) + \hat V_\phi^\pi (s_{i, t+1})
y i , t ≈ r ( s i , t , a i , t ) + V ^ ϕ π ( s i , t + 1 )
带上折扣因子 γ \gamma γ (更着重近的奖励)的话,就是 r ( s i , t , a i , t ) + γ V ^ ϕ π ( s i , t + 1 ) r(s_{i,t}, a_{i,t}) + \gamma \hat V_\phi^\pi(s_{i,t+1}) r ( s i , t , a i , t ) + γ V ^ ϕ π ( s i , t + 1 ) 。这就是很经典的 TD Target。
这样子可以显著降低方差 但是由于 V ^ \hat V V ^ 是网络估计出来的值,所以引入了偏差 。
这样,优势函数 A ( s , a ) A(s,a) A ( s , a ) 的估计值变成经典的 TD error 的形式:
A ^ π ( s t , a t ) = r ( s t , a t ) + γ V ^ ϕ π ( s t + 1 ) − V ^ ϕ π ( s t ) \hat A^\pi(s_t, a_t) = r(s_t, a_t) + \gamma \hat V_\phi^\pi (s_{t+1}) - \hat V_\phi^\pi(s_t)
A ^ π ( s t , a t ) = r ( s t , a t ) + γ V ^ ϕ π ( s t + 1 ) − V ^ ϕ π ( s t )
关于折扣因子,对于 Monte Carlo 策略梯度,γ t ′ − t \gamma^{t'-t} γ t ′ − t 和 γ t ′ − 1 \gamma^{t'-1} γ t ′ − 1 的区别见 0414 EAI 第 46 页。后者为严格推导出的但是实际中用前者(discounted reward-to-go)
偏差与方差的权衡
我们现在有了两种计算 A A A (或者说 Target) 的方法:
Monte Carlo : ∑ γ k r t + k − V ( s t ) \sum \gamma^k r_{t+k} - V(s_t) ∑ γ k r t + k − V ( s t ) → \to → 无偏,高方差。
TD(0) : r t + γ V ( s t + 1 ) − V ( s t ) r_t + \gamma V(s_{t+1}) - V(s_t) r t + γ V ( s t + 1 ) − V ( s t ) → \to → 低方差,高偏差。
能不能折中一下?
N-step Returns
我们可以不只看 1 步,也不看无穷步,而是看 n n n 步:
A ^ n π ( s t , a t ) = ∑ k = 0 n − 1 γ k r t + k + γ n V ^ ϕ π ( s t + n ) − V ^ ϕ π ( s t ) \hat{A}_n^\pi(s_t, a_t) = \sum_{k=0}^{n-1} \gamma^k r_{t+k} + \gamma^n \hat{V}_\phi^\pi(s_{t+n}) - \hat{V}_\phi^\pi(s_t)
A ^ n π ( s t , a t ) = k = 0 ∑ n − 1 γ k r t + k + γ n V ^ ϕ π ( s t + n ) − V ^ ϕ π ( s t )
n = 1 n=1 n = 1 就是 TD(0)。
n = ∞ n=\infty n = ∞ 就是 Monte Carlo。
n n n 越大,方差越大,偏差越小。
2. GAE (Generalized Advantage Estimation)
GAE 是目前最常用的方法。它的核心思想是把所有可能的 n n n -step returns 进行加权平均(权重随 n n n 指数衰减)。
定义 δ t = r t + γ V ( s t + 1 ) − V ( s t ) \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) δ t = r t + γ V ( s t + 1 ) − V ( s t ) 为单步 TD error。
GAE 的计算公式为:
A ^ t G A E = ∑ k = 0 ∞ ( γ λ ) k δ t + k \hat{A}^{GAE}_t = \sum_{k=0}^\infty (\gamma \lambda)^k \delta_{t+k}
A ^ t G A E = k = 0 ∑ ∞ ( γ λ ) k δ t + k
其中 λ ∈ [ 0 , 1 ] \lambda \in [0, 1] λ ∈ [ 0 , 1 ] 是一个超参数:
λ = 0 \lambda = 0 λ = 0 : 变回 TD(0),方差最小,偏差最大。
λ = 1 \lambda = 1 λ = 1 : 变回 Monte Carlo,无偏,方差最大。
通常取 λ = 0.95 \lambda = 0.95 λ = 0 . 9 5 ,在两者之间取得很好的平衡。
网络架构设计
在代码实现中,Actor 和 Critic 的网络结构有两种常见设计:
Two Network Design (独立网络)
Actor 网络 π θ ( a ∣ s ) \pi_\theta(a|s) π θ ( a ∣ s ) 和 Critic 网络 V ϕ ( s ) V_\phi(s) V ϕ ( s ) 完全独立,参数不共享。
优点 :简单,训练稳定,互不干扰。
缺点 :无法共享特征(feature),如果输入是图像(CNN),计算量会由两倍。
Shared Network Design (共享网络)
Batch vs Online Actor-Critic
两种 actor-critic 的核心都一样:
Actor :用策略梯度更新参数 (\theta)
Critic :拟合状态价值 (\hat V_\phi(s)),并用它构造 advantage 给 actor 用
差别主要在于:critic/actor 是“攒一批再更新”(batch),还是“每一步都更新”(online) 。
共同核心:1-step TD advantage(TD-error)
用 critic 近似:
V ^ ϕ ( s ) ≈ V π ( s ) \hat V_\phi(s)\approx V^\pi(s)
V ^ ϕ ( s ) ≈ V π ( s )
最常用的 advantage 估计是 1-step bootstrap:
A ^ ( s , a ) = r ( s , a ) + γ V ^ ϕ ( s ′ ) − V ^ ϕ ( s ) \hat A(s,a)
= r(s,a) + \gamma \hat V_\phi(s') - \hat V_\phi(s)
A ^ ( s , a ) = r ( s , a ) + γ V ^ ϕ ( s ′ ) − V ^ ϕ ( s )
也常写成 TD-error:
δ t : = r t + γ V ^ ϕ ( s t + 1 ) − V ^ ϕ ( s t ) , A ^ t = δ t \delta_t := r_t + \gamma \hat V_\phi(s_{t+1}) - \hat V_\phi(s_t),
\quad \hat A_t=\delta_t
δ t : = r t + γ V ^ ϕ ( s t + 1 ) − V ^ ϕ ( s t ) , A ^ t = δ t
Actor 的梯度估计:
∇ θ J ( θ ) ≈ ∑ i ∇ θ log π θ ( a i ∣ s i ) A ^ ( s i , a i ) \nabla_\theta J(\theta)\approx \sum_i \nabla_\theta \log \pi_\theta(a_i|s_i)\ \hat A(s_i,a_i)
∇ θ J ( θ ) ≈ i ∑ ∇ θ log π θ ( a i ∣ s i ) A ^ ( s i , a i )
更新:
θ ← θ + α ∇ θ J ( θ ) \theta \leftarrow \theta + \alpha \nabla_\theta J(\theta)
θ ← θ + α ∇ θ J ( θ )
注:如果有 terminal(done),需要把 bootstrap 切断:
δ t : = r t + γ ( 1 − d t + 1 ) V ^ ϕ ( s t + 1 ) − V ^ ϕ ( s t ) \delta_t := r_t + \gamma(1-d_{t+1})\hat V_\phi(s_{t+1}) - \hat V_\phi(s_t)
δ t : = r t + γ ( 1 − d t + 1 ) V ^ ϕ ( s t + 1 ) − V ^ ϕ ( s t )
Batch actor-critic:先采样一批,再集中更新
直觉:先把数据攒起来,再用 mini-batch 的方式把 critic 拟合得更靠谱,然后用这一批数据统一更新 actor(梯度更平滑、更稳定)。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 repeat: # 1) collect a batch with current policy D = {} for step = 1..N: a ~ πθ(a|s) (s', r, done) = env.step(a) store (s, a, r, s', done) into D if done: reset env and get new s else: s = s' # 2) update critic (value fitting) # target 可以是 MC / n-step / TD(lambda) 等,这里写成最常见的 TD target for k = 1..K_v: # K_v: critic updates per batch sample minibatch B from D y = r + γ(1-done) Vφ(s') minimize Σ (Vφ(s) - y)^2 over φ # 3) compute advantages on the batch (1-step TD form) for (s,a,r,s',done) in D: A = r + γ(1-done) Vφ(s') - Vφ(s) # 4) update actor with the batch advantages for k = 1..K_π: # K_π: actor updates per batch sample minibatch B from D maximize Σ log πθ(a|s) * A over θ until convergence
特点:
✅ 梯度更稳:一次用一批样本估计方向,噪声更小
❌ 更新更“滞后”:要等攒够一批数据才能更新一次
Online actor-critic:交互一步,立刻更新一步
直觉:每走一步就用当前 transition 更新 critic,再用同一个 TD-error 立刻更新 actor(反应快,但更 noisy)。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 initialize θ, φ s = env.reset() repeat: # 1) act a ~ πθ(a|s) (s', r, done) = env.step(a) # 2) critic update (one-step TD) δ = r + γ(1-done) Vφ(s') - Vφ(s) φ ← φ - β * ∇φ (δ^2) # value regression / TD learning # 3) actor update (policy gradient with TD advantage) θ ← θ + α * ∇θ log πθ(a|s) * δ if done: s = env.reset() else: s = s' until convergence
特点:
✅ 反应快:每一步都能立刻修正策略
❌ 更抖:单步更新的方差更大,通常要更小学习率或做一些稳定化(例如把 online 改成“小 batch online”、或用 GAE / n-step)
一个容易混的点:critic 的 target 和 actor 的 advantage 不一定必须同一种
常见组合是:
critic 用某种 return target 做回归(TD / n-step / λ \lambda λ -return)
actor 用 advantage 做更新(1-step TD-error 或 GAE)
它们都在做同一件事:用 V ^ ϕ \hat V_\phi V ^ ϕ 把“未来回报”压缩成一个可学习的信号,从而降低策略梯度的方差。