文章目录
- 前言
- **一、 理论基础:什么是策略梯度?**
- **1.1 基于价值 vs. 基于策略**
- **1.2 策略梯度(Policy Gradient)**
- **1.3 REINFORCE 算法:蒙特卡洛策略梯度**
- **1.4 REINFORCE 算法流程**
- **二、 PyTorch 代码实践**
- **2.1 环境与辅助函数**
- **2.2 核心算法实现**
- **2.3 训练与结果**
- **总结**
前言
欢迎来到“从代码学习深度强化学习”系列!在之前的文章中,我们可能已经接触了许多基于价值(Value-based)的强化学习算法,如 Q-learning 和 DQN。这些算法的核心思想是学习一个价值函数(如 Q-函数),然后根据这个函数间接地推导出一个最优策略。然而,在很多现实场景中,尤其是那些动作空间连续或者非常大的问题中,直接学习一个策略函数可能更为高效和直接。
今天,我们将深入探讨**策略梯度(Policy Gradient)**方法,这正是直接学习策略的算法家族的基石。我们将聚焦于该家族中最基础也最经典的算法之一:REINFORCE。通过本篇博客,您将不仅理解 REINFORCE 的核心理论,还将跟随我们一步步用 PyTorch 实现一个完整的 REINFORCE 智能体,并在经典的 CartPole 环境中进行训练和测试。
让我们一起从理论出发,最终落脚于代码,彻底掌握 REINFORCE 算法的精髓!
完整代码:下载链接
一、 理论基础:什么是策略梯度?
在深入代码之前,我们必须先理解 REINFORCE 算法背后的核心思想——策略梯度。
1.1 基于价值 vs. 基于策略
首先,让我们明确两类方法的根本区别:
- 基于价值 (Value-based) 的方法:如 Q-learning、DQN 及其改进算法,它们学习的是价值函数。学习过程并不会显式地存在一个策略,而是根据学到的价值函数(例如,选择Q值最高的动作)来推导出一个策略。
- 基于策略 (Policy-based) 的方法:这类方法不通过价值函数,而是直接学习一个目标策略。智能体会学习一个带参数的策略函数
π(a|s, θ)
,这个函数直接输出在某个状态s
下采取各个动作a
的概率。我们的目标就是找到最优的参数θ
,使得策略最优。
策略梯度方法正是基于策略的方法的基础。
1.2 策略梯度(Policy Gradient)
基于策略的方法首先需要将策略参数化。假设我们的目标策略 πθ
是一个随机性策略,并且处处可微,其中 θ
是对应的参数。我们可以用一个线性模型或者神经网络来构建这样一个策略函数建模,它输入某个状态,然后输出一个动作的概率分布。我们的目标是要寻找一个最优策略并最大化这个策略在环境中的期望回报。
我们将策略学习的目标函数定义为:
J ( θ ) = E s 0 [ V π θ ( s 0 ) ] J(\theta)=\mathbb{E}_{s_0}[V^{\pi_\theta}(s_0)] J(θ)=Es0[Vπθ(s0)]
其中, s 0 s_0 s0 表示初始状态,V
是状态价值函数,J(θ)
代表了在策略 π θ \pi_{\theta} πθ 下,从初始状态 s 0 s_0 s0开始所能获得的期望总回报。
现在有了目标函数,我们就可以将目标函数对策略参数 θ
求导,得到导数后就可以用梯度上升方法来最大化这个目标函数,从而得到最优策略。这个梯度就是我们常说的策略梯度,其具体形式如下(推导过程略):
∇ θ J ( θ ) ∝ ∑ s ∈ S ν π θ ( s ) ∑ a ∈ A Q π θ ( s , a ) ∇ θ π θ ( a ∣ s ) = ∑ s ∈ S ν π θ ( s ) ∑ a ∈ A π θ ( a ∣ s ) Q π θ ( s , a ) ∇ θ π θ ( a ∣ s ) π θ ( a ∣ s ) = E π θ [ Q π θ ( s , a ) ∇ θ log π θ ( a ∣ s ) ] \begin{aligned}\nabla_\theta J(\theta)&\propto\sum_{s\in S}\nu^{\pi_\theta}(s)\sum_{a\in A}Q^{\pi_\theta}(s,a)\nabla_\theta\pi_\theta(a|s)\\&=\sum_{s\in S}\nu^{\pi_\theta}(s)\sum_{a\in A}\pi_\theta(a|s)Q^{\pi_\theta}(s,a)\frac{\nabla_\theta\pi_\theta(a|s)}{\pi_\theta(a|s)}\\&=\mathbb{E}_{\pi_\theta}[Q^{\pi_\theta}(s,a)\nabla_\theta\log\pi_\theta(a|s)]\end{aligned} ∇θJ(θ)∝s∈S∑ν