Advertisement

(10-3)Actor-Critic算法:Soft Actor-Critic (SAC)

阅读量:

10.3 Soft Actor-Critic (SAC)

Soft Actor-Critic(简称SAC)是一种基于深度强化学习的方法...旨在应对具有连续动作空间与高维状态空间的复杂任务...该算法作为演员-评论家框架的一个增强型版本...通过引入一些创新性改进措施来显著提升性能

10.3.1 Soft Actor-Critic算法的核心思想

Soft Actor-Critic(SAC)的基本概念在于通过最大熵强化学习来实现策略优化,并在探索与利用之间实现协调。该方法采用双值函数、自动调节目标熵以及经验回放等技术来解决连续动作空间的问题,并由深度神经网络来掌握复杂的策略。SAC已在多个强化学习任务中取得了显著成效,并特别适合于处理高维状态和连续动作的问题。

  1. 最大熵强化学习:最大熵强化学习的思想为SAC提供了理论基础。在这一框架下,不仅关注于最大化累积奖励,还强调策略的不确定性最大化(或称为熵)。因此,SAC策略在追求高回报的同时,也会努力保持多样性和探索性,从而能够更全面地探索状态空间。通过引入最大熵正则化项,SAC在优化过程中实现了对探索与利用的平衡。
  2. 连续动作空间:针对连续动作空间的特殊需求,SAC开发了一种独特的解决方案。由于在连续动作空间中,可能的动作是无限多样的,SAC采用了高斯分布来描述策略参数,这样既能保证动作的有效性又能灵活适应不同的环境。
  3. 双值函数(Q值和V值):为了更精确地评估策略性能,在Q-网络和价值网络之间建立了明确的关系。这种设计不仅有助于准确估计状态-动作对的价值,Q值函数还能被用来计算优势函数,从而指导整个策略的学习过程。
  4. 目标熵的自动调整:通过动态调节目标熵这一关键机制,SAC能够实现对探索与利用之间的平衡调节。当当前策略的不确定性低于设定目标时,SAC会鼓励更多的探索行为。
  5. 经验回放:经验回放技术使得SAC能够更有效地利用先前的经验,从而提高训练效率和模型稳定性。

10.3.2 熵(Entropy)的作用及其在SAC中的应用

信息论中的熵(Entropy)及其在强化学习领域中的重要地位受到广泛关注。具体而言,在强化学习框架内,熵概念被成功应用于最大熵强化学习算法中,在此框架下策略的熵指标则起到指导探索过程的作用,并通过平衡探索与利用之间的关系来优化决策过程。随后将深入探讨其在强化学习中的具体应用及其在Soft Actor-Critic(SAC)算法实现中的关键角色:在此方法论下 entropy 的计算与应用不仅推动了智能体行为决策的质量提升还为复杂环境下的自主行动提供了理论基础。

**1.**熵的作用

  1. 不确定性评估:信息论中的"熵"是一种用于评估不确定性程度的指标,在强化学习领域被广泛应用于衡量状态下的行为选择情况。
  2. 探索与信息获取:"熵"这一概念不仅用于平衡探索与信息获取,在强化学习理论中还被用来量化行为选择过程中的均匀分布特性。
  3. 策略优化:以最大化行为决策多样性为目标的"最大熵原理"通常被采用作为重要的优化准则,在这一过程中除了追求更高的预期回报之外还需要特别考虑决策空间的有效扩展可能性。
  4. 策略改进:通过引入"最大约束条件"的方式进行改进设计,在这一过程中不仅能够提升系统的稳定性和可靠性还能够实现对复杂环境的有效适应。
  5. 效应分析:"最大约束条件"这一概念也被成功应用于系统响应效果分析领域,并且通过建立相应的约束方程组能够较为准确地预测系统的响应特性。
  6. 应用案例:"最大约束条件"方法已经被广泛应用于多个实际案例研究当中,并且通过这些实践应用已经取得了显著的研究成果。
  7. 优势体现:"最大约束条件"作为一种严格的系统设计方法,在提高系统性能方面展现出了显著的优势。
  8. 应用前景:"最大约束条件"理论不仅为传统工业系统提供了新的设计思路,在智能控制系统的设计过程中也展现出巨大的应用潜力。
  9. 基本原理:"最大约束条件"理论基于系统的能量守恒定律和资源分配效率的基本原理展开研究,在这一过程中通过对系统的能量分布进行合理规划能够实现资源的最大化利用效率

**2.**熵在Soft Actor-Critic中的应用

Within the Soft Actor-Critic (SAC) framework, entropy serves as a pivotal concept integral to its theoretical foundation. Specifically, in SAC architecture, entropy plays a central role in information processing and decision-making mechanisms.

  1. 最大化策略的熵:SAC的目标函数不仅包括最大化期望累积奖励,还包括最大化策略的熵。这可以表示为一个带有熵正则化项的优化问题,其中目标是最大化期望奖励和策略熵的加权和。这使得SAC策略更具探索性,因为它会鼓励策略选择多样性的动作。
  2. 自动调整目标熵:SAC通过自动调整目标熵的方式来平衡探索和利用。它使用一个目标熵的参数,然后通过学习过程中的自动调整来控制策略的探索性。当策略的熵低于目标熵时,SAC会鼓励更多的探索,以保持策略的多样性。
  3. 探索性能的提升:通过引入熵正则化项,SAC能够在探索性能和利用性能之间找到平衡。这有助于在强化学习任务中更好地处理探索问题,特别是在高维状态和连续动作空间中。

总体而言,在SAC框架中,熵被用来实现对探索与利用的动态平衡。为了提升系统的探索能力,在训练过程中会最大化策略的熵值。因此,在这一机制下构建起来的方法能够有效地解决连续动作空间的问题,并且在实际应用中表现出色。

10.3.3 SAC算法的训练过程

Soft Actor-Critic(SAC)算法的训练过程通常包括以下步骤:

(1)初始化

初始化主演员及其对应的目标演员,并分别初始化其对应的策略评估器及其对应的目标策略评估器的神经网络参数;随后后续设定其他关键算法参数如学习率、目标熵、折扣因子等。

(2)数据采集

通过与环境的交互来采集样本数据。这一过程通常包括采用当前策略(演员网络)对环境进行交互,并记录所获得的状态、执行的动作、即时奖励以及随后的状态变化。为提升数据利用率的目标,常会采用经验回放缓冲区来存储并循环利用先前的经验样本。

(3)计算目标策略熵

评估目标策略的熵,并用于优化目标熵的一致性设置。一般情况下,在稳定环境中 entropy 值为恒定数值;然而,在动态变化的环境中 entropy 可以通过训练过程进行动态调整。

(4)更新评论家网络

通过缓存区中的样本数据获取Q值(基于状态-动作对的价值评估),并采用均方误差或其他合适的损失函数训练评论家网络以近似Q值函数。随后更新目标评论家网络常采用软更新策略(如滑动平均值用于更新参数)。

(5)更新演员和策略网络

通过评估者网络基于Q值估计来计算政策梯度。利用政策梯度算法调整演员网络参数以寻求最大化期望累积奖励与熵的加权总和。同步目标演员与目标策略网络参数常采用渐进式复制方式。

(6)自动调整目标熵

在训练过程中动态调节目标熵以协调探索与开发。当策略的熵低于设定值时提升目标值以此促进更多地探索。

(7)重复:重复步骤2至步骤6,直到达到预定的训练轮数或其他停止条件。

(8)评估机制:当训练完成时,可以通过演员网络的最终参数设置来评估策略的有效性。通常情况下,在测试环境中对策略进行执行,并计算相应的平均奖励或其他关键性能指标来量化其表现。

(9)保存模型(可选):保存训练后的演员、评论家和策略网络模型,以备将来使用。

SAC的训练遵循迭代机制,在演员网络与评论家网络之间存在协作关系,并基于反馈机制不断优化策略。该算法具有处理连续动作空间与高维状态空间的能力,并且能够平衡多样性和探索性的需求。

10.3.4 SAC算法实战

以下是一个基于SAC算法的简化示例,在此设定中构建了一个基本的模拟场景。其中有一个虚拟机器人旨在避开障碍物的同时逃离原点位置。该代理通过训练阶段逐步优化其动作选择策略以实现长期累积奖励的最大化。

**实例10-3:使用SAC算法训练一个强化学习代理(源码路径:daima*10*sac.py

实例文件sac.py的主要实现代码如下所示:

复制代码
 # 定义虚拟环境

    
 class Environment:
    
     def __init__(self):
    
     self.state_dim = 2  # 状态维度为2(x坐标和y坐标)
    
     self.action_dim = 1  # 动作维度为1(推进或后退)
    
     self.state = np.array([0.0, 0.0])  # 初始状态为原点坐标
    
  
    
     def step(self, action):
    
     # 模拟虚拟机器人的动作
    
     velocity = action[0]  # 动作表示速度
    
     self.state[0] += velocity  # 更新x坐标
    
  
    
     # 计算奖励,目标是使机器人尽量远离原点
    
     reward = -np.abs(self.state[0])
    
  
    
     # 检查是否达到终止条件(机器人离原点太远)
    
     done = np.abs(self.state[0]) > 10.0
    
  
    
     return self.state, reward, done
    
  
    
  
    
 # 创建连续动作空间的SAC代理
    
 class SACAgent:
    
     def __init__(self, state_dim, action_dim):
    
     self.state_dim = state_dim
    
     self.action_dim = action_dim
    
  
    
     # 创建策略网络和Q网络
    
     self.actor = self.build_actor()
    
     self.q1 = self.build_critic()
    
     self.q2 = self.build_critic()
    
  
    
     # 定义优化器
    
     self.actor_optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
    
     self.critic_optimizer = tf.keras.optimizers.Adam(learning_rate=0.002)
    
  
    
     def build_actor(self):
    
     input_layer = Input(shape=(self.state_dim,))
    
     x = Dense(64, activation='relu')(input_layer)
    
     x = Dense(64, activation='relu')(x)
    
     mean = Dense(self.action_dim, activation='tanh')(x)
    
     log_stddev = Dense(self.action_dim)(x)
    
     actor = Model(inputs=input_layer, outputs=[mean, log_stddev])
    
     return actor
    
  
    
     def build_critic(self):
    
     input_layer = Input(shape=(self.state_dim + self.action_dim,))
    
     x = Dense(64, activation='relu')(input_layer)
    
     x = Dense(64, activation='relu')(x)
    
     q_value = Dense(1)(x)
    
     critic = Model(inputs=input_layer, outputs=q_value)
    
     return critic
    
  
    
     def select_action(self, state):
    
     mean, log_stddev = self.actor.predict(np.array([state]))
    
     stddev = tf.math.exp(log_stddev)
    
     action_distribution = tfp.distributions.Normal(loc=mean, scale=stddev)
    
     action = action_distribution.sample()
    
     return action.numpy()[0]
    
  
    
     def update(self, state, action, reward, next_state, done):
    
     with tf.GradientTape(persistent=True) as tape:
    
         mean, log_stddev = self.actor(np.array([state]))
    
         stddev = tf.math.exp(log_stddev)
    
         action_distribution = tfp.distributions.Normal(loc=mean, scale=stddev)
    
         log_prob = action_distribution.log_prob(action)
    
  
    
         # 将action从一维数组转换为二维数组
    
         action = np.array([action])
    
  
    
         # 连接state和action
    
         q1_value = self.q1(np.concatenate([np.array([state]), action], axis=-1))
    
  
    
         q2_value = self.q2(np.concatenate([np.array([state]), action], axis=-1))
    
  
    
         next_mean, next_log_stddev = self.actor(np.array([next_state]))
    
         next_stddev = tf.math.exp(next_log_stddev)
    
         next_action_distribution = tfp.distributions.Normal(loc=next_mean, scale=next_stddev)
    
         next_action = next_action_distribution.sample()
    
         next_log_prob = next_action_distribution.log_prob(next_action)
    
  
    
         target_q_value = tf.minimum(q1_value, q2_value) - log_prob + next_log_prob
    
         target_q_value = tf.stop_gradient(target_q_value)
    
  
    
         critic_loss1 = tf.reduce_mean(tf.square(target_q_value - q1_value))
    
         critic_loss2 = tf.reduce_mean(tf.square(target_q_value - q2_value))
    
  
    
         actor_loss = tf.reduce_mean(log_prob - tf.minimum(q1_value, q2_value))
    
  
    
     actor_gradients = tape.gradient(actor_loss, self.actor.trainable_variables)
    
     critic_gradients1 = tape.gradient(critic_loss1, self.q1.trainable_variables)
    
     critic_gradients2 = tape.gradient(critic_loss2, self.q2.trainable_variables)
    
  
    
     self.actor_optimizer.apply_gradients(zip(actor_gradients, self.actor.trainable_variables))
    
     self.critic_optimizer.apply_gradients(zip(critic_gradients1, self.q1.trainable_variables))
    
     self.critic_optimizer.apply_gradients(zip(critic_gradients2, self.q2.trainable_variables))
    
  
    
     del tape
    
  
    
  
    
 # 训练SAC代理
    
 def train_sac_agent():
    
     env = Environment()
    
     agent = SACAgent(env.state_dim, env.action_dim)
    
  
    
     max_episodes = 1000
    
     for episode in range(max_episodes):
    
     state = env.state
    
     total_reward = 0
    
  
    
     while True:
    
         action = agent.select_action(state)
    
         next_state, reward, done = env.step(action)
    
         agent.update(state, action, reward, next_state, done)
    
  
    
         total_reward += reward
    
         state = next_state
    
  
    
         if done:
    
             break
    
  
    
     print(f"Episode: {episode}, Total Reward: {total_reward}")
    
  
    
  
    
 if __name__ == "__main__":
    
     train_sac_agent()
    
    
    
    
    代码解读

上述代码的实现流程如下所示:

  1. 构建了一个虚拟环境Environment,在该环境中状态空间由x坐标和y坐标两个维度构成;而行动空间则由推进或后退两种操作构成。虚拟机器人的目标是尽量远离初始位置。
  2. SAC代理SACAgent包含策略网络(actor)与两个价值网络(critics)。其中策略网络用于输出行动均值与对数标准差参数;而价值网络则用于评估状态-行动对的价值。
  3. 策略网络与价值网络的具体架构将在build_actor与build_critic方法中分别定义。
  4. select_action方法负责根据当前状态输出一个行动样本。
  5. update函数实现了Soft Actor-Critic算法的核心逻辑:首先计算相应状态下各行动的概率密度;其次评估状态-行动对的价值;接着计算目标价值并更新参数;最后利用梯度下降法优化策略模型与价值模型参数。
  6. 在训练循环中;代理将通过多轮交互学习来优化自身性能:在每一轮循环中;代理根据当前状态选择行动;随后通过环境反馈获得奖励信号;最终更新模型参数以适应新的任务需求。
  7. 当程序直接运行脚本时;将初始化并启动SAC代理的学习过程。

未完待续

全部评论 (0)

还没有任何评论哟~