DQN 04 - Actor-Critic Methods

xiangyu fu Lv3

4.1 简介

在强化学习中,Actor-Critic方法是一种结合策略优化(policy optimization)和价值评估(value estimation)的方法。它通过将策略网络(Actor)和价值网络(Critic)结合在一起,提高了智能体的学习效率和稳定性。

  • Actor(行为者):负责选择动作。Actor是一个策略网络,输入状态 ,输出在该状态下采取每个可能动作的概率分布
  • Critic(评论者):负责评估动作的价值。Critic是一个价值网络,输入状态 (以及可能的动作 ),输出该状态的值 或动作-状态对的值

4.2 动机

在强化学习(Reinforcement Learning, RL)中,智能体通过与环境交互来学习策略,以最大化累积奖励。传统的RL方法大致分为两类:基于值的方法(Value-based methods)基于策略的方法(Policy-based methods)。每种方法都有其优缺点,Actor-Critic方法结合了这两种方法的优点,解决了各自的一些问题。

传统方法的问题

  1. 基于值的方法

    • Q-learningSARSA是典型的基于值的方法,它们通过估计状态-动作对的值(Q值)来指导策略选择。
    • 缺点
      • 高维动作空间:在连续动作空间中,基于值的方法难以直接应用,因为Q值表会变得过于庞大且难以处理。
      • 策略不可微:基于值的方法需要从Q值中提取策略,这通常是非平滑的,难以应用梯度方法优化。
  2. 基于策略的方法

    • REINFORCE是一个经典的策略梯度方法,通过直接优化策略来最大化累积奖励。
    • 缺点
      • 高方差:策略梯度估计的方差较高,导致训练过程不稳定且收敛缓慢。
      • 效率低:每一步更新需要完整的轨迹,训练效率较低。

Actor-Critic方法的优势

Actor-Critic方法结合了基于值和基于策略方法的优点,通过同时学习策略和价值评估来提高训练效率和稳定性。

  1. 降低方差

    • Actor-Critic方法通过引入Critic来估计状态值或动作-状态对的值(即V值或Q值),从而降低策略梯度估计的方差。Critic提供了一个基线(baseline),使得策略更新更加稳定。
  2. 高效的策略更新

    • Actor(行为者)直接输出在给定状态下采取不同动作的概率分布,使得策略可以直接应用于连续动作空间,并且策略是可微的,可以使用梯度方法进行优化。
    • Critic(评论者)评估当前策略的价值,并提供梯度信号来引导Actor的更新。
  3. 适应高维状态和动作空间

    • 由于Actor-Critic方法的策略表示和价值表示都可以使用神经网络进行参数化,它们可以很自然地扩展到高维状态和动作空间。

4.3 A3C

A3C(Asynchronous Advantage Actor-Critic,异步优势演员-评论者)是深度强化学习中一种高效的策略优化方法。它通过异步并行训练多个智能体来提高训练效率和稳定性。

4.3.1 A3C算法的基本概念

  1. 异步更新:多个智能体在不同的环境实例上并行运行,各自独立地与环境交互,更新局部策略参数和全局策略参数。
  2. 优势函数:使用优势函数来减少策略梯度的方差,优势函数定义为实际回报与状态值函数之间的差异。
  3. 多步回报:使用n步回报替代单步回报,以更好地估计长期回报,提高训练稳定性和效率。

4.3.2 公式详解

A3C算法的核心思想是通过异步并行的方式同时训练多个智能体,每个智能体独立地与环境交互,计算梯度并更新全局参数。以下是A3C算法的主要公式和步骤:

  1. 策略梯度

    • 策略梯度用于更新Actor的策略参数,基于优势函数计算。
    • 优势函数 表示为:
    • 策略梯度公式:
    • 其中, 是策略网络输出的在状态 下选择动作 的概率。
  2. 价值函数

    • Critic网络用于评估状态值 ,通过最小化均方误差更新价值函数。
    • 价值函数更新公式:
  3. 多步回报

    • 使用n步回报替代单步回报,以更好地估计长期回报。
    • n步回报定义为:
  4. 全局参数更新

    • 每个智能体独立地与环境交互,计算局部梯度,并将其应用于全局参数。
    • 全局参数更新公式:
    • 其中, 是第 个智能体计算的梯度。
  5. 异步并行

    • 多个智能体在不同的环境实例上并行运行,各自独立地与环境交互。
    • 每个智能体定期将局部参数同步到全局参数,并使用全局参数更新局部参数。

4.3.3 A3C算法的主要步骤

  1. 初始化

    • 初始化全局策略网络参数 和全局价值网络参数
    • 初始化多个智能体的局部参数
  2. 异步并行训练

    • 每个智能体在各自的环境实例中并行运行。
    • 在每个时间步
      • 根据当前状态 使用策略网络 选择动作
      • 执行动作 ,得到新的状态 和奖励
      • 计算优势函数
      • 使用策略梯度公式更新局部策略网络参数
      • 使用价值函数公式更新局部价值网络参数
    • 定期将局部参数 同步到全局参数
  3. 全局参数更新

    • 将所有智能体计算的局部梯度累积并应用于全局参数。
  4. 重复

    • 重复上述过程,直到达到预定的训练步骤或满足停止条件。

4.4 A2C

A2C(Advantage Actor-Critic,优势演员-评论者)是A3C(Asynchronous Advantage Actor-Critic)的同步版本。与A3C不同,A2C通过同步方式并行训练多个智能体,保持了训练的高效性和稳定性,同时简化了实现过程。

4.4.1 A2C算法的基本概念

  1. 同步更新:多个智能体在不同的环境实例上并行运行,但在每个训练阶段结束时同步更新策略和价值网络的参数。
  2. 优势函数:使用优势函数来减少策略梯度的方差,优势函数定义为实际回报与状态值函数之间的差异。
  3. 多步回报:使用n步回报替代单步回报,以更好地估计长期回报,提高训练稳定性和效率。

4.4.2 公式详解

A2C算法的核心思想与A3C类似,但通过同步并行方式来训练多个智能体。以下是A2C算法的主要公式和步骤:

  1. 策略梯度

    • 策略梯度用于更新Actor的策略参数,基于优势函数计算。
    • 优势函数 表示为:
    • 策略梯度公式:
    • 其中, 是策略网络输出的在状态 下选择动作 的概率。
  2. 价值函数

    • Critic网络用于评估状态值 ,通过最小化均方误差更新价值函数。
    • 价值函数更新公式:
  3. 多步回报

    • 使用n步回报替代单步回报,以更好地估计长期回报。
    • n步回报定义为:
  4. 同步参数更新

    • 每个智能体独立地与环境交互,计算局部梯度,并在每个训练阶段结束时同步更新全局参数。
    • 全局参数更新公式:
    • 其中, 是第 个智能体计算的梯度。

4.4.3 A2C算法的主要步骤

  1. 初始化

    • 初始化全局策略网络参数 和全局价值网络参数
    • 初始化多个智能体的局部参数
  2. 同步并行训练

    • 每个智能体在各自的环境实例中并行运行。
    • 在每个时间步
      • 根据当前状态 使用策略网络 选择动作
      • 执行动作 ,得到新的状态 和奖励
      • 计算优势函数
      • 使用策略梯度公式更新局部策略网络参数
      • 使用价值函数公式更新局部价值网络参数
    • 在每个训练阶段结束时,将所有智能体的局部梯度累积,并同步更新全局参数。
  3. 全局参数更新

    • 将所有智能体计算的局部梯度累积并应用于全局参数。
  4. 重复

    • 重复上述过程,直到达到预定的训练步骤或满足停止条件。

4.4.4 A2C算法的优缺点

优点

  1. 高效性:通过并行训练多个智能体,提高了样本效率和训练速度。
  2. 稳定性:同步更新参数避免了异步更新可能带来的不稳定性。
  3. 易实现:A2C的同步机制相对于A3C的异步机制实现起来更加简单。

缺点

  1. 资源占用:并行训练需要更多的计算资源和内存。
  2. 同步开销:每个训练阶段结束时的同步更新可能带来一定的开销。

4.5 GAE:广义优势估计

广义优势估计(Generalized Advantage Estimation,GAE)是强化学习中的一种技术,用于降低策略梯度方法中优势函数估计的方差,从而提高训练的稳定性和效率。GAE是由John Schulman等人在其论文“High-Dimensional Continuous Control Using Generalized Advantage Estimation”中提出的。

4.5.1 动机

在策略梯度方法中,我们使用优势函数(Advantage Function)来指导策略的更新。传统的优势函数定义为实际回报与状态值函数之间的差异。然而,这种方法可能导致高方差,使得训练过程不稳定。GAE通过引入折扣因子,平滑优势函数估计,减少方差,提高策略更新的稳定性。

4.5.2 公式详解

GAE的核心思想是通过引入折扣因子,对优势函数进行加权平均,从而平滑优势估计。以下是GAE的主要公式:

  1. 优势函数(Advantage Function)

    传统的优势函数定义为:

    其中, 是状态值函数, 是折扣因子, 是即时奖励。

  2. 时间差分误差(Temporal Difference Error,TD Error)

    多步时间差分误差定义为:

    其中, 是多步回报的步数。

  3. 广义优势估计(Generalized Advantage Estimation,GAE)

    GAE通过对不同步数的时间差分误差进行加权平均来平滑优势函数估计。GAE定义为:
    $$
    A^{GAE(\gamma, \lambda)}t = \sum{k=0}^{\infty} (\gamma \lambda)^k \delta_{t+k}
    $$
    其中, 是一个新的折扣因子,用于控制时间差分误差的加权。

  4. 实际实现中的截断

    在实际实现中,由于无限求和不可行,我们通常在有限步数 内进行截断:
    $$
    A^{GAE(\gamma, \lambda)}t = \sum{k=0}^{T} (\gamma \lambda)^k \delta_{t+k}
    $$

4.5.3 主要步骤

  1. 计算时间差分误差

    • 对每个时间步 ,计算多步时间差分误差
  2. 加权平均

    • 使用折扣因子 ,对时间差分误差进行加权平均,得到广义优势估计
  3. 策略更新

    • 使用计算得到的优势估计 ,通过策略梯度方法更新策略参数。

4.5.4 GAE的优缺点

优点

  1. 降低方差:GAE通过引入折扣因子,平滑优势函数估计,显著降低了策略梯度估计的方差。
  2. 提高稳定性:由于方差降低,策略更新更加稳定,训练过程更高效。
  3. 灵活性:通过调整折扣因子 ,可以在偏差和方差之间进行权衡,适应不同的任务需求。

缺点

  1. 复杂度增加:相比于简单的优势函数估计,GAE引入了额外的计算步骤,增加了实现的复杂度。
  2. 参数敏感性:GAE的性能对折扣因子 的选择较为敏感,需要在不同任务中进行调参。

广义优势估计(GAE)通过对优势函数进行加权平均,显著降低了策略梯度方法中的方差,提高了策略更新的稳定性和效率。GAE是现代强化学习算法中的一项重要技术,广泛应用于各种策略优化方法中。通过合理调整参数 ,GAE可以在偏差和方差之间找到最佳平衡,从而在不同任务中取得优异的性能表现。

4.6 DDPG

DDPG(Deep Deterministic Policy Gradient,深度确定性策略梯度)是一种针对连续动作空间的强化学习算法。它结合了深度Q网络(DQN)和确定性策略梯度(Deterministic Policy Gradient,DPG)的优点,通过使用深度神经网络对策略和Q值进行建模,能够在高维连续动作空间中高效地进行策略优化。DDPG由Lillicrap等人在其论文“Continuous Control With Deep Reinforcement Learning”中提出。

4.6.1 动机

在连续动作空间中,基于值的方法(如DQN)难以直接应用,因为Q值表会变得过于庞大且难以处理。确定性策略梯度方法(DPG)通过直接学习确定性策略来避免动作空间的高维问题,而DDPG进一步结合深度学习技术,使得该方法能够处理高维状态和动作空间中的复杂任务。

4.6.2 DDPG算法的基本概念

  1. 确定性策略:DDPG使用确定性策略而非随机策略,即策略网络直接输出特定状态下的具体动作,而不是动作的概率分布。
  2. 策略网络(Actor):负责选择动作,输入状态 ,输出动作
  3. Q网络(Critic):负责评估动作的价值,输入状态 和动作 ,输出Q值
  4. 目标网络:为了稳定训练过程,DDPG使用目标网络(Target Networks),即在每次参数更新时,目标网络的参数缓慢地向策略网络和Q网络的参数靠近。
  5. 经验回放池:DDPG使用经验回放池(Replay Buffer)来存储智能体与环境交互的数据,通过小批量随机抽样来打破数据相关性,提高训练效率。

4.6.3 公式详解

DDPG结合了深度Q网络和确定性策略梯度的优点,以下是其主要公式和步骤:

  1. 策略更新(Policy Update)

    策略网络(Actor)的目标是最大化Q值,策略梯度公式为:
    $$
    \nabla_{\theta^\mu} J \approx \mathbb{E}{s \sim \mathcal{D}} \left[ \nabla_a Q(s, a|\theta^Q) |{a=\mu(s|\theta^\mu)} \nabla_{\theta^\mu} \mu(s|\theta^\mu) \right]
    $$
    其中, 是策略网络, 是Q网络, 是经验回放池。

  2. Q网络更新(Critic Update)

    Q网络(Critic)的目标是最小化Bellman误差,损失函数为:

    其中,目标值 定义为:

    分别是目标Q网络和目标策略网络, 是折扣因子。

  3. 目标网络更新(Target Network Update)

    为了稳定训练过程,使用软更新(Soft Update)来更新目标网络的参数:


    其中, 是一个小的常数(如0.001),表示更新的速率。

  4. 经验回放(Experience Replay)

    智能体与环境交互,生成经验 ,并将其存储到经验回放池中。从经验回放池中随机抽取小批量样本用于训练,以打破数据的相关性,提高训练的稳定性和效率。

4.6.4 DDPG算法的主要步骤

  1. 初始化

    • 初始化策略网络 和Q网络 及其对应的目标网络
    • 初始化经验回放池
  2. 交互和存储经验

    • 智能体在环境中执行动作 (其中 是探索噪声),得到新的状态 和奖励
    • 将经验 存储到经验回放池 中。
  3. 从经验回放池中采样

    • 从经验回放池中随机采样小批量样本
  4. 更新Critic网络

    • 计算目标值
    • 最小化损失函数 ,更新Q网络参数。
  5. 更新Actor网络

    • 使用策略梯度公式 更新策略网络参数。
  6. 更新目标网络

    • 软更新目标网络参数
  7. 重复

    • 重复上述过程,直到达到预定的训练步骤或满足停止条件。

DDPG算法通过结合深度Q网络和确定性策略梯度的优点,成功地在高维连续动作空间中实现了高效的策略优化。通过策略网络和Q网络的协同训练,以及目标网络和经验回放池的使用,DDPG能够稳定地训练复杂的强化学习任务。

4.7 Continues control example

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class DDPG():
"""Interacts with and learns from the environment using the DDPG algorithm."""

def __init__(self, state_size, action_size, random_seed):
self.state_size = state_size
self.action_size = action_size
self.seed = random.seed(random_seed)

# Actor Neural Network (Regular and target)
self.actor_regular = Actor(state_size, action_size, random_seed).to(device)
self.actor_target = Actor(state_size, action_size, random_seed).to(device)
self.actor_optimizer = optim.Adam(self.actor_regular.parameters(), lr=LR_ACTOR)

# Critic Neural Network (Regular and target)
self.critic_regular = Critic(state_size, action_size, random_seed).to(device)
self.critic_target = Critic(state_size, action_size, random_seed).to(device)
self.critic_optimizer = optim.Adam(self.critic_regular.parameters(), lr=LR_CRITIC)

# Replay memory
self.memory = ReplayBuffer(action_size, BUFFER_SIZE, BATCH_SIZE, random_seed)

# Ensure that both networks have the same weights
self.deep_copy(self.actor_target, self.actor_regular)
self.deep_copy(self.critic_target, self.critic_regular)

def step(self, states, actions, rewards, next_states, dones, timestep):
# Save collected experiences
for state, action, reward, next_state, done in zip(states, actions, rewards, next_states, dones):
self.memory.add(state, action, reward, next_state, done)

# Learn from our buffer if possible
if len(self.memory) > BATCH_SIZE and timestep % UPDATE_EVERY == 0:
for _ in range(N_EXPERIENCES):
experiences = self.memory.sample()
self.learn(experiences, GAMMA)

def act(self, states):
states = torch.from_numpy(states).float().to(device)

# Evaluation mode
# Notify all your layers that you are in eval mode, that way,
# Batchnorm or dropout layers will work in eval mode instead of training mode.
self.actor_regular.eval()
# torch.no_grad() impacts the autograd engine and deactivate it.
# It will reduce memory usage and speed up
with torch.no_grad():
actions = self.actor_regular(states).cpu().data.numpy()
# Enable Training mode
self.actor_regular.train()

return actions


def learn(self, experiences, gamma):
states, actions, rewards, next_states, dones = experiences

# Update the critic neural network
# Get predicted next-state actions
actions_next = self.actor_target(next_states)
# Get Q values from target model
Q_targets_next = self.critic_target(next_states, actions_next)

# Compute Q targets for current states
Q_targets = rewards + (gamma * Q_targets_next * (1 - dones))

# Calculate the critic loss
Q_expected = self.critic_regular(states, actions)
critic_loss = F.mse_loss(Q_expected, Q_targets)

# Minimize the loss
self.critic_optimizer.zero_grad()
critic_loss.backward()
self.critic_optimizer.step()

# Update the actor neural network
# Calculate the actor loss
actions_pred = self.actor_regular(states)
# Change sign because of the gradient descent
actor_loss = -self.critic_regular(states, actions_pred).mean()

# Minimize the loss function
self.actor_optimizer.zero_grad()
actor_loss.backward()
self.actor_optimizer.step()

# Update target network using the soft update approach (slowly updating)
self.soft_update(self.critic_regular, self.critic_target, TAU)
self.soft_update(self.actor_regular, self.actor_target, TAU)


def soft_update(self, local_model, target_model, tau):
# Update the target network slowly to improve the stability
for target_param, local_param in zip(target_model.parameters(), local_model.parameters()):
target_param.data.copy_(tau*local_param.data + (1.0-tau) * target_param.data)

def deep_copy(self, target, source):
for target_param, param in zip(target.parameters(), source.parameters()):
target_param.data.copy_(param.data)
  • Title: DQN 04 - Actor-Critic Methods
  • Author: xiangyu fu
  • Created at : 2024-06-06 14:38:47
  • Updated at : 2025-12-10 16:10:05
  • Link: https://redefine.ohevan.com/2024/06/06/DRL/4.Actor-Critic Methods/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments