First Step to Reinforcement Learning

1. 强化学习的递归本质:从时序差分到策略梯度的范式全景

1.1. 核心视角:自举(Bootstrapping)作为分类标准

强化学习算法的根本差异可以用一个等式是否成立来划分:

Current Estimate=?Immediate+γ×Next Estimate\text{Current Estimate} \stackrel{?}{=} \text{Immediate} + \gamma \times \text{Next Estimate}

  • 能自举(Bootstrapping):可以用自己的估计值代替真实未来(如 DQN、Actor-Critic 的 Critic)
  • 不能自举(Non-bootstrapping):必须等待真实结果(如 REINFORCE)

这一区分决定了算法是**“每步更新"还是"必须等游戏结束”**。

1.2. Value-Based 路线:完全递归在价值上

1.2.1. DQN:直接自举 Q(s,a)

递归对象:动作价值函数 Q(s,a)Q(s,a)

核心等式

Q(s,a)=r+γmaxaQ(s,a)Q(s,a) = r + \gamma \max_{a'} Q(s', a')

关键机制

  • 自举:用 maxaQ(s,a)\max_{a'} Q(s', a')(自己的估计)代替真实未来回报
  • 判别式决策:先算清所有动作的账,用 max\max 选出最优(贪婪)

为何能每步更新:不需要知道游戏最终得分,只需要 rr 和对下一状态的猜测 Q(s)Q(s')

1.2.2. Dueling DQN:价值的正交分解

改进:将 QQ 拆分为状态基线动作差分,保持递归结构不变。

分解

Q(s,a)=V(s)状态基价+(A(s,a)1AaA(s,a))零均值优势Q(s,a) = \underbrace{V(s)}_{\text{状态基价}} + \underbrace{\left(A(s,a) - \frac{1}{|\mathcal{A}|}\sum_{a'}A(s,a')\right)}_{\text{零均值优势}}

递归公式(形式不变)

V(s)+A(s,a)Q(s,a)=r+γmaxa[V(s)+A(s,a)]\underbrace{V(s) + A(s,a)}_{Q(s,a)} = r + \gamma \max_{a'} \left[ V(s') + A(s',a') \right]

关键优势

  • 显式差分V(s)V(s) 跨动作学习(样本效率翻倍),A(s,a)A(s,a) 专注相对优劣
  • 零均值约束:强制 aA(s,a)=0\sum_a A(s,a) = 0,保证 V(s)=Ea[Q(s,a)]V(s) = \mathbb{E}_a[Q(s,a)]

1.3. Policy-Based 路线:非自举的蒙特卡洛方法

1.3.1. REINFORCE:无法自举的根源

核心:直接学习策略 πθ(as)\pi_\theta(a|s)不学习价值函数,因此无法自举

策略梯度定理

θJ=Eπθ[θlogπθ(atst)Gt真实累积回报]\nabla_\theta J = \mathbb{E}_{\pi_\theta} \left[ \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot \underbrace{G_t}_{\text{真实累积回报}} \right]

其中 Gt=rt+γrt+1+γ2rt+2+G_t = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \dots从时刻 t 到游戏结束的真实总回报

为何必须等游戏结束

  • GtG_t 包含未来的所有奖励 rt+1,rt+2,r_{t+1}, r_{t+2}, \dots
  • 在时刻 tt,这些尚未发生,无法像 DQN 那样用 Q(s)Q(s') 猜测
  • 无自举:等式右边没有 J\nabla Jπ\pi 的估计值,只有真实观测 GtG_t

方差灾难GtG_t 的随机性极大(同一动作,这次可能 G=100G=100,下次 G=10G=-10),导致梯度噪声巨大,训练不稳定。

1.3.2. REINFORCE with Baseline:减方差,但仍无自举

改进:引入 Baseline bb(如全局平均回报),将更新权重改为 (Gtb)(G_t - b)

公式

θJ=E[θlogπθ(as)(Gtb)]\nabla_\theta J = \mathbb{E} \left[ \nabla_\theta \log \pi_\theta(a|s) \cdot (G_t - b) \right]

效果

  • 降低方差GtbG_t - b 的波动范围小于 GtG_t
  • 仍无自举:仍然需要等待真实的 GtG_t,只是权重调整了
  • 仍不能每步更新:必须等一局结束才能算 GtG_t

1.4. Actor-Critic:桥接自举与策略梯度

1.4.1. 核心创新:用 Critic 实现自举

突破:引入 Critic(价值网络 Vϕ(s)V_\phi(s),用单步估计 r+γV(s)r + \gamma V(s') 代替真实总回报 GtG_t

Advantage 的估计(TD 误差)

A(s,a)(r+γV(s))单步目标(自举)V(s)Baseline(Critic 预测)=δTDA(s,a) \approx \underbrace{(r + \gamma V(s'))}_{\text{单步目标(自举)}} - \underbrace{V(s)}_{\text{Baseline(Critic 预测)}} = \delta_{\text{TD}}

关键对比

  • REINFORCE:权重是 GtG_t(蒙特卡洛,无自举,必须等结束)
  • Actor-Critic:权重是 δTD\delta_{\text{TD}}(时序差分,有自举,每步可算

1.4.2. 策略梯度的自举化

Actor 更新公式

θJ=Eπ[θlogπθ(as)(r+γV(s)V(s))Advantage(自举得到)]\nabla_\theta J = \mathbb{E}_{\pi} \left[ \nabla_\theta \log \pi_\theta(a|s) \cdot \underbrace{(r + \gamma V(s') - V(s))}_{\text{Advantage(自举得到)}} \right]

递归结构

  • Critic 的 V(s)V(s) 满足自举:V(s)r+γV(s)V(s) \approx r + \gamma V(s')(与 DQN 类似)
  • Actor 不再直接自举,但使用 Critic 提供的自举优势信号进行更新

为何能每步更新

  • 不需要等待 GtG_t,只需当前步的 rr 和 Critic 对下一状态的估计 V(s)V(s')
  • 从"等游戏结束"变为"走一步,更新一步"

1.4.3. 架构与流程

网络结构

  • Actor:输入 ss,输出 π(as)\pi(a|s)(概率分布)
  • Critic:输入 ss,输出 V(s)V(s)(标量价值)

单步训练流程

  1. Actor 采样aπ(s)a \sim \pi(\cdot|s)(生成动作,非 max\max 选择)
  2. 执行观察:获得 rrss'
  3. Critic 评估:计算 V(s)V(s)V(s)V(s')
  4. 计算 Advantageδ=r+γV(s)V(s)\delta = r + \gamma V(s') - V(s)
  5. 更新 Critic:最小化 (V(s)(r+γV(s)))2(V(s) - (r + \gamma V(s')))^2(让 VV 逼近自举目标)
  6. 更新 Actor:梯度上升 logπ(as)δ\nabla \log \pi(a|s) \cdot \deltaδ>0\delta>0 则增概率)

1.5. 三大范式对比:递归、差分与决策

维度 Dueling DQN (Value-Based) REINFORCE (Policy-Based) Actor-Critic (混合)
核心对象 Q(s,a)Q(s,a)(状态-动作价值) π(as)\pi(a\|s)(动作概率) V(s)V(s) + π(as)\pi(a\|s)
递归公式 Q=r+γmaxQQ = r + \gamma \max Q' GtG_t 真实回报) V=r+γVV = r + \gamma V'(仅 Critic)
自举能力 完全自举 无自举 半自举(Critic 自举,Actor 利用)
更新时机 每步(用 QQ' 猜测) 必须结束(等 GtG_t 每步(用 VV' 猜测)
Baseline/差分 显式 A(s,a)=QVA(s,a) = Q - V(零均值) 粗糙全局平均 GtGˉG_t - \bar{G} 精准状态相关 r+γVVr + \gamma V' - V
动作选择 判别式max\max,算清所有账) 采样式(按概率随机) 采样式(按概率随机)
关键操作 max\max(最优选择) 无(纯采样) E\mathbb{E}(策略期望)
是否知其他动作价值 是(必须输出所有 AA 否(黑箱) 否(黑箱,只关心实际执行)

1.6. 设计哲学总结

1.6.1. 关于"递归"的三层境界

  1. DQN/Dueling完全自举在价值估计上(QQ 递归依赖 maxQ\max Q'),像"规划"——先算清未来,再行动
  2. REINFORCE无自举,像"历史评价"——做完一件事,等最终结果出来,再评判
  3. Actor-Critic半自举,像"实时反馈"——每走一步,Critic 立即说"比预期好/差",Actor 立即调整

1.6.2. 关于"差分"的演进

  • Dueling显式差分VVAA 分离,Q=V+AQ = V + A
  • REINFORCE粗糙差分GtGˉG_t - \bar{G},全局平均)
  • Actor-Critic隐式精准差分A=r+γVVA = r + \gamma V' - V,状态相关 Baseline)

1.6.3. 关于"动作选择"的范式

  • 判别式(Dueling):先评估所有选项(输出所有 QQ),再挑最大max\max
  • 生成式(Actor-Critic):直接生成概率分布(π\pi),采样即得动作,无需比较

1.6.4. 一句话记忆

Dueling(中央计划):当前动作价值 = 即时回报 + 选最好的下一价值(max\max,完全递归)
REINFORCE(历史评定):策略梯度 = 动作置信度 × 真实总回报GtG_t,无递归,必须等待)
Actor-Critic(市场调节):策略梯度 = 动作置信度 × 实时差分反馈r+γVVr + \gamma V' - V,半递归,即走即评)

结语
强化学习的演进史,就是**"如何更高效地估计未来"的历史。从 REINFORCE 的"等结局"(蒙特卡洛),到 DQN 的"猜未来"(时序差分自举),再到 Actor-Critic 的"边做边评"(策略梯度 + 自举基线),核心矛盾始终是偏差(Bias)与方差(Variance)的权衡**,以及评估(Evaluation)与决策(Decision)的解耦。理解自举是否可行、如何可行,就掌握了现代深度强化学习的钥匙。

2. 批量强化学习:从 Fitted Q-Iteration 到 Conservative Q-Learning

2.1. 范式转换:从在线探索到离线学习

前文讨论的 SARSA 与 Q-Learning 都属于在线强化学习(Online RL):智能体与环境实时交互,边收集数据边更新策略,形成"探索-学习"的闭环。然而,在许多现实场景中,持续交互是不可能的或代价高昂的——我们无法让医疗 AI 在真实患者身上试错 10 万次,也无法让自动驾驶系统在公共道路上用随机策略探索。

批量强化学习(Batch RL) 应运而生:先一次性收集固定数据集 D={(si,ai,ri,si)}i=1N\mathcal{D} = \{(s_i, a_i, r_i, s'_i)\}_{i=1}^N,随后完全脱离环境,仅从这个"冻结"的数据集中学习最优策略。Fitted Q-Iteration (FQI) 正是这一范式的代表性算法。

2.2. Fitted Q-Iteration:批量拟合贝尔曼方程

2.2.1. 算法本质

FQI 解决了这样一个问题:给定一批固定数据,如何逼近贝尔曼最优方程?

与 Q-Learning 的增量更新不同,FQI 采用监督学习回归的方式迭代求解:

1
2
3
4
5
6
7
8
9
10
11
12
# 阶段 1:数据收集(任意策略,一旦完成即固定)
D = collect_data(policy=mixture_of_random_and_expert, N=100000)

# 阶段 2:拟合 Q 迭代(不再与环境交互)
Q = initial_function_approximator() # 神经网络/随机森林/线性模型

for k in range(K): # 迭代直到收敛
# 构造监督学习目标(贝尔曼目标)
targets = [r + gamma * max(Q(s', a')) for (s, a, r, s') in D]

# 纯监督学习:拟合 (s, a) → target
Q = regression(D.states, D.actions, targets, loss='MSE')

核心特征

  • 批量(Batch):数据集 D\mathcal{D} 固定不变,训练过程中不再采集新数据
  • 函数拟合(Fitted):必须使用函数逼近(神经网络、决策树等),无法查表
  • 迭代(Iteration):反复构造目标、拟合函数,直到 Q 值收敛(类似值迭代的采样版本)

2.2.2. 与在线算法的本质差异

维度 Q-Learning(在线) Fitted Q-Iteration(离线)
数据流 持续流动,新经验不断覆盖旧经验 固定冻结,反复采样同一批数据
策略演化 自适应:策略随学习改进,新数据质量提升 静态:数据由历史策略产生,无法针对盲区补充
更新机制 增量式:QQ+αTD误差Q \leftarrow Q + \alpha \cdot \text{TD误差} 批量式:完整拟合贝尔曼目标(监督回归)
探索能力 强:可通过 ϵ\epsilon 衰减或好奇心机制持续探索未知 弱:受限于初始数据分布,无法探索数据未覆盖区域
稳定性 易发散(移动目标问题) 相对稳定(每轮目标固定,纯监督学习)

2.3. FQI 的阿喀琉斯之踵:分布不匹配与外推误差

FQI 的致命弱点在于数据分布的固定性。由于无法在线调整采集策略,如果初始数据存在盲区,算法将陷入"垃圾进,垃圾出"的困境。

2.3.1. 外推误差(Extrapolation Error)

当系统进入数据分布之外(Out-of-Distribution, OOD)的状态-动作对时,函数逼近器(特别是神经网络)会产生过度自信的虚假估计

  • 幻觉 Q 值:在未见过的状态,网络可能预测出荒谬的高价值(类似 Q-Learning 中的最大化偏差)
  • 策略崩溃max\max 操作选中这些幻觉值,导致策略执行危险动作
  • 无法自愈:在线算法可通过探索纠正错误,但 FQI 无法生成新数据来填补盲区

2.3.2. 典型案例

假设用纯随机策略收集迷宫数据:

  • 99% 的时间在原地打转或撞墙,仅 0.1% 偶然到达终点
  • FQI 学到"所有动作都很糟糕",因为它从未充分学习成功路径上的状态转移
  • 相比之下,在线 Q-Learning 一旦到达终点,会立即更新价值并自适应地倾向于终点方向,逐步收集关键路径样本

2.4. Conservative Q-Learning:保守主义解决方案

针对 FQI 的外推误差,Conservative Q-Learning (CQL) 通过**悲观主义(Pessimism)**机制提供了解决方案。

2.4.1. 核心思想

CQL 在标准贝尔曼误差基础上,增加保守正则项

LCQL=E(s,a)D[(Q(s,a)T^Q(s,a))2]标准贝尔曼误差+λ[EsD,aπ^[Q(s,a)]E(s,a)D[Q(s,a)]]保守惩罚项\mathcal{L}_{\text{CQL}} = \underbrace{\mathbb{E}_{(s,a)\sim \mathcal{D}}[(Q(s,a) - \hat{\mathcal{T}}Q(s,a))^2]}_{\text{标准贝尔曼误差}} + \lambda \underbrace{\left[\mathbb{E}_{s\sim \mathcal{D}, a\sim \hat{\pi}}[Q(s,a)] - \mathbb{E}_{(s,a)\sim \mathcal{D}}[Q(s,a)]\right]}_{\text{保守惩罚项}}

物理意义

  • 惩罚高估:对数据分布内未见过的动作(或分布外的状态),降低其 Q 值估计
  • 鼓励在分布内行动:优先选择数据集中出现过的 (s,a)(s,a) 对,避免冒险进入盲区
  • 安全探索:即使最优策略理论上应尝试某动作,如果数据不足,CQL 会选择保守

2.4.2. 算法效果

  • 缓解分布偏移:在数据稀疏区域,Q 值被系统性压低,防止策略盲目乐观
  • 离线强化学习的突破:使 FQI 能在固定数据集上安全学习,成为现代离线 RL(如 CQL、IQL、TD3+BC)的基础

2.5. 跨领域迁移:CQL 思想在无信标闭环控制中的应用

CQL 的**"对未知保持悲观"哲学不仅适用于强化学习,也为有监督学习+闭环控制**系统(如无信标导航)提供了关键启示。

2.5.1. 问题映射

在无信标闭环控制中,系统面临与 FQI 相似的分布外泛化风险:

离线强化学习 无信标闭环控制
固定数据集 D\mathcal{D} 有监督训练的有限采集数据
策略进入 OOD 状态 系统运行中进入训练域外状态
外推误差导致 Q 值幻觉 模型给出虚假准确的预测
max\max 操作选中幻觉值 PID 基于错误预测持续积分
结果:策略崩溃 结果:系统发散到不安全区域

2.5.2. 可迁移的保守策略

借鉴 CQL 的解决方案:

1. 不确定性量化与置信度衰减

1
2
3
4
5
uncertainty = model.predictive_variance(current_state)
confidence = 1 / (1 + uncertainty) # CQL 式的悲观权重

# 保守控制融合:不确定时降低模型权重,增加安全回退
control = confidence * model_prediction + (1 - confidence) * safe_fallback

2. 分布外检测(OOD Detection)与模式切换

1
2
3
4
5
6
reconstruction_error = vae.reconstruction_error(current_state)

if reconstruction_error > threshold: # 类似 CQL 的分布外判断
# 进入保守模式:冻结模型预测,启用纯 PID 或紧急制动
control = conservative_pid_only()
system.trigger_safety_protocol()

3. 悲观训练(Pessimistic Training) 在监督学习损失函数中引入 CQL 式的保守正则:

1
2
# 标准监督损失 + 危险区域惩罚(类似 CQL 的保守项)
loss = MSE(prediction, target) + lambda * max(0, prediction - safe_threshold)^2

迫使模型在边界区域天生偏向保守估计,即使训练数据支持冒险预测。

2.6. 总结:何时选择批量学习?

场景 在线学习(Q-Learning) 批量学习(FQI/CQL)
环境可交互且成本低 ✅ 首选 ❌ 不必要
历史数据丰富但禁止继续探索(医疗、昂贵实验) ❌ 不可行 ✅ 唯一选择
安全关键且探索危险(自动驾驶公共道路) ⚠️ 高风险 ✅ 先在模拟/历史数据上用 CQL 预训练
需要自适应优化采集策略 ✅ 强 ❌ 无

核心洞察

  • FQI 代表了"离线优化"的范式,用固定数据求解贝尔曼方程,但受限于分布不匹配
  • CQL 通过悲观价值估计解决了外推误差,其"对未知保持怀疑"的思想可迁移至任何面临分布外泛化的控制系统
  • 在无信标等闭环场景中,不确定性检测 + 保守回退机制是防止发散的关键,这正是 CQL 哲学在控制领域的延伸

3. 从贝尔曼方程到深度强化学习:SARSA、Q-Learning 与经验回放的系统性梳理

3.1. 引言:强化学习的理论根基

强化学习的核心问题是如何量化"状态-动作"的长期价值。1950年代,Richard Bellman 提出的贝尔曼方程(Bellman Equation)给出了价值的递归定义;而时域差分(Temporal Difference, TD)学习,正是贝尔曼方程的随机采样实现

本文将从理论出发,推导 SARSA 与 Q-Learning 的算法本质,解析经验回放(Replay Buffer)的工程逻辑,并通过"悬崖行走"案例揭示两者在风险态度上的根本差异。

3.2. 理论基础:贝尔曼方程的两种形式

3.2.1. 贝尔曼期望方程(Bellman Expectation Equation)

对于遵循策略 π\pi 的状态价值函数,其精确定义为:

Vπ(s)=aπ(as)s,rp(s,rs,a)[r+γVπ(s)]V^\pi(s) = \sum_a \pi(a|s) \sum_{s',r} p(s',r|s,a) \left[ r + \gamma V^\pi(s') \right]

核心特征:当前价值完全取决于后继价值的期望,形成递归定义。

3.2.2. 贝尔曼最优方程(Bellman Optimality Equation)

追求最优策略时,价值函数定义为:

Q(s,a)=s,rp(s,rs,a)[r+γmaxaQ(s,a)]Q^*(s,a) = \sum_{s',r} p(s',r|s,a) \left[ r + \gamma \max_{a'} Q^*(s',a') \right]

关键区别:使用 max\max 操作而非策略加权平均,代表"假设下一动作最优"的理论极限。

现实困境:这些方程需要知道环境的转移概率 p(s,rs,a)p(s',r|s,a),且涉及巨大的求和计算,在现实中往往不可得。

3.3. 时域差分学习:贝尔曼方程的采样实现

3.3.1. 从期望到采样

TD 学习的核心洞察:用单次采样的经验 (s,a,r,s)(s,a,r,s') 代替理论期望

TD(0) 更新公式:

V(s)V(s)+α[r+γV(s)V(s)]TD 误差 δtV(s) \leftarrow V(s) + \alpha \cdot \underbrace{[r + \gamma V(s') - V(s)]}_{\text{TD 误差 } \delta_t}

  • TD 目标r+γV(s)r + \gamma V(s') 是贝尔曼更新目标的无偏估计
  • 自举(Bootstrapping):用当前对 V(s)V(s') 的估计来更新 V(s)V(s),实现走一步、学一步

3.3.2. 控制问题:从 VVQQ

当问题从预测(评估策略)转向控制(寻找最优策略)时,我们需要学习动作价值函数 Q(s,a)Q(s,a)。TD 框架在此分化为两种路径:

3.4. 控制算法的双生子:SARSA vs Q-Learning

3.4.1. 算法定义与公式

SARSA(On-Policy)

  • 命名来源:SARSAS \to A \to R \to S' \to A'
  • 对应贝尔曼期望方程
  • 更新公式:

    Q(s,a)Q(s,a)+α[r+γQ(s,a)Q(s,a)]Q(s,a) \leftarrow Q(s,a) + \alpha [r + \gamma Q(s', \mathbf{a'}) - Q(s,a)]

  • 关键aa' 必须是按当前策略实际执行的下一动作

Q-Learning(Off-Policy)

  • 对应贝尔曼最优方程
  • 更新公式:

    Q(s,a)Q(s,a)+α[r+γmaxaQ(s,a)Q(s,a)]Q(s,a) \leftarrow Q(s,a) + \alpha [r + \gamma \max_{a'} Q(s', a') - Q(s,a)]

  • 关键:使用 maxa\max_{a'},假设在 ss' 采取最优动作,与实际执行无关

3.4.2. 核心差异的本质

维度 SARSA(同策略) Q-Learning(异策略)
学习对象 当前正在执行的策略(含探索错误) 理论最优策略(假设完美执行)
策略分离 行为策略 = 目标策略 = ϵ\epsilon-贪婪 行为策略(ϵ\epsilon-贪婪)≠ 目标策略(贪婪)
TD 目标 r+γQ(s,a)r + \gamma Q(s',a')(实际动作) r+γmaxQ(s,)r + \gamma \max Q(s',\cdot)(理论最优)
探索风险 计入成本(保守) 忽略不计(激进)

3.5. 悬崖行走:数值化的直观对比

3.5.1. 场景设定

1
2
3
起点[S] → → → 悬崖边[E] → → → 终点[G]

悬崖 (-100)
  • 最短路径:S → E → G(2步,贴崖)
  • 安全路径:S → 上 → 上 → G(3步,绕远)
  • 策略ϵ\epsilon-贪婪(ϵ=0.1\epsilon=0.1

3.5.2. 失败的轨迹分析

假设智能体在悬崖边 EE,理论最优是"向左"(安全),但 10% 概率随机探索选了"向右"(掉崖,r=100r=-100)。

SARSA 的更新

1
2
3
# a' 是实际执行的"向右"(掉崖)
td_target = -1 + 0.9 * Q(E, "向右") # -1 + 0.9*(-100) = -91
Q(D, "向右") += 0.5 * (-91 - 0) = -45.5 # 大幅拉低

逻辑:SARSA 认为"走到 E 很危险,因为我的探索策略有 10% 概率让我掉下去"。

Q-Learning 的更新

1
2
3
# 不管实际做了什么,假设在 E 选最优(向左)
td_target = -1 + 0.9 * max(Q(E, ["左","右"])) # -1 + 0.9*(-1) = -1.9
Q(D, "向右") += 0.5 * (-1.9 - 0) = -0.95 # 轻微下降

逻辑:Q-Learning 认为"走到 E 很安全,因为最优玩家不会掉下去"。

3.5.3. 收敛结果

  • SARSA:学会绕远路(安全路径),因为它评估的是"会犯错的自己"
  • Q-Learning:学会贴崖走(最短路径),因为它评估的是"完美的理想"

3.6. 工程实现:经验回放缓冲区(Replay Buffer)

3.6.1. 为什么需要缓冲区?

原始问题:在线更新(走一步、学一步、扔一步)存在三大缺陷:

  1. 样本浪费:关键经验(如掉崖)用完即弃
  2. 数据相关:连续经验高度相似,导致神经网络过拟合局部
  3. 分布不均:罕见状态难以多次学习

解决方案:引入经验回放缓冲区(Replay Buffer),存储历史经验 (s,a,r,s,done)(s,a,r,s',\text{done}),训练时随机采样

3.6.2. 为什么只有 Q-Learning 能用缓冲区?

这是 Off-Policy 的核心优势:

Q-Learning 的 TD 目标

r+γmaxaQ(s,a)r + \gamma \max_{a'} Q(s', a')

仅依赖于 (s,a,r,s)(s,a,r,s'),与产生这条数据的"旧策略"无关。即使是从 1000 步前的旧策略采集的经验,只要知道 ss',就能计算 max\max 并更新当前 Q 表。

SARSA 的困境

r+γQ(s,a)r + \gamma Q(s', a')

其中 aa' 必须是当前策略会选择的下一动作。如果用旧经验,当时的 aa' 是旧策略选的,与当前策略不匹配,更新将评估错误的策略。

结论Off-Policy 的 Q-Learning 可以"用旧策略的数据学习新策略",而 On-Policy 的 SARSA 必须"现采现用"

3.6.3. 马尔可夫性与随机采样

缓冲区能够打乱顺序随机采样,根本前提是环境的马尔可夫性

P(st+1st,at,st1,at1,)=P(st+1st,at)P(s_{t+1}|s_t,a_t,s_{t-1},a_{t-1},\dots) = P(s_{t+1}|s_t,a_t)

因为当前状态包含全部决策信息,单条经验 (s,a,r,s)(s,a,r,s') 是独立的转移单元,与时间上下文无关。这使得:

  • 第 100 步的经验和第 10000 步的经验可以混洗
  • 打破时间相关性,满足神经网络训练的独立同分布(i.i.d.)假设

3.6.4. 有放回采样

标准实现采用有放回(Sampling with Replacement)

  • 同一条经验可在同一 batch 中出现多次,也可在不同训练步骤中反复抽取
  • 有利于罕见但关键的经验(如终点奖励)被多次学习
  • 实现简单(随机索引),只要缓冲区容量(如 100k)远大于 batch size(如 32),统计差异可忽略

3.7. Max 操作的实现细节

3.7.1. 离散动作空间

表格法:直接查表取最大值

1
2
q_values = Q_table[next_state]  # [q1, q2, q3, q4]
max_q = np.max(q_values) # O(|A|),动作空间小时几乎零成本

神经网络(DQN):网络架构天然支持一次性输出

1
2
3
# 网络输入:状态 s',输出层:每个动作一个神经元(如18个动作)
q_values = network.forward(s') # 返回18个Q值
max_q = torch.max(q_values) # 并行计算,GPU高效

3.7.2. 连续性困境

若动作连续(无穷多种,如方向盘角度),无法遍历 max\max,此时应放弃 Q-Learning,改用 Actor-Critic(如 SAC、PPO)。

3.8. 总结:从理论到实践的完整图谱

1
2
3
4
5
6
7
8
9
10
11
12
贝尔曼方程(理论基础)
├── 贝尔曼期望方程 → SARSA(On-Policy)
│ └── 更新:Q(s,a) ← Q(s,a) + α[r + γQ(s',a') - Q(s,a)]
│ └── 策略统一:学习"我是谁"(含错误)
│ └── 缓冲区:❌ 难以使用(必须用当前策略数据)
│ └── 性格:保守、务实、风险规避

└── 贝尔曼最优方程 → Q-Learning(Off-Policy)
└── 更新:Q(s,a) ← Q(s,a) + α[r + γmaxQ(s',·) - Q(s,a)]
└── 策略分离:学习"我想成为谁"(最优理想)
└── 缓冲区:✅ 天然支持(可用任意旧数据)
└── 性格:激进、理想、追求极限

核心洞察

  • 贝尔曼方程定义了价值的递归真理
  • TD 学习提供了无模型、在线逼近的方法
  • max 操作决定了是否考虑探索风险(SARSA 的 aa' vs Q-Learning 的 max\max
  • Replay Buffer 是 Off-Policy 的加速器,让经验可以"反复温习",但其可行性根植于环境的马尔可夫性

选择指南

  • SARSA:当探索有真实代价(自动驾驶、机器人),需要评估"当前这个会犯错的策略"
  • Q-Learning:当追求极限性能(游戏 AI),或需要利用历史数据(离线学习)

理解这两者的差异,本质上就是理解**“同策略评估现实风险"与"异策略追求理论最优”**的分野——而这一切,都源于贝尔曼那个简洁而深刻的递归等式。

4. 什么是强化学习,关于强化学习的几点疑问

强化学习三要素:环境状态,行动,奖励

目标:尽量多的获得奖励

本质:连续决策

基本的强化学习模型包括:

  • 环境状态的集合 S
  • 动作的集合 A
  • 状态之间的转换规则(是环境的一部分)
  • 规定转换后“即时奖励”的规则(是环境的一部分)
  • 描述主体(智能体)能够观察到什么的规则(是环境的一部分)
  • 能够做出决策/动作的主体(智能体)

4.1. 区别于深度学习,强化学习的本质特点是什么?

两个定义

1,强化学习是机器学习的一个重要分支,主要用来解决连续决策问题。

2,强化学习又称 再励学习,评价学习或增强学习,是机器学习的范式和方法论之一,用于 描述和解决智能体(agent)在于环境交互过程中通过学习策略以达成回报最大或实现特定 目标的问题。

强化学习的本质是 描述和解决智能体(agent)在于环境交互过程 中通过学习策略以达成回报最大或实现特定目标的问题。它本质是这样一种场景, 在这种场景中它为了达到某种目的,做出连续的决策。这样符合这种场景,那就是强化学习 。

强化学习和深度学习这两个名词的维度是不一样的。深度学习描述的是算法本身的特点,深 度够不够,是不是连接主义的模型。深度学习可以用来做无监督,也可以用来做半监督,也 可以用来做弱监督,甚至可以用来作为强化学习算法的一部分。深度学习这个名词,不管应 用场景只管模型本身是不是满足深度学习的特点。

而强化学习描述的是应用场景的特点,只要能提供智能体决策的算法,管它是什么模型,什 么结构,那就是强化学习的算法。从这个角度上讲,我现在认为强化学习和监督学习,无监 督学习,弱监督学习,是并列的,是对应用场景的描述。和深度学习不是同一维度的。

强化学习的本质在于目标给定的形式,不像无监督学习那样完全没 有学习目标,也不像监督学习那样有非常明确的目标(label),强化学习的目标一般是变 化的,不明确的,甚至可能不存在绝对正确的目标。,强化学习的问题都可以抽象成,环境 状态,行动和奖励。应该说只要能抽象为这三个要素,目标是获得最大奖励的模型,就是强 化学习的模型。

强化学习的最大的特点是“试错”,是尝试各种可能,而强化结果好的可能。(策略网络的特 点,估值网络的特点是修正和预测获益)

由于强化学习是一种决策学习,这个问题的特点就是离散型。但是离散并不就是强化学习( 连续的决策才是,目标的模糊和不确定性是决策问题的特点)。深度学习本质是函数的拟合 ,所以连续可微是它的特点。并不能说连续可微的问题就是深度学习,离散的问题就是强化 学习。

4.2. 深度学习用梯度下降的算法实现模型的优化,强化学习无法求导,甚至连学习目标都是模糊的如何优化模型参数?

这个问题要了解下一节,具体的强化学习方法。

4.3. 强化学习与弱监督学习?

弱监督是属于有监督学习,只是它学习的目标不是被给予的标签,而是比被给予标签更强的 标签(强弱是指标签做含有的信息量),也就是说弱监督是根据少量信息的标签,推测出更 多的信息。

强化学习的本质是连续决策。连续决策的特点是目标的模糊和不确定性。

所以,虽然弱监督和强化学习都没有给出最终准确的目标,但是他们任然很不同的

4.4. 深度学习是死的,没有智能的机器学习算法,强化学习是“活的”,有智能的机器学习算法

深度学习大部分我们用作有监督的学习算法。其实说深度学习是死的,不如说有监督学习是 死的。

有监督学习其实是完全的复刻标签里面含有的知识,它的本质就是一个函数拟合的问题,它 无法摆脱对绝对的标签的依赖,无法超越标签。

而强化学习,正由于它的目标是模糊和不确定的。使得算法在设计上必须具有随机性和探索 性,它能够探索出人类从来没有到过的领域。就像在围棋上,下出人类完全无法理解的棋, 人从来没有想过的一些下法。这就是强化学习算法探索出来的知识。所以我觉得它是活着的 ,拥有智能的算法。

从感性的层面,强化学习算法很接近人脑的行为:感知环境,探索环境 ,强化有益行为

4.5. 关于深度学习,强化学习,连续可导性和离散不可导性的讨论

  1. 从函数的角度,深度学习和强化学习都需要学习一个函数映射。深度学习是从输入到 target 的映射。强化学习是学从环境状态到 Action 的映射。这两个映射可以看成性 质一样的,因为深度学习可以作为强化学习的智能体。所以从函数的角度,他们没有连 续和离散的区别。(PS. 深度学习模型和强化学习的智能体都是连续可导的函数 。target 和 Action 都可以是离散的或者连续的。)

  2. 深度学习作为用梯度下降算法优化的模型,无法优化对 loss 不可导的参数。如在深度 学习中,设计一个分支来决定模型是否应该包含某个模块,这个分支的参数是不可优化 的。因为包含和不包含是离散的,对 loss 不可导。

不过假设,如果包含与不包含是连续的。也就是说,可以以 0.1 的权重包含。那么,这些 参数是可以优化的。从这点来看,离散就是导致模型参数不可优化的原因。

  1. 强化学习在离散的情况下解决 2 中的问题。由此,我得到了一个概念,强化学习解决 离散的问题。

  2. 下面我们来分析一下这个场景。首先,决定一个模块该不该被使用,这个场景是一次 Action 的场景,不是连续决策的场景。也就是说 Action 一次,我就能知道最终 reward 多少了,只有单步的 reward。

限于这个单次决策的场景来看,如果 Action 相对于 reward 是连续可导的,那么深度学习 就能解决这个问题。如果 Action 相对于 reward 是离散的,那么仅仅深度学习无法解决这 个问题,要靠强化学习。

这里单次 Action 就知道 reward,实际上这个问题就退化为了有监督 学习,因为这个单步的 reward 就可以看成我的标签了。所以深度学习解决这个问题是很自 然的。

  1. 多次决策的问题,无论是连续的还是离散的都只能用强化学习的方法。因为多次决策, 这个问题就不可以退化为监督学习的问题了。它是一个真正的强化学习的问题。

综上所诉,强化学习解决深度学习解决不了的离散问题,那只是在单次决策的时候,这个问 题退化为了有监督学习。强化学习的方法,恰好可以提供离散变量的学习。

强化学习方法解决深度学习中的离散问题,仅仅是强化学习附带的一个小福利。

因为它能把经验转化为可导的目标,就拿策略网络来说,从梯度的角 度,它只管增加当前随机 Action 的概率,而加入 advatage 之后,自动就优化除了想要的 大 reward 的行为。

4.6. 深度学习优化和强化学习优化的感性理解

前面说了深度学习优化可导的参数,强化学习可以优化不可导的参数。这里说一下对深度学 习优化方法和强化学习优化方法的感性理解。

还是说前面包不会包含某模块的例子,由于连续可导,对于每一个参数值,深度学习模型其 实都同时参与了两种 Action(包含和不包含)。score = 0.1 包含,其实其中包含了含有 的成分,也包含了不含有的成分。所以我们可以连续的变动 score,看看包含多好,还是不 好含多好。这其实就是梯度下降算法的方式。得益于每一个参数,其实我都对包含和不包含 的情况都有了解,我当然知道哪个更好,就往那边移动(优化)。

然而,对于离散的情况,要么只能包含,要么只能不包含。当选择包含的时候,模型对不包 含的情况完全是无知的。可能更好,也可能差。当不包含的时候,也是一样的。无论哪种情 况,我都没有办法优化,两种情况是完全隔离开的,信息不沟通的,是离散的。所以梯度下 降算法无法优化它。

强化学习用随机探索的方法让两者信息又沟通起来。包含一下试一下,然后,不包含也试一 下。尝试的结果是哪种 reward 多,就增大哪种的概率。

所以,无论哪种优化方法,信息的沟通都是必要的。要对所有的 action 都了解,才能知道选择哪种 action。 只是深度学习是连续的,它的每一种参数, 都包含了所有 Action 的信息(reward),每一种 Action 都参与了,所以它能直接连续的 梯度下降的优化,不需要随机探索了。而对于离散的,每种 action 只能知道自己的 reward,对其他 Action 一无所知的时候,梯度的优化是不行的。必须要探索各种 Action,还是要知道了每一种 Action 的情况(reward)之后,才能优化。这是方法论 。

更进一步,离散的地方,相对于 reward 一定是不可导的,所以深度学习不行。而强化学习 ,更准确的说是策略网络,相当于给离散的地方加了标签,这样它就在离散的地方有监督了 ,它就可以根据增加的标签优化。而标签的设计就是根据探索的结果,增大 reward 大的 Action,reward 大的 Action 就是它的标签,而且这个标签是动态的,是对抗得出的。

强化学习方法算出的梯度是策略梯度。

强化学习: 不知道选哪边了; 试试呗;按试出来 reward 大的 Action 优化它。

强化学习:它离散,对于 reward 不可导;不直接用 reward 优化它 ,给它加个标签,把试出来 reward 大的 Action,作为标签去优化

在不可导的地方加标签。

由此,强化学习算法的本质是制作标签,无论是连续决策,标签不确 定的情况,还是它能解决离散问题的情况,它都是用制作标签的方法解决的。

5. 策略网络(Policy Network)和估值网络(Value Network)

AlphaGo 使用了快速走子,策略网络,估值网络和蒙特卡洛搜索树等技术。

强化学习算法的一个关键是随机性和探索性,我们需要让算法 通过试验样本自己学习什么才是某个环境状态下比较好的 Action,而不是像有监督学习一 样,告诉模型什么是好的 Action,因为我们也不知道什么是好的 Action.

深度强化学习模型的本质是神经网络,神经网络是工具,根据问题转化以及建模的不同,主 要分为策略网络和估值网络。

强化学习中最重要的两类方法Policy-based,Value-based。第一种直接预测在某个环境 下应该采取的行动(直接输出改采取 Action 的概率)。第二种预测在某个环境下所有行动 的期望价值,然后通过选择 q 值最高的行动执行策略。

他们都能完成决策,但由于建模的不同,估值网络包含有更多的信息,它不仅能提供决策, 还预测了决策带来的收益。

策略网络是隐式的学习了某一 Action 所带来的全部获益(当前获 益+后续获益),而估值网络直接显示的学习 Action 所带来的全部获益。强化学习 算法做出最佳抉择只需要知道哪个 Action 全部获益最大,策略网络就是这样做的,估值网 络不仅学习了哪个 Action 全部获益最大,还把每个 Action 的全部获益给计算出来了。

相对来说,策略网络的性能会比估值网络好一些。

Value Based 方法适合仅有少量 Action 的环境,而 Policy Based 方 法更通用,适合 Action 种类非常多,或者具有连续取值的 Action 的环境。结合了深度学 习之后,Policy Based 方法就变成了策略网络,Value Based 方法就变成了估值网络 。

5.1. 策略网络(Policy Network)

直接看一个例子,学习的目标是,左右用力使得木棍不倒地 Policy_Network.py

关键代码

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
score = tf.matmul(layer1,W2)
probability = tf.nn.sigmoid(score)#网络输出采取Action 1的概率。
input_y = tf.placeholder(tf.float32,[None,1], \\
name="input_y")# 输入采取过的行为,这个行为是随机生成的。
advantages = tf.placeholder(tf.float32,name="reward_signal")
# 输入获益
loglik = tf.log(input_y*(input_y - probability) + \\
(1 - input_y)*(input_y + probability))
# 损失函数,如果行为是1,则增大

#概率,如果行为是 0,则减小概率(相当于也是增加0的概率),也就是说这个损
#失函数无论当前行为是什么都会增大当前行为的概率。
loss = -tf.reduce_mean(loglik * advantages) # 这行代码很关键,
#相当于给损失函数成了一个权重advantages,得到最终的损失函数。
#advantages是当前试验的全部获益。如果全部获益大,将以更大的权重,增加
#当前行为的概率。

#所以,策略网络其实也是一个对抗学习的过程,增加所有采取过行为的概率,只是
#获益多的行为以更大的权重增加。

#一个试验: 由初始状态开始,随机采取一连串的行为
#(Policy_Network.py 中是根据当前模型输出的概率,来生成随机的行为,但
#是我感觉直接用0.5的概率随机生成一连串的0和1的行为也是可以的,下面将实
#验一下),直到任务结束。

## 由于每个试验,都可以一直行为到任务结束,所以每个action,我们都可以得
#到它在该试验中的全部获益(当前获益 + 之后所有行为的获益)

## 随机生成了n个试验,其中又各种各样的决策(随机探索),全部获益大的
#action,它的advantages也大,那么它的概率就增大的多,它被强化的厉害。

##试验生成的过程,实际上就是数据集构建的过程。策略网络的数据集是由环境
#和一系列随机的行为构成的。它提供了环境在各种行为下的反应(获益)。模型
#学习为环境带来高获益的行为的规律。

由上面的代码可知,从策略网络的角度看强化学习的话,强化学习的关键其实是对数据集的 构建—如何构建数据集。

在构建数据集的时候,随机探索肯定是必要的。随机探索的结果会得到一系列好的行为,也 会得到一系列不好的行为。如何强化好的行为就是算法设计的时候需要注意的。

上面的代码在探索阶段借用了当前的模型,即根据当前模型输出的概率随机生成行为,从而 形成数据集。如果完全的随机(一直使用 0.5 的概率随机的生成 Action)会什么样呢?

5.1.1. 数据集是否可以和模型无关(不随着模型变化)?

关键修改代码

1
2
3
4
###基于当前模型,根据当前的状态x,生成Action 1的概率
tfprob = sess.run(probability,feed_dict={observations: x})
### 基于预测概率,随机生成行为,并试探环境。生成数据集。
action = 1 if np.random.uniform() < tfprob else 0

修改后

1
2
3
4
5
### 注释掉这句,并不需要根据当前模型生成概率
### tfprob = sess.run(probability,feed_dict={observations: x})
### 直接设置概率为0.5,随机完全随机探索生成数据集。
tfprob = 0.5
action = 1 if np.random.uniform() < tfprob else 0

结果:修改后,模型无法收敛。

完全随机很小的概率能探索出很好的试验,这些好的行为也很难持续的得到强化。

所以,强化学习也有一种效果叠加的感觉。在完全随机的情况下 ,探索出相对好的 action,再在这个相对好的 action 的基础上,在探索探索出更好的 action。

如果数据集不依赖模型,就是一直在完全随机的基础上探索。这样很难收敛。

也可以这样看,完全随机的话,最多能学到前几步的策略(因为完全随机就走不了几步,探 索的经验就只有那几步)。依赖于模型,探索的行为更有价值,因为是依赖于学到过的知识 的,一方面确认了,按学到的知识走,确实获益多,一方面又在学到的知识的基础上,做了 一些随机,探索更好的知识。

5.2. 估值网络(Value Network,Q-learning)

Q-Learing 用神经网络实现,得到的模型就是估值网络。

也看一个例子 ,Value_Network.py

学习每个 Action 所对应的 reward 的期望。

我们先看看数据集的结构

1
2
3
4
###Save the experience to our episode buffer.
episodeBuffer.add(np.reshape(np.array([s,a,r,s1,d]),[1,5]))
### 其中s是当前时刻的环境状态,a是当前随机采取的Action,r是这个Action的当前reward
### s1是采取Action之后的下一状态,d是布尔型表示是否任务结束。
  1. 现在目标是学习 Q(st, at),也就是当前环境状态,采取行为 a 的全部 reward 的期望。

  2. 现在假设我们有模型 Qdesird,可以预测全部 reward 了,那么这个模型 应该满足条件,Qdesired(st, at) = r + λ\lambda Maxa Qdesired(st+1, a),这有点递 归的感觉了。

  3. 现在我们能不能根据这个公式 , 来优化出 Qdesired。肯定是能的。对于 探索过的所有试验,公式都满足的话,此时的模型就可以看成我们想要的模型了。我感 觉这就是估值网络方法的核心。

直接看关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
###Choose an action by greedily (with e chance of random action)
### from the Q-network
if np.random.rand(1) < e or total_steps < pre_train_steps:
a = np.random.randint(0,4)
else:
a = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:[s]})[0]
### 这段代码其实是探索的代码,当最开始的时候是完全随机探索(total_steps < pre_train_steps的时候)
### 当total_steps >= pre_train_steps之后呢,就不是完全随机探索了。
### 有e的概率是随机探索的,(1-e)的概率是由训练好的模型决定之后的Action。
### 这里是估值网络和策略网络的不同,策略网络本身就具有随机性,所以不需要引入
### 额外的参数e和pre_train_steps来控制随机探索的强度。
### 策略网络在训练的过程中,本身就是由随机性大,到慢慢的收敛到好的Action
### 所以可以直接得到好的探索的训练样本。估值网络没有这样好的性质,它连
### 随机性都没有,就需要人为的制造,满足从完全随机探索,到在好的Action的
### 基础上具有一定的随机性进行探索。

这是策略网络和估值网络的共通之处,其实这也最上面那个注释"by greedily (with e chance of random action) from the Q-network"的意思。

“贪心”两个字完美的诠释了强化学习,无论是策略网络还是估值网络 ,在探索阶段,在生成数据集上的特点。

在策略网络那一节,我做的那个试验,和模型无关生成数据集。其实就是不贪心了,不贪心 不行。

1
2
3
4
5
6
7
8
9
if total_steps > pre_train_steps:
if e > endE:
e -= stepDrop
### 完全随机了之后,开始慢慢减小随机性。
### 模型约不可靠的时候,探索性和随机性越强。后来模型慢慢变得可靠就减弱随机性。
### 因为模型越来越可靠的时候,随机性大就会得到很多远远低于当前模型性能的试验
### 这些试验都是早就被pass了的,学不到什么东西,损坏模型的探索。
### endE=0.1 说明无论训练的多好,模型都保持了随机性,保持了探索性
### 人永远要有好奇心,永远要觉得自己的知识还可能不是最好的

下面的代码是将在数据集弄好的情况下,如何训练模型的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if total_steps % (update_freq) == 0:
trainBatch = myBuffer.sample(batch_size) #Get a random batch of experiences.
#Below we perform the Double-DQN update to the target Q-values
# 主网络预测了下一刻需要采取的Action,trainBatch[:,3]是当前的下一刻的环境
# 回顾公式,Q(st, at) = r + $\lambda$ Max Q(s_t+1, a)
# 这里主函数预测的Action就是t+1时刻(下一时刻)获益值最大的Action
Q1 = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,3])})
# target网络预测了下一时刻的reward
Q2 = sess.run(targetQN.Qout,feed_dict={targetQN.scalarInput:np.vstack(trainBatch[:,3])})
end_multiplier = -(trainBatch[:,4] - 1)
# 用主网络预测出的Action以及target网络预测出的所有行为的reward
# 选择了最大的reward,也就是公式中的 Max Q(s_t+1, a)
doubleQ = Q2[range(batch_size),Q1]
# 这里得到的就是公式Q(st, at) = r + $\lambda$ Max Q(s_t+1, a)
# 的右边,当前reward加上乘以衰减系数之后的,下一步最大reward
targetQ = trainBatch[:,2] + (y*doubleQ * end_multiplier)
#Update the network with our target values.
# 公式右边得到了之后,在把真正的当前状态输入进去,得到左边
# 左边以右边作为标签进行学习。更新主网络的参数
_ = sess.run(mainQN.updateModel, \
feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,0]),mainQN.targetQ:targetQ, mainQN.actions:trainBatch[:,1]})
# 更新target网络的参数。
updateTarget(targetOps,sess) #Update the target network toward the primary network.

target 网络参数的更新方式代码

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
def updateTargetGraph(tfVars,tau):
total_vars = len(tfVars)
op_holder = []
# 主网络是和target网络一样的,前一半参数正好是主网络的参数
for idx,var in enumerate(tfVars[0:total_vars//2]):
# idx+total_vars对应的时候后一半的参数也就是target网络的参数
# 这里相当于是target参数 = 主网络参数 * tau + (1- tau)*target参数
# 也就是说target网络在以一定的速度向主网络靠近
# 结合前面的代码,主网络才是真正学习的网络,target网络的作用仅仅是得到等式
# 右边的值,即标签,即使是等式右边,也不是target网络完全决定的
# target网络得到了所有Action的reward,最大的Action是主网络选择的
# 为什么要这么做,target网络也是在模仿主网络,只用主网络也能得到等式的右边
# 理论上其实右边也应该是主网络决定,现在搞了个主网络的模仿者target网络
# 是出于优化的考虑。我们后面叙述。
op_holder.append(tfVars[idx+total_vars//2].assign\\
((var.value()*tau) \\
+ ((1-tau)*tfVars[idx+total_vars//2].value())))
return op_holder

def updateTarget(op_holder,sess):
for op in op_holder:
sess.run(op)

```

现在其实我们把关键的代码都看了,在这段代码实现中,引入了一些state of the art的trick,下面我们结合看过的代码在提一遍。

1. 引入卷积层,这段代码比较简单,我们没有看。环境状态是用图片的形式给的,用CNN提取特征是比较自然的。
2. Experience replay。估值网络不像策略网络一样得到试验之后,用一次就扔掉再去制作新的试验(数据集)来训练。它把每次试验都放在一个试验池里面。试验池长度为N,如果超过了N,那就把最老的试验样本扔掉。每次 训练的时候从试验池里面随机选择batchsize个样本进行训练,保持了对样本的利用率,同时其实也增加了模型的稳定性,因为数据集是相对稳定的(相比于N=1而言,每次训练了就扔掉,进来的都是新的,不那么稳定)。
3. 使用target网络来辅助训练。\*\*之所以要用target网络来制造训练目标,用主网络来实际训练,是为了让Q-Learing训练的目标保持平稳。\*\*强化学习不像普通的监督学习,它的目标是变化的,\*\*因为学习目标的一部分就是模型本身输出的。\*\*每次更新模型参数都会导致学习目标发生变化,如果更新频繁,幅度很大,我们的训练过程就会变得非常不稳定并且失控。\*\*DQN的训练会陷入目标Q与预测Q的反馈循环中,震荡发散。\*\*所以用target网络来制造目标,target网络和主网络又不是矛盾的,因为target网络会逼近主网络,它是主网络的模仿者,所以它提供的目标Q也是有权威的。
4. Double DQN。这个trick源于target网络选的最大Action不准。模仿的不够好,现在就让主网络来帮它选。也就是上面代码中我们看过了主网络输出action,选择target网络输出的reward,得到公式的右边。
5. Dueling DQN。上代码

```python
self.AW = tf.Variable(xavier_init([h_size//2,env.actions]))
self.VW = tf.Variable(xavier_init([h_size//2,1]))
self.Advantage = tf.matmul(self.streamA,self.AW)
self.Value = tf.matmul(self.streamV,self.VW)

###Then combine them together to get our final Q-values.
### 看这里Qout是网络最终预测的所有Action的reward。它由两部分组成Value和Advantage
### 由最上面两行可以看出Value是一维的,是实数,advantage是#action维度的向量
### 所以,Dueling DQN就是将reward裁成了两部分,一部分是环境状态本身具有的价值Value
### 另一部分就是Action本身具有的价值,相加起来就是在这个环境下Action具有的价值。
### 其实我感觉这些解释都是人为的,具体是不是这样谁也不知道,可能只是这样优化的好。
### 因为即使不分为两部分,网络输出Qout的时候,输入也是环境状态,肯定都会把环境考虑
### 进去才有Action的价值。然而直接输出这个价值,发现优化的不好,分为两部分之后,发现
### 优化的好了。其实谁也不知道其中到底是什么原因起作用。
self.Qout = self.Value + tf.subtract(self.Advantage,tf.reduce_mean(self.Advantage,axis=1,keep_dims=True))

5.3. 策略网络和估值网络的不同

从策略网络和估值网络看,强化学习都有探索和对抗两个过程。通过探索,得到数据集,包 含了各种可能性。通过对抗,让数据集中好的(reward 高的试验胜出)。他们的不同点在 于对抗的方法。

  1. 策略网络:对抗的焦点在于选择 Action 的概率。
  2. 估值网络:对抗的焦点在于评估 Action 的 reward。
  3. 两者都会影响数据集的制作,而且影响的方式是相同的:贪心和随机探索
  4. 比起策略网络,估值网络更加没有对抗的感觉。因为策略网络在提高某一个 Action 的 概率的时候,会抑制其他 Action 的概率(总的概率为 1)。而估值网络在提高某一个 Action 的 reward 的时候,和其他 Action 是无关的。而且其实不能说是提高 reward,它是预测出正确的 reward。(这是两者的很大的不同处,策略网络更像是 一个分类问题,而估值网络像是一个回归问题)

6. 回顾

强化学习的本质是连续决策。强化学习算法的关键是标签制作,数据集制作。

连续决策问题是没有确定的标签的,它通过探索试验得到数据集和标签,为没有提供标签的 问题,做了标签,让问题可以解决。

深度学习无法优化离散的不可导的参数,强化学习也可以通过在离散的地方做数据集做标签 ,把它转换为可导的,可用 sgd 优化的问题。

做标签和数据集的关键是随机性以及贪心,贪心让它立足于以往的知识,随机让它不刚愎自 用,保持谦卑,给新的可能保留空间。

无论是策略网络还是估值网络,在数据集的制作上都是一样的,随机性和贪心。估值网络的 数据集制作,可以看出强化学习探索的本质(由于估值网络本身没有随机性,它在制作数据 集的时候,显示的暴露了,探索和贪心的本质。策略网络这方面还不太好看出来,因为它是 隐式的利用探索和贪心)。

策略网络,增大所有行为的概率,但是对于 reward 大 的行为增大的权重大。这个思路在 我得感觉上更加符合强化两个字。强化好的行为嘛。

估值网络的本质是公式 Qdesired(st, at) = r + λ\lambda Maxa Qdesired(st+1, a),有点递归的感 觉。

策略网络和估值网络数据集也有一点不同,策略网络的数据集是纵向的,一串行为一起的。 而估值网络的数据集是单个单个的。

由下面代码可以看出,策略网络中,每一窜试验就会训练一次,只是网络参数更新会积累了 好几次试验之后才更新。策略网络关心从开始到结束一系列行为。而估值网络只关心当前和 下一状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if done:
episode_number += 1
epx = np.vstack(xs)
epy = np.vstack(ys)
epr = np.vstack(drs)
tfp = tfps
xs,hs,dlogps,drs,ys,tfps = [],[],[],[],[],[]

discounted_epr = discount_rewards(epr)
discounted_epr -= np.mean(discounted_epr)
discounted_epr //= np.std(discounted_epr)

tGrad = sess.run(newGrads,feed_dict={observations: epx, input_y: epy, advantages: discounted_epr})
for ix,grad in enumerate(tGrad):
gradBuffer[ix] += grad

if episode_number % batch_size == 0:
sess.run(updateGrads,feed_dict={W1Grad: gradBuffer[0],W1_1Grad:gradBuffer[1],W2Grad:gradBuffer[2]})

估值网络人为的控制随机强度,也是一个值得考虑的问题。