系列文章目录

Fundamental Tools

RL【1】:Basic Concepts
RL【2】:Bellman Equation
RL【3】:Bellman Optimality Equation

Algorithm

RL【4】:Value Iteration and Policy Iteration
RL【5】:Monte Carlo Learning
RL【6】:Stochastic Approximation and Stochastic Gradient Descent

Method

RL【7-1】:Temporal-difference Learning
RL【7-2】:Temporal-difference Learning
RL【8】:Value Function Approximation
RL【9】:Policy Gradient
RL【10-1】:Actor - Critic
RL【10-2】:Actor - Critic


文章目录

  • 系列文章目录
    • Fundamental Tools
    • Algorithm
    • Method
  • 前言
  • Off-policy actor-critic
    • Importance sampling
    • The theorem of off-policy policy gradient
    • The algorithm of off-policy actor-critic
  • Deterministic actor-critic (DPG)
    • Introduction
    • The theorem of deterministic policy gradient
    • The algorithm of deterministic actor-critic
  • 总结


前言

本系列文章主要用于记录 B站 赵世钰老师的【强化学习的数学原理】的学习笔记,关于赵老师课程的具体内容,可以移步:
B站视频:【【强化学习的数学原理】课程:从零开始到透彻理解(完结)】
GitHub 课程资料:Book-Mathematical-Foundation-of-Reinforcement-Learning


Off-policy actor-critic

Importance sampling

Definition

Note that

EX∼p0[X]=∑xp0(x)x=∑xp1(x)p0(x)p1(x)x=EX∼p1[f(X)]\mathbb{E}{X \sim p_0}[X] = \sum_x p_0(x)x = \sum_x p_1(x) \frac{p_0(x)}{p_1(x)} x = \mathbb{E}{X \sim p_1}[f(X)]EXp0[X]=xp0(x)x=xp1(x)p1(x)p0(x)x=EXp1[f(X)]

  • Thus, we can estimate EX∼p1[f(X)]\mathbb{E}{X \sim p_1}[f(X)]EXp1[f(X)] in order to estimate EX∼p0[X]\mathbb{E}{X \sim p_0}[X]EXp0[X].
  • How to estimate EX∼p1[f(X)]\mathbb{E}_{X \sim p_1}[f(X)]EXp1[f(X)]? Easy.
    • Let

      fˉ≐1n∑i=1nf(xi),where xi∼p1\bar{f} \doteq \frac{1}{n}\sum_{i=1}^n f(x_i), \quad \text{where } x_i \sim p_1fˉn1i=1nf(xi),where xip1

    • Then,

      EX∼p1[fˉ]=EX∼p1[f(X)]\mathbb{E}{X \sim p_1}[\bar{f}] = \mathbb{E}{X \sim p_1}[f(X)]EXp1[fˉ]=EXp1[f(X)]

      varX∼p1[fˉ]=1nvarX∼p1[f(X)]\text{var}{X \sim p_1}[\bar{f}] = \frac{1}{n}\text{var}{X \sim p_1}[f(X)]varXp1[fˉ]=n1varXp1[f(X)]

定理推导

  1. 基本思想
    • 我们通常想要估计一个期望:

      EX∼p0[X]\mathbb{E}_{X \sim p_0}[X]EXp0[X]

    • 但有时候 直接从 p0p_0p0 采样很难,或者采样代价高。于是我们考虑换一个更容易采样的分布 p1p_1p1,但同时通过一个修正因子(importance weight)来保持无偏估计。

  2. 推导过程
    • 从定义出发:

      EX∼p0[X]=∑xp0(x)x\mathbb{E}_{X \sim p_0}[X] = \sum_x p_0(x)xEXp0[X]=xp0(x)x

    • 插入一个“1”:

      =∑xp1(x)p0(x)p1(x)x=EX∼p1[f(X)]= \sum_x p_1(x)\frac{p_0(x)}{p_1(x)}x = \mathbb{E}_{X \sim p_1}[f(X)]=xp1(x)p1(x)p0(x)x=EXp1[f(X)]

      • 其中:

        f(x)=p0(x)p1(x)xf(x) = \frac{p_0(x)}{p_1(x)} xf(x)=p1(x)p0(x)x

    • 这样就把原本关于 p0p_0p0 的期望,转化成了关于 p1p_1p1 的期望。

  3. Monte Carlo 近似
    • 由于无法解析计算 EX∼p1[f(X)]\mathbb{E}_{X \sim p_1}[f(X)]EXp1[f(X)],我们用采样近似:
      • 采样 nnn 个样本 xi∼p1x_i \sim p_1xip1,定义

        fˉ=1n∑i=1nf(xi)=1n∑i=1np0(xi)p1(xi)xi\bar{f} = \frac{1}{n}\sum_{i=1}^n f(x_i) = \frac{1}{n}\sum_{i=1}^n \frac{p_0(x_i)}{p_1(x_i)} x_ifˉ=n1i=1nf(xi)=n1i=1np1(xi)p0(xi)xi

      • 性质:

        • 无偏:EX∼p1[fˉ]=EX∼p0[X]\mathbb{E}{X \sim p_1}[\bar{f}] = \mathbb{E}{X \sim p_0}[X]EXp1[fˉ]=EXp0[X]
        • 方差:Var[fˉ]=1nVar[f(X)]\text{Var}[\bar{f}] = \frac{1}{n}\text{Var}[f(X)]Var[fˉ]=n1Var[f(X)]
    • 所以样本数越多,估计越稳定。

Importance Weight

Therefore, fˉ\bar{f}fˉ is a good approximation for EX∼p1[f(X)]=EX∼p0[X]\mathbb{E}{X \sim p_1}[f(X)] = \mathbb{E}{X \sim p_0}[X]EXp1[f(X)]=EXp0[X].

EX∼p0[X]≈fˉ=1n∑i=1nf(xi)=1n∑i=1np0(xi)p1(xi)xi\mathbb{E}{X \sim p_0}[X] \approx \bar{f} = \frac{1}{n}\sum{i=1}^n f(x_i) = \frac{1}{n}\sum_{i=1}^n \frac{p_0(x_i)}{p_1(x_i)} x_iEXp0[X]fˉ=n1i=1nf(xi)=n1i=1np1(xi)p0(xi)xi

  • p0(xi)p1(xi)\frac{p_0(x_i)}{p_1(x_i)}p1(xi)p0(xi) is called the importance weight.
    • If p1(xi)=p0(xi)p_1(x_i) = p_0(x_i)p1(xi)=p0(xi), the importance weight is one and fˉ\bar{f}fˉ becomes xˉ\bar{x}xˉ.
    • If p0(xi)≥p1(xi)p_0(x_i) \geq p_1(x_i)p0(xi)p1(xi), xix_ixi can be more often sampled by p0p_0p0 than p1p_1p1.
      The importance weight (>1> 1>1) can emphasize the importance of this sample.

Importance Weight 的意义

  • 修正因子:

    w(x)=p0(x)p1(x)w(x) = \frac{p_0(x)}{p_1(x)}w(x)=p1(x)p0(x)

  • 解释:

    • 如果 p1(x)=p0(x)p_1(x) = p_0(x)p1(x)=p0(x),那么 w(x)=1w(x)=1w(x)=1,这就退化成普通 Monte Carlo。
    • 如果某个 xxxp0p_0p0 下比在 p1p_1p1 下更常见(即 p0(x)≥p1(x)p_0(x) \ge p_1(x)p0(x)p1(x)),那么 w(x)>1w(x) > 1w(x)>1,采到这个样本时会“放大”它的重要性。
    • 相反,如果 p0(x)≪p1(x)p_0(x) \ll p_1(x)p0(x)p1(x),那么 w(x)<1w(x) < 1w(x)<1,采到的样本会被削弱影响。
  • 直观上:importance weight 让“偏样”的分布 p1p_1p1 采到的数据,能被重新加权,修正成目标分布 p0p_0p0 下的真实期望。

Q & A

  • Question
    • While fˉ=1n∑i=1np0(xi)p1(xi)xi\bar{f} = \frac{1}{n}\sum_{i=1}^n \frac{p_0(x_i)}{p_1(x_i)}x_ifˉ=n1i=1np1(xi)p0(xi)xi requires p0(x)p_0(x)p0(x), if I know p0(x)p_0(x)p0(x), why not directly calculate the expectation?
  • Answer
    • It is applicable to the case where it is easy to calculate p0(x)p_0(x)p0(x) given an xxx, but difficult to calculate the expectation.
      • For example, continuous case, complex expression of p0p_0p0, or no expression of p0p_0p0 (e.g., p0p_0p0 represented by a neural network).

为什么不直接算期望?

  • 既然要用到 p0(x)p_0(x)p0(x),为什么不直接计算 EX∼p0[X]\mathbb{E}_{X \sim p_0}[X]EXp0[X]
  • 原因:
    • 我们可能能写出 p0(x)p_0(x)p0(x),但它的积分或期望形式复杂,没法直接算。
      • 比如在连续空间,高维积分几乎不可解。
      • p0(x)p_0(x)p0(x) 可能由神经网络表示(无解析形式)。
    • 而从 p1p_1p1 采样比较容易,比如选择一个更简单的分布。

Equation Summary

if {xi}∼p1\{x_i\} \sim p_1{xi}p1,

xˉ=1n∑i=1nxi→EX∼p1[X]\bar{x} = \frac{1}{n}\sum_{i=1}^n x_i \to \mathbb{E}_{X \sim p_1}[X]xˉ=n1i=1nxiEXp1[X]

fˉ=1n∑i=1np0(xi)p1(xi)xi→EX∼p0[X]\bar{f} = \frac{1}{n}\sum_{i=1}^n \frac{p_0(x_i)}{p_1(x_i)} x_i \to \mathbb{E}_{X \sim p_0}[X]fˉ=n1i=1np1(xi)p0(xi)xiEXp0[X]

在 RL 中的应用

  • 在强化学习里:

    • 行为策略:采样数据的分布 p1=πbp_1 = \pi_bp1=πb(behavior policy)
    • 目标策略:我们想优化的分布 p0=πp_0 = \pip0=π(target policy)
  • 如果直接用行为策略的数据来学习,会有分布不匹配的问题。Importance sampling 就通过

    wt=π(at∣st)πb(at∣st)w_t = \frac{\pi(a_t|s_t)}{\pi_b(a_t|s_t)}wt=πb(atst)π(atst)

    • 来修正,使得学习仍然是关于目标策略的无偏估计。

The theorem of off-policy policy gradient

Like the previous on-policy case, we need to derive the policy gradient in the off-policy case.

  • Suppose β\betaβ is the behavior policy that generates experience samples.

  • Our aim is to use these samples to update a target policy π\piπ that can minimize the metric

    J(θ)=∑s∈Sdβ(s)vπ(s)=ES∼dβ[vπ(S)]J(\theta) = \sum_{s \in \mathcal{S}} d_\beta(s) v_\pi(s) = \mathbb{E}{S \sim d\beta}[v_\pi(S)]J(θ)=sSdβ(s)vπ(s)=ESdβ[vπ(S)]

    • where dβd_\betadβ is the stationary distribution under policy β\betaβ.

Theorem (Off-policy policy gradient theorem)

  • In the discounted case where γ∈(0,1)\gamma \in (0,1)γ(0,1), the gradient of J(θ)J(\theta)J(θ) is

    ∇θJ(θ)=ES∼ρ,A∼β[π(A∣S,θ)β(A∣S)∇θln⁡π(A∣S,θ)qπ(S,A)]\nabla_\theta J(\theta) = \mathbb{E}{S \sim \rho, A \sim \beta} \left[ \frac{\pi(A|S,\theta)}{\beta(A|S)} \nabla\theta \ln \pi(A|S,\theta) q_\pi(S,A) \right]θJ(θ)=ESρ,Aβ[β(AS)π(AS,θ)θlnπ(AS,θ)qπ(S,A)]

    • where β\betaβ is the behavior policy and ρ\rhoρ is a state distribution.

Off-policy Policy Gradient Theorem 的直观含义和推导思路。

1. 背景:为什么要 Off-policy?

  • 在前面 on-policy 的情形中,
    • 我们用目标策略 π\piπ 自己生成的轨迹来更新 π\piπ
    • 但是在实际应用中,常常会遇到以下问题:
      • 目标策略 π\piπ 还没收敛,样本质量不足;
      • 我们已经有了由其他策略(例如旧的策略、随机策略、经验库)生成的大量数据;
      • 希望 复用已有样本 来提高数据利用率。
  • 这时候,就需要 off-policy learning
    • 利用行为策略 β\betaβ 生成的样本,去更新目标策略 π\piπ
  1. 性能目标函数
    • 定义目标函数:

      J(θ)=∑s∈Sdβ(s)vπ(s)J(\theta) = \sum_{s \in \mathcal{S}} d_\beta(s) v_\pi(s)J(θ)=sSdβ(s)vπ(s)

      =ES∼dβ[vπ(S)]= \mathbb{E}{S \sim d\beta}[v_\pi(S)]=ESdβ[vπ(S)]

      • dβ(s)d_\beta(s)dβ(s):在行为策略 β\betaβ 下,状态 sss平稳分布
      • vπ(s)v_\pi(s)vπ(s):在目标策略 π\piπ 下,从状态 sss 出发的期望回报。
    • 也就是说,我们要最大化的是:β\betaβ 产生的状态分布下,π\piπ 的价值函数

  2. Off-policy Policy Gradient Theorem
    • 定理给出的梯度形式是:

      ∇θJ(θ)=ES∼ρ,A∼β[π(A∣S,θ)β(A∣S)∇θln⁡π(A∣S,θ)qπ(S,A)]\nabla_\theta J(\theta) = \mathbb{E}{S \sim \rho, A \sim \beta} \left[ \frac{\pi(A|S,\theta)}{\beta(A|S)} \nabla\theta \ln \pi(A|S,\theta) q_\pi(S,A) \right]θJ(θ)=ESρ,Aβ[β(AS)π(AS,θ)θlnπ(AS,θ)qπ(S,A)]

    • 其中:

      • ρ\rhoρ:状态分布;
      • β\betaβ:行为策略;
      • π\piπ:目标策略;
      • π(A∣S,θ)β(A∣S)\frac{\pi(A|S,\theta)}{\beta(A|S)}β(AS)π(AS,θ)重要性采样权重
  3. 为什么要重要性采样比率?
    • 在 on-policy 的情形下,AAA 是由 π\piπ 采样的,所以没有问题。

    • 但是在 off-policy 中,AAA 是由 β\betaβ 采样的,这和 π\piπ 不一致。

    • 为了修正这种分布不匹配,就要引入修正因子:

      π(A∣S,θ)β(A∣S)\frac{\pi(A|S,\theta)}{\beta(A|S)}β(AS)π(AS,θ)

    • 这样,虽然我们是从 β\betaβ 的分布中采样,但通过加权,可以让期望和在 π\piπ 下采样的结果保持一致。

  4. 直观解释
    • 分布修正:通过 πβ\frac{\pi}{\beta}βπ,把 β\betaβ 下的采样分布“修正”为 π\piπ 下的分布;
    • 无偏性:保证估计的期望仍然是 π\piπ 下的真实梯度;
    • 可复用性:我们可以利用 β\betaβ 生成的旧经验来更新 π\piπ,而不是每次都要重新采样。
  5. 实际问题
    • 虽然引入了 πβ\frac{\pi}{\beta}βπ 修正项保证了无偏性,但也带来了方差过大的问题。
    • 因此,实际中很多 off-policy 算法(比如 DDPG、SAC)会:
      • 使用 截断的重要性权重(clipped importance sampling);
      • 或者用 critic 近似 qπ(s,a)q_\pi(s,a)qπ(s,a) 来减少方差。

The algorithm of off-policy actor-critic

Off-policy policy gradient

  • The off-policy policy gradient is also invariant to a baseline b(s)b(s)b(s).

  • In particular, we have

    ∇θJ(θ)=ES∼ρ,A∼β[π(A∣S,θ)β(A∣S)∇θln⁡π(A∣S,θ)(qπ(S,A)−b(S))]\nabla_\theta J(\theta) = \mathbb{E}{S \sim \rho, A \sim \beta} \left[ \frac{\pi(A|S,\theta)}{\beta(A|S)} \nabla\theta \ln \pi(A|S,\theta) (q_\pi(S,A) - b(S)) \right]θJ(θ)=ESρ,Aβ[β(AS)π(AS,θ)θlnπ(AS,θ)(qπ(S,A)b(S))]

  • To reduce the estimation variance, we can select the baseline as b(S)=vπ(Sb(S) = v_\pi(Sb(S)=vπ(S) and obtain

    ∇θJ(θ)=E[π(A∣S,θ)β(A∣S)∇θln⁡π(A∣S,θ)(qπ(S,A)−vπ(S))]\nabla_\theta J(\theta) = \mathbb{E} \left[ \frac{\pi(A|S,\theta)}{\beta(A|S)} \nabla_\theta \ln \pi(A|S,\theta) (q_\pi(S,A) - v_\pi(S)) \right]θJ(θ)=E[β(AS)π(AS,θ)θlnπ(AS,θ)(qπ(S,A)vπ(S))]

为什么需要 Off-policy?

在 on-policy 的情况下,Actor 和 Critic 的更新都依赖于 当前策略 π\piπ 产生的数据。但在实际应用中,这样有两个问题:

  1. 策略需要不断更新 → 采样效率低。
  2. 旧的数据(由旧策略产生)无法直接利用。

因此我们希望能在 一个行为策略 β\betaβ(behavior policy) 下收集经验,然后用这些经验去更新一个 目标策略 π\piπ(target policy)。这就需要 importance sampling 来进行修正。

Off-policy Policy Gradient with Baseline

在 off-policy 场景下,策略梯度公式变为:

∇θJ(θ)=ES∼ρ,A∼β[π(A∣S,θ)β(A∣S)∇θln⁡π(A∣S,θ)(qπ(S,A)−b(S))]\nabla_\theta J(\theta) = \mathbb{E}{S \sim \rho, A \sim \beta} \left[ \frac{\pi(A|S,\theta)}{\beta(A|S)} \nabla\theta \ln \pi(A|S,\theta) (q_\pi(S,A) - b(S)) \right]θJ(θ)=ESρ,Aβ[β(AS)π(AS,θ)θlnπ(AS,θ)(qπ(S,A)b(S))]

关键点:

  • π(A∣S,θ)β(A∣S)\frac{\pi(A|S,\theta)}{\beta(A|S)}β(AS)π(AS,θ) 称为 importance weight,用于校正行为策略与目标策略的分布差异。

  • baseline b(S)b(S)b(S) 用于降低方差。最常见选择是 b(S)=vπ(S)b(S) = v_\pi(S)b(S)=vπ(S),得到 advantage function

    qπ(S,A)−vπ(S)=δπ(S,A)q_\pi(S,A) - v_\pi(S) = \delta_\pi(S,A)qπ(S,A)vπ(S)=δπ(S,A)

Stochastic gradient-ascent algorithm

  • The corresponding stochastic gradient-ascent algorithm is

    θt+1=θt+αθπ(at∣st,θt)β(at∣st)∇θln⁡π(at∣st,θt)(qt(st,at)−vt(st))\theta_{t+1} = \theta_t + \alpha_\theta \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)} \nabla_\theta \ln \pi(a_t|s_t,\theta_t) (q_t(s_t,a_t) - v_t(s_t))θt+1=θt+αθβ(atst)π(atst,θt)θlnπ(atst,θt)(qt(st,at)vt(st))

  • Similar to the on-policy case,

    qt(st,at)−vt(st)≈rt+1+γvt(st+1)−vt(st)≐δt(st,at)q_t(s_t,a_t) - v_t(s_t) \approx r_{t+1} + \gamma v_t(s_{t+1}) - v_t(s_t) \doteq \delta_t(s_t,a_t)qt(st,at)vt(st)rt+1+γvt(st+1)vt(st)δt(st,at)

  • Then, the algorithm becomes

      $\theta_{t+1} = \theta_t + \alpha_\theta \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)}
    

    \nabla_\theta \ln \pi(a_t|s_t,\theta_t) \delta_t(s_t,a_t)$

  • and hence

    θt+1=θt+αθ(δt(st,at)β(at∣st))∇θπ(at∣st,θt)\theta_{t+1} = \theta_t + \alpha_\theta \left( \frac{\delta_t(s_t,a_t)}{\beta(a_t|s_t)} \right) \nabla_\theta \pi(a_t|s_t,\theta_t)θt+1=θt+αθ(β(atst)δt(st,at))θπ(atst,θt)

Off-policy actor-critic based on importance sampling

  • Initialization:
    • A given behavior policy β(a∣s)\beta(a|s)β(as).
    • A target policy π(a∣s,θ0)\pi(a|s,\theta_0)π(as,θ0) where θ0\theta_0θ0 is the initial parameter vector.
    • A value function v(s,w0)v(s,w_0)v(s,w0) where w0w_0w0 is the initial parameter vector.
  • Aim: Search for an optimal policy by maximizing J(θ)J(\theta)J(θ).
  • At time step t in each episode, do
    • Generate ata_tat following β(st)\beta(s_t)β(st) and then observe rt+1,st+1r_{t+1}, s_{t+1}rt+1,st+1.

    • TD error (advantage function):

      δt=rt+1+γv(st+1,wt)−v(st,wt)\delta_t = r_{t+1} + \gamma v(s_{t+1},w_t) - v(s_t,w_t)δt=rt+1+γv(st+1,wt)v(st,wt)

    • Critic (value update):

      wt+1=wt+αwπ(at∣st,θt)β(at∣st)δt∇wv(st,wt)w_{t+1} = w_t + \alpha_w \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)} \delta_t \nabla_w v(s_t,w_t)wt+1=wt+αwβ(atst)π(atst,θt)δtwv(st,wt)

    • Actor (policy update):

      θt+1=θt+αθπ(at∣st,θt)β(at∣st)δt∇θln⁡π(at∣st,θt)\theta_{t+1} = \theta_t + \alpha_\theta \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)} \delta_t \nabla_\theta \ln \pi(a_t|s_t,\theta_t)θt+1=θt+αθβ(atst)π(atst,θt)δtθlnπ(atst,θt)

Off-policy Actor-Critic 算法流程深度解析

  1. 初始化

    • 行为策略 β(a∣s)\beta(a|s)β(as)

      • 这是用来 收集数据 的策略。它可以是一个旧版本的策略,也可以是专门设计来探索的策略。它的优点是能产生大量样本,甚至存放在 经验回放池 中供以后使用。
      • 用来收集经验,提高样本利用率。
    • 目标策略 π(a∣s,θ)\pi(a|s,\theta)π(as,θ)

      这是我们真正想要优化的策略(Actor)。参数是 θ\thetaθ,它决定了我们的最终决策性能。

    • 价值函数 v(s,w)v(s,w)v(s,w)

      • Critic 的任务是近似状态价值或动作价值,用参数 www 表示。Critic 为 Actor 提供“动作好坏的评价信号”。
      • 真正优化的目标,保证学习方向正确。
  2. 采样阶段

    • 在时间步 ttt
      1. 用行为策略 β(st)\beta(s_t)β(st) 选择动作 ata_tat
      2. 环境返回奖励 rt+1r_{t+1}rt+1 和下一个状态 st+1s_{t+1}st+1
    • 注意:这里的动作不是从 π\piπ 采样,而是从 β\betaβ 采样。
    • 这就是 off-policy 的关键:数据来自别的策略。
  3. 计算 TD 误差(Advantage 近似)

    δt=rt+1+γv(st+1,wt)−v(st,wt)\delta_t = r_{t+1} + \gamma v(s_{t+1},w_t) - v(s_t,w_t)δt=rt+1+γv(st+1,wt)v(st,wt)

    • 直观理解:
      • 如果奖励 + 下一状态的价值 大于 当前状态价值 → 说明动作比预期更好,δt>0\delta_t > 0δt>0
      • 如果奖励 小于 预期 → 动作比想象中差,δt<0\delta_t < 0δt<0
  4. Critic 更新(值函数近似)

    wt+1=wt+αwπ(at∣st,θt)β(at∣st)δt∇wv(st,wt)w_{t+1} = w_t + \alpha_w \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)} \delta_t \nabla_w v(s_t,w_t)wt+1=wt+αwβ(atst)π(atst,θt)δtwv(st,wt)

    • Critic 学习目标是 让价值函数更好地逼近 TD 目标
    • 乘上 πβ\frac{\pi}{\beta}βπ 是因为数据不是从目标策略 π\piπ 采样的,而是从行为策略 β\betaβ 采样的,我们必须用 importance sampling 权重 进行修正,保证更新是 无偏的
      • 没有这个修正,Critic 会学到偏差很大的价值估计,从而误导 Actor。
  5. Actor 更新(策略改进)

    θt+1=θt+αθπ(at∣st,θt)β(at∣st)δt∇θln⁡π(at∣st,θt)\theta_{t+1} = \theta_t + \alpha_\theta \frac{\pi(a_t|s_t,\theta_t)}{\beta(a_t|s_t)} \delta_t \nabla_\theta \ln \pi(a_t|s_t,\theta_t)θt+1=θt+αθβ(atst)π(atst,θt)δtθlnπ(atst,θt)

    • 直观理解:
      • 如果 δt>0\delta_t > 0δt>0,说明这个动作比预期更好,Actor 就应该 增加该动作的概率
      • 如果 δt<0\delta_t < 0δt<0,说明动作不好,Actor 应该 降低该动作的概率
    • 同样,πβ\frac{\pi}{\beta}βπ 用来修正数据分布。
    • 最终,Actor 会逐渐朝着能带来更大长期回报的方向优化。
  6. 核心理解

    1. β\betaβ 负责采样,π\piπ 负责学习
      • 这使得我们可以反复使用旧数据(经验回放),大大提高采样效率。
    2. Importance Sampling 保证无偏
      • 修正因 β≠π\beta ≠ \piβ=π 带来的分布差异,否则 Actor 和 Critic 的更新方向会有偏差。
    3. TD 误差作为 Advantage
      • Critic 提供的 δt\delta_tδt 告诉 Actor:这个动作比平均水平好多少,从而指导策略改进。

Deterministic actor-critic (DPG)

Introduction

The ways to represent a policy:

  • Up to now, a general policy is denoted as

      $\pi(a|s,\theta) \in [0,1],$
    
    • which can be either stochastic or deterministic.
  • Now, the deterministic policy is specifically denoted as

    a=μ(s,θ)≐μ(s)a = \mu(s,\theta) \doteq \mu(s)a=μ(s,θ)μ(s)

    • μ\muμ is a mapping from S\mathcal{S}S to A\mathcal{A}A.
    • μ\muμ can be represented by, for example, a neural network with the input as sss, the output as aaa, and the parameter as θ\thetaθ.
    • We may write μ(s,θ)\mu(s,\theta)μ(s,θ) in short as μ(s)\mu(s)μ(s).

确定性策略的表示

  • 一般策略:π(a∣s,θ)\pi(a|s, \theta)π(as,θ),可以是分布也可以是函数。

  • 确定性策略:

    a=μ(s,θ)a = \mu(s, \theta)a=μ(s,θ)

    它是一个 映射 S→AS \to ASA

  • 实现方式:用一个神经网络,输入状态 sss,输出一个唯一动作 aaa

这意味着 不再采样,而是直接计算

The theorem of deterministic policy gradient

Introduction

  • The policy gradient theorems introduced before are merely valid for stochastic policies.
  • If the policy must be deterministic, we must derive a new policy gradient theorem.
  • The ideas and procedures are similar.

为什么要从随机策略转向确定性策略?

  • 在之前的 stochastic policy gradient (SPG) 中,我们有:

    π(a∣s,θ)>0,∀(s,a)\pi(a|s, \theta) > 0, \quad \forall (s,a)π(as,θ)>0,(s,a)

    • 意味着无论什么状态,每个动作都有概率被选到。
  • 好处:理论上保证覆盖整个动作空间。

  • 问题:

    • 连续动作空间时,分布很难采样完整,学习效率低;
    • 梯度估计有 高方差,更新不稳定。
  • 于是我们考虑:

    • 能不能直接学一个函数 a=μ(s,θ)a = \mu(s, \theta)a=μ(s,θ),让策略 deterministically 输出动作?

Definition

  • Consider the metric of average state value in the discounted case:

    J(θ)=E[vμ(s)]=∑s∈Sd0(s)vμ(s)J(\theta) = \mathbb{E}[v_\mu(s)] = \sum_{s \in \mathcal{S}} d_0(s) v_\mu(s)J(θ)=E[vμ(s)]=sSd0(s)vμ(s)

    • where d0(s)d_0(s)d0(s) is a probability distribution satisfying ∑s∈Sd0(s)=1\sum_{s \in \mathcal{S}} d_0(s) = 1sSd0(s)=1.
    • d0d_0d0 is selected to be independent of μ\muμ. The gradient in this case is easier to calculate.
  • There are two special yet important cases of selecting d0d_0d0.

    • The first special case is that d0(s0)=1d_0(s_0) = 1d0(s0)=1 and d0(s≠s0)=0d_0(s \neq s_0) = 0d0(s=s0)=0, where s0s_0s0 is a specific starting state of interest.
    • The second special case is that d0d_0d0 is the stationary distribution of a behavior policy that is different from the μ\muμ.

DPG 的目标函数

  • 我们依旧定义目标函数(期望回报):

    J(θ)=E[vμ(s)]=∑s∈Sd0(s)vμ(s)J(\theta) = \mathbb{E}[v_\mu(s)] = \sum_{s \in \mathcal{S}} d_0(s) v_\mu(s)J(θ)=E[vμ(s)]=sSd0(s)vμ(s)

    • 其中:
      • vμ(s)v_\mu(s)vμ(s):在策略 μ\muμ 下,状态 sss 的价值。
      • d0(s)d_0(s)d0(s):状态分布,可以有不同的选择:
        • 如果 d0(s0)=1d_0(s_0)=1d0(s0)=1,表示从某个起点状态开始。
        • 如果 d0d_0d0 是行为策略的平稳分布,说明我们是 off-policy 学习。

Theorem (Deterministic policy gradient theorem in the discounted case)

  • In the discounted case where γ∈(0,1)\gamma \in (0,1)γ(0,1), the gradient of J(θ)J(\theta)J(θ) is

    ∇θJ(θ)=∑s∈Sρμ(s)∇θμ(s)(∇aqμ(s,a))∣a=μ(s)\nabla_\theta J(\theta) = \sum_{s \in \mathcal{S}} \rho_\mu(s) \nabla_\theta \mu(s) \big(\nabla_a q_\mu(s,a)\big)\big|_{a=\mu(s)}θJ(θ)=sSρμ(s)θμ(s)(aqμ(s,a))a=μ(s)

    =ES∼ρμ[∇θμ(S)(∇aqμ(S,a))∣a=μ(S)]= \mathbb{E}_{S \sim \rho\mu} \Big[ \nabla_\theta \mu(S) \big(\nabla_a q_\mu(S,a)\big)\big|_{a=\mu(S)} \Big]=ESρμ[θμ(S)(aqμ(S,a))a=μ(S)]

  • Here, ρμ\rho_\muρμ is a state distribution.

  • One important difference from the stochastic case:

    • The gradient does not involve the distribution of the action AAA (why?).
    • As a result, the deterministic policy gradient method is off-policy.

确定性策略梯度定理

  • 定理表明:

    ∇θJ(θ)=ES∼ρμ[∇θμ(S)∇aqμ(S,a)∣a=μ(S)]\nabla_\theta J(\theta) = \mathbb{E}_{S \sim \rho\mu} \Big[ \nabla_\theta \mu(S) \, \nabla_a q_\mu(S,a) \big|_{a=\mu(S)} \Big]θJ(θ)=ESρμ[θμ(S)aqμ(S,a)a=μ(S)]

    • 关键点:
      1. 梯度更新依赖于:
        • 策略梯度 ∇θμ(S)\nabla_\theta \mu(S)θμ(S):动作 aaa 对参数 θ\thetaθ 的敏感性(“动作会随参数怎么变”)。
        • 动作价值梯度 ∇aqμ(S,a)\nabla_a q_\mu(S,a)aqμ(S,a):动作 aaa 对未来价值的敏感性(“这个动作对价值函数的边际贡献”)。
        • 组合:我们要让动作朝着“价值上升最快”的方向调整。
      2. 区别于随机策略的情况:这里没有 π(a∣s)\pi(a|s)π(as) 的分布项!
        • 在 stochastic PG 中,更新公式中会有 ∇θln⁡π(a∣s,θ)\nabla_\theta \ln \pi(a|s,\theta)θlnπ(as,θ),因为需要考虑采样概率。
        • 在 DPG 中,动作是唯一确定的,不需要概率分布,所以消掉了这一项。

为什么和随机策略不同?

  • stochastic policy gradient (REINFORCE) 里:

    ∇θJ(θ)=E[∇θln⁡π(a∣s,θ)qπ(s,a)]\nabla_\theta J(\theta) = \mathbb{E}[\nabla_\theta \ln \pi(a|s,\theta) \, q_\pi(s,a)]θJ(θ)=E[θlnπ(as,θ)qπ(s,a)]

    • 解释:
      • 因为动作是“从分布中采样”,所以必须用 ln⁡π(a∣s,θ)\ln \pi(a|s,\theta)lnπ(as,θ) 的导数来捕捉“采样概率随参数变化的敏感性”。
  • 而在 deterministic case

    • 动作是确定的,不需要概率分布。
    • 于是 ln⁡π\ln \pilnπ 项消失,直接用 ∇θμ(s)\nabla_\theta \mu(s)θμ(s)

为什么 DPG 是 Off-policy?

  • 在随机策略下,我们必须从当前策略 π\piπ 中采样动作(on-policy)。

  • 但在 DPG 中,公式只依赖于 μ(s)\mu(s)μ(s)qμ(s,a)q_\mu(s,a)qμ(s,a),与采样分布 β\betaβ 无关。

    → 我们可以用任意行为策略(例如 ϵ\epsilonϵ-greedy 探索策略)来收集数据,再用这些数据更新 μ\muμ

The algorithm of deterministic actor-critic

Gradient-ascent algorithm for deterministic policy gradient

  • Based on the policy gradient, the gradient-ascent algorithm for maximizing J(θ)J(\theta)J(θ) is:

    θt+1=θt+αθES∼ρμ[∇θμ(S)(∇aqμ(S,a))∣a=μ(S)]\theta_{t+1} = \theta_t + \alpha_\theta \mathbb{E}{S \sim \rho\mu} \left[ \nabla_\theta \mu(S) (\nabla_a q_\mu(S, a)) \big|_{a=\mu(S)} \right]θt+1=θt+αθESρμ[θμ(S)(aqμ(S,a))a=μ(S)]

  • The corresponding stochastic gradient-ascent algorithm is

    θt+1=θt+αθ∇θμ(st)(∇aqμ(st,a))∣a=μ(st)\theta_{t+1} = \theta_t + \alpha_\theta \nabla_\theta \mu(s_t) (\nabla_a q_\mu(s_t, a)) \big|_{a=\mu(s_t)}θt+1=θt+αθθμ(st)(aqμ(st,a))a=μ(st)

Gradient-ascent algorithm

  • Deterministic policy gradient

    θt+1=θt+αθES∼ρμ[∇θμ(S)(∇aqμ(S,a))∣a=μ(S)]\theta_{t+1} = \theta_t + \alpha_\theta \mathbb{E}{S \sim \rho\mu} \left[ \nabla_\theta \mu(S) (\nabla_a q_\mu(S, a)) \big|_{a=\mu(S)} \right]θt+1=θt+αθESρμ[θμ(S)(aqμ(S,a))a=μ(S)]

    • 含义:
      • 在确定性策略下,动作 aaa 不再是一个概率分布采样结果,而是直接由函数 μ(s,θ)\mu(s, \theta)μ(s,θ) 给出。
      • 策略参数 θ\thetaθ 的更新方向由 链式法则 得到:
        1. ∇θμ(S)\nabla_\theta \mu(S)θμ(S):状态对策略参数的敏感性(即参数变化对输出动作的影响);
        2. ∇aqμ(S,a)\nabla_a q_\mu(S, a)aqμ(S,a):动作对价值函数的敏感性(即动作改变对未来回报的影响)。
      • 两者结合,意味着参数更新方向是动作变化对回报的敏感性 × 参数变化对动作的敏感性
  • Stochastic gradient-ascent algorithm

    θt+1=θt+αθ∇θμ(st)(∇aqμ(st,a))∣a=μ(st)\theta_{t+1} = \theta_t + \alpha_\theta \nabla_\theta \mu(s_t)(\nabla_a q_\mu(s_t, a)) \big|_{a=\mu(s_t)}θt+1=θt+αθθμ(st)(aqμ(st,a))a=μ(st)

    • 这里用单个采样状态 sts_tst 近似期望。
    • 相当于 mini-batch SGD 的思想,用样本来代替整体分布的期望。

Deterministic actor-critic algorithm

  • Initialization: A given behavior policy β(a∣s)\beta(a|s)β(as). A deterministic target policy μ(s,θ0)\mu(s, \theta_0)μ(s,θ0) where θ0\theta_0θ0 is the initial parameter vector. A value function v(s,w0)v(s, w_0)v(s,w0) where w0w_0w0 is the initial parameter vector.
  • Aim: Search for an optimal policy by maximizing J(θ)J(\theta)J(θ).
  • At time step t in each episode, do
    • Generate ata_tat following β\betaβ and then observe rt+1,st+1r_{t+1}, s_{t+1}rt+1,st+1.

    • TD error:

      δt=rt+1+γq(st+1,μ(st+1,θt),wt)−q(st,at,wt)\delta_t = r_{t+1} + \gamma q(s_{t+1}, \mu(s_{t+1}, \theta_t), w_t) - q(s_t, a_t, w_t)δt=rt+1+γq(st+1,μ(st+1,θt),wt)q(st,at,wt)

    • Critic (value update):

      wt+1=wt+αwδt∇wq(st,at,wt)w_{t+1} = w_t + \alpha_w \delta_t \nabla_w q(s_t, a_t, w_t)wt+1=wt+αwδtwq(st,at,wt)

    • Actor (policy update):

      θt+1=θt+αθ∇θμ(st,θt)(∇aq(st,a,wt+1))∣a=μ(st)\theta_{t+1} = \theta_t + \alpha_\theta \nabla_\theta \mu(s_t, \theta_t)(\nabla_a q(s_t, a, w_{t+1})) \big|_{a=\mu(s_t)}θt+1=θt+αθθμ(st,θt)(aq(st,a,wt+1))a=μ(st)

Deterministic Actor-Critic Algorithm (DAC)

  • 算法流程:
    1. 初始化:

      • 行为策略 β(a∣s)\beta(a|s)β(as):用于采样数据(可以是 μ+noise\mu + \text{noise}μ+noise)。
      • 目标策略 μ(s,θ)\mu(s, \theta)μ(s,θ):确定性输出动作。
      • 价值函数 q(s,a,w)q(s,a,w)q(s,a,w):用参数 www 近似。
    2. 执行过程:

      • 在状态 sts_tst 下,根据行为策略 β\betaβ 生成动作 ata_tat
      • 执行 ata_tat,观察奖励 rt+1r_{t+1}rt+1 和下一个状态 st+1s_{t+1}st+1
    3. TD 误差:

      δt=rt+1+γq(st+1,μ(st+1,θt),wt)−q(st,at,wt)\delta_t = r_{t+1} + \gamma q(s_{t+1}, \mu(s_{t+1}, \theta_t), w_t) - q(s_t, a_t, w_t)δt=rt+1+γq(st+1,μ(st+1,θt),wt)q(st,at,wt)

      • 衡量当前 qqq 估计与真实回报之间的差距。
      • 如果 δt>0\delta_t > 0δt>0,说明实际回报比估计高,动作和策略需要被强化。
    4. Critic 更新:

      wt+1=wt+αwδt∇wq(st,at,wt)w_{t+1} = w_t + \alpha_w \delta_t \nabla_w q(s_t, a_t, w_t)wt+1=wt+αwδtwq(st,at,wt)

      • 类似 TD 学习,逼近真实的 qqq 函数。
    5. Actor 更新:

      θt+1=θt+αθ∇θμ(st,θt)(∇aq(st,a,wt+1))∣a=μ(st)\theta_{t+1} = \theta_t + \alpha_\theta \nabla_\theta \mu(s_t, \theta_t)(\nabla_a q(s_t, a, w_{t+1}))|_{a=\mu(s_t)}θt+1=θt+αθθμ(st,θt)(aq(st,a,wt+1))a=μ(st)

      • 利用 critic 提供的梯度信号,更新确定性策略。
      • 注意这里直接用梯度 ∇aq\nabla_a qaq,而不是通过 log-likelihood trick。

Remarks

  • This is an off-policy implementation where the behavior policy β\betaβ may be different from μ\muμ.
  • β\betaβ can also be replaced by μ+noise\mu + \text{noise}μ+noise.
  • How to select the function to represent q(s,a,w)q(s,a,w)q(s,a,w)?
    • Linear function:

      q(s,a,w)=ϕT(s,a)wq(s,a,w) = \phi^T(s,a) wq(s,a,w)=ϕT(s,a)w where ϕ(s,a)\phi(s,a)ϕ(s,a) is the feature vector. Details can be found in the DPG paper.

    • Neural networks: deep deterministic policy gradient (DDPG) method.

Remarks 的意义

  • Off-policy:
    • 行为策略 β\betaβ 可以和目标策略 μ\muμ 不同。
    • 好处:数据采样更灵活,可以复用过去的经验(比如 replay buffer)。
  • 行为策略 = 目标策略 + 噪声:
    • 常见做法:在 μ\muμ 的输出上加噪声(如 Ornstein-Uhlenbeck noise),增加探索性。
    • DDPG 就是这样实现的。
  • Q 函数表示方式:
    1. 线性函数近似:

      q(s,a,w)=ϕT(s,a)wq(s,a,w) = \phi^T(s,a) wq(s,a,w)=ϕT(s,a)w

      • 简单高效,但表达能力有限。
    2. 神经网络:

      • 对连续动作空间更适用(即 DDPG 方法)。
      • 神经网络负责拟合复杂的 qqq 函数。

与随机策略梯度的对比

  • 随机策略梯度:

    更新依赖于 ∇θlog⁡πθ(a∣s)qπ(s,a)\nabla_\theta \log \pi_\theta(a|s) q_\pi(s,a)θlogπθ(as)qπ(s,a)

    • 优点:可以探索更多动作。
    • 缺点:连续动作空间中采样效率低。
  • 确定性策略梯度:

    更新依赖于 ∇θμ(s)∇aq(s,a)\nabla_\theta \mu(s) \nabla_a q(s,a)θμ(s)aq(s,a)

    • 优点:直接学最优动作,避免动作采样;更适合高维连续控制问题。
    • 缺点:探索能力依赖额外噪声机制。

总结

Actor-Critic 方法通过 Critic 提供的价值估计来指导 Actor 的策略更新,而在确定性策略梯度(DPG/DDPG)中,Actor 直接输出动作并利用 ∇θμ(s)∇aq(s,a)\nabla_\theta \mu(s)\nabla_a q(s,a)θμ(s)aq(s,a) 更新,避免了概率采样,高效适用于连续动作空间,但探索需依赖额外噪声。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/99131.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/99131.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/99131.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源大模型天花板?DeepSeek-V3 6710亿参数MoE架构深度拆解

文章目录认知解构&#xff1a;DeepSeek的定位与核心价值模型概述与发展历程创立初期与技术奠基&#xff08;2023年7月-2024年11月&#xff09;里程碑一&#xff1a;MoE架构规模化突破&#xff08;2024年12月&#xff09;里程碑二&#xff1a;推理成本革命性优化&#xff08;202…

10 训练中的一些问题

&#x1f31f; 大背景&#xff1a;训练神经网络 下山寻宝 训练神经网络就像你蒙着眼在一座大山里&#xff0c;想找最低点&#xff08;最小损失&#xff09;。你只能靠脚下的坡度&#xff08;梯度&#xff09;来决定往哪儿走。 你的位置 模型参数&#xff08;权重 www&#xf…

synchronized锁升级的过程(从无锁到偏向锁,再到轻量级锁,最后到重量级锁的一个过程)

锁升级是 Java 中 synchronized 锁 的核心优化机制&#xff08;基于 JVM 的 对象头 Mark Word 实现&#xff09;&#xff0c;指锁的状态从 无锁 → 偏向锁 → 轻量级锁 → 重量级锁 逐步升级的过程。其目的是通过 “按需升级”&#xff0c;在不同并发场景下选择最优的锁实现&am…

HOT100--Day25--84. 柱状图中最大的矩形,215. 数组中的第K个最大元素,347. 前 K 个高频元素

HOT100–Day25–84. 柱状图中最大的矩形&#xff0c;215. 数组中的第K个最大元素&#xff0c;347. 前 K 个高频元素 每日刷题系列。今天的题目是《力扣HOT100》题单。 题目类型&#xff1a;栈&#xff0c;堆。 84. 柱状图中最大的矩形 思路&#xff1a; class Solution {publ…

基于 Apache Doris 的用户画像数据模型设计方案

一、 需求分析与设计目标数据源&#xff1a;用户基本信息&#xff1a;用户ID、性别、出生日期、注册时间、常驻地域&#xff08;省、市、区&#xff09;、职业等。用户体检报告&#xff1a;每次体检的报告ID、体检时间、各项指标&#xff08;如血压、血糖、血脂、BMI等&#xf…

Python的深度学习

深入理解Python高级特性掌握Python的高级特性是进阶的关键&#xff0c;包括装饰器、生成器、上下文管理器、元类等。这些特性能够提升代码的灵活性和效率。例如&#xff0c;装饰器可以用于实现AOP&#xff08;面向切面编程&#xff09;&#xff0c;生成器可以处理大数据流而无需…

数据库范式(Normalization)

一个设计混乱的数据库就像一个杂乱的房间&#xff0c;用起来非常不方便&#xff1a;东西到处乱放&#xff08;数据冗余&#xff09;&#xff0c;找件东西要翻遍所有角落&#xff08;查询困难&#xff09;&#xff0c;扔掉一把旧椅子时&#xff0c;可能会把搭在上面的唯一一件外…

数据结构---循环队列

基于循环数组实现的循环队列解决了顺序队列中的假溢出导致的空间浪费问题操作&#xff1a;&#xff08;1&#xff09;初始化//循环队列 typedef struct {int *data;//指针模拟声明数组int head,tail;//队头&#xff0c;队尾 }Queue; //初始化 Queue *InitQueue() {Queue *q (Q…

深入理解线程模型

线程作为操作系统调度的基本执行单元&#xff0c;是实现高吞吐、低延迟系统的基础。一、进程与线程的体系结构对比核心概念&#xff1a;进程&#xff08;Process&#xff09;&#xff1a;操作系统资源分配的基本单位&#xff0c;拥有独立的虚拟地址空间、文件描述符表、环境变量…

TTC定时器中断——MPSOC实战3

开启TTC定时器&#xff0c;不同于7000系列的私有定时器此处设置LPD_LSBUS频率TTC频率取决于LPD_LSBUS可前往指定位置查看参数不使能填写对应宏可前往指定位置查看参数main.c#include <stdio.h> #include "xparameters.h" #include "xgpiops.h" #incl…

人工智能训练师三级备考笔记

一、实操1&#xff09;通用语法&#xff08;常见于实操题第一块代码块&#xff09;1.读取文件数据或加载数据集等描述时一般为以下结构&#xff1a;Datapd.read_文件格式(文件名) 注意&#xff1a;文件名需要用‘ ’框起来&#xff0c;必须要有引号文件格式有以下内容csv、txt…

Cherry Studio递归工具调用机制深度解析

在现代AI应用开发中,工具调用(Tool Calling)已成为大语言模型与外部系统交互的核心机制。Cherry Studio作为一款先进的AI对话客户端,实现了一套完整的递归工具调用系统,能够让AI助手在执行复杂任务时自动调用多个工具,并根据执行结果智能决策下一步操作。本文将深入解析这…

[哈希表]966. 元音拼写检查器

966. 元音拼写检查器 class Solution:def spellchecker(self, wordlist: List[str], queries: List[str]) -> List[str]:origin set(wordlist) # 存储原始单词用于完全匹配lower_to_origin {} # 存储小写形式到原始单词的映射vowel_to_origin {} # 存储元音模糊形…

正则表达式与文本三剑客(grep、sed、awk)基础与实践

正则表达式基础与实践一、正则表达式概述1. 定义正则表达式&#xff08;Regular Expression&#xff0c;简称 RE&#xff09;是用于描述字符排列和匹配模式的语法规则&#xff0c;核心作用是对字符串进行分割、匹配、查找、替换操作。它本质是 “模式模板”&#xff0c;Linux 工…

eclipse中web项目编译后的lib里面jar为空问题处理

1. 检查项目构建配置验证项目性质右键单击项目 → Properties确认项目已正确配置&#xff1a;​Project Facets​&#xff1a;确保已勾选"Dynamic Web Module"​Targeted Runtimes​&#xff1a;确保已选择服务器运行时&#xff08;如Tomcat&#xff09;检查部署程序…

C语言中的递归问题——汉诺塔问题

汉诺塔&#xff08;Tower of Hanoi)&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。传说大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在…

ArkAnalyzer源码初步分析I——分析ts项目流程

1.前言&#xff1a; 鸿蒙程序分析框架ArkAnalyzer&#xff08;方舟分析器&#xff09; 源码地址 入门文档 2.阅读入门文档后&#xff1a; 本人具有一定的Java开发经验。虽然我对 TypeScript&#xff08;TS&#xff09;和 ArkTS 还不熟&#xff0c;但很多概念对我这个 Java 开…

c#基础二(类和对象,构造器调用顺序、访问级别、重写和多态、抽象类和接口)

一、类1.0对象初始化器class Student {public String name;public int age { get; set; } } internal class Program {static void Main(string[] args){ //写法一Student stunew Student();stu.name"Tom";stu.age20;//写法二Student stu2 new Student { name &qu…

Qt之快捷键、事件处理、自定义按键——完成记事本项目

快捷键我们电脑中的记事本中还支持快捷键&#xff0c;如“CTRLO”打开文件、“CTRLS”保存文件在Qt中使用QShortcut这个类创建快捷键在.cpp文件的构造函数中创建QShortcut对象&#xff0c;绑定打开文件和保存文件的槽函数放大缩小字体还是在.cpp的构造函数中编写代码Widget::Wi…

Open cascade中如何使用BRepAlgoAPI_Splitter分割一个Face

理论介绍 在OpenCASCADE几何建模内核中&#xff0c;BRepAlgoAPI_Splitter是一个强大的工具&#xff0c;用于将一个形状&#xff08;Shape&#xff09;用另一个形状&#xff08;Tool&#xff09;进行分割。这种操作在CAD建模中非常常见&#xff0c;比如用平面切割实体、用曲线分…