
在强化学习领域,策略梯度算法和基于价值的方法是两种重要的学习范式。策略梯度算法直接对策略进行优化,通过调整策略参数来最大化累积奖励;而基于价值的方法则通过学习价值函数来间接指导策略的选择。Actor - Critic算法巧妙地将这两种方法结合起来,充分发挥了它们的优势,在许多复杂的强化学习任务中取得了出色的表现。本文将详细介绍策略梯度算法以及Actor - Critic算法的原理、特点和实现。
在策略梯度算法中,策略通常用一个参数化的函数 $\pi{\theta}(a|s)$ 来表示,其中 $\theta$ 是策略的参数,$s$ 是状态,$a$ 是动作。这个函数表示在状态 $s$ 下选择动作 $a$ 的概率。例如,在一个简单的机器人导航任务中,状态 $s$ 可以是机器人当前的位置和朝向,动作 $a$ 可以是机器人的前进、左转、右转等操作,$\pi{\theta}(a|s)$ 则给出了在当前状态下选择每个动作的概率。
策略梯度算法的目标是最大化期望累积奖励 $J(\theta)$,即:
[J(\theta) = \mathbb{E}{\tau \sim \pi{\theta}} \left[ \sum_{t=0}^{T} r(s_t, a_t) \right]]
其中,$\tau = (s_0, a_0, r_0, s_1, a_1, r_1, \cdots)$ 是一个轨迹,$r(s_t, a_t)$ 是在状态 $s_t$ 下执行动作 $a_t$ 获得的即时奖励。
为了优化目标函数 $J(\theta)$,我们需要计算其关于参数 $\theta$ 的梯度 $\nabla{\theta} J(\theta)$。根据策略梯度定理,有:
[\nabla{\theta} J(\theta) = \mathbb{E}{\tau \sim \pi{\theta}} \left[ \sum{t=0}^{T} \nabla{\theta} \log \pi{\theta}(a_t|s_t) Q^{\pi{\theta}}(st, a_t) \right]]
其中,$Q^{\pi{\theta}}(st, a_t)$ 是动作价值函数,表示在策略 $\pi{\theta}$ 下,从状态 $s_t$ 执行动作 $a_t$ 后获得的期望累积奖励。
通过计算梯度,我们可以使用梯度上升法来更新策略参数:
[\theta \leftarrow \theta + \alpha \nabla_{\theta} J(\theta)]
其中,$\alpha$ 是学习率。
基于价值的方法主要通过学习价值函数来指导策略的选择。最常见的价值函数是状态价值函数 $V^{\pi}(s)$ 和动作价值函数 $Q^{\pi}(s, a)$。
状态价值函数 $V^{\pi}(s)$ 表示在策略 $\pi$ 下,从状态 $s$ 开始获得的期望累积奖励:
[V^{\pi}(s) = \mathbb{E}{\tau \sim \pi} \left[ \sum{t=0}^{T} r(s_t, a_t) | s_0 = s \right]]
动作价值函数 $Q^{\pi}(s, a)$ 表示在策略 $\pi$ 下,从状态 $s$ 执行动作 $a$ 后获得的期望累积奖励:
[Q^{\pi}(s, a) = \mathbb{E}{\tau \sim \pi} \left[ \sum{t=0}^{T} r(s_t, a_t) | s_0 = s, a_0 = a \right]]
基于价值的方法通常使用动态规划、蒙特卡罗方法或时间差分学习来学习价值函数,然后根据价值函数选择最优动作。
Actor - Critic算法结合了策略梯度算法和基于价值的方法。它由两个部分组成:Actor(策略网络)和Critic(价值网络)。
Actor负责学习策略 $\pi_{\theta}(a|s)$,通过策略梯度算法来更新策略参数 $\theta$。Actor根据当前状态 $s$ 选择动作 $a$,并与环境进行交互,获得奖励 $r$ 和下一个状态 $s’$。
Critic负责学习价值函数 $V{\phi}(s)$ 或 $Q{\phi}(s, a)$,其中 $\phi$ 是价值网络的参数。Critic根据Actor与环境交互得到的数据来更新价值网络的参数,以估计状态或动作的价值。
Actor - Critic算法的基本流程如下:
与传统的策略梯度算法相比,Actor - Critic算法使用Critic来估计价值函数,从而减少了策略梯度估计的方差。因为Critic可以提供更准确的价值估计,使得策略更新更加稳定。
由于结合了价值函数的学习,Actor - Critic算法可以更快地收敛到最优策略。Critic可以帮助Actor更快地找到有价值的动作,从而加速学习过程。
Actor - Critic算法可以很方便地处理连续动作空间。因为Actor直接输出动作的概率分布,对于连续动作空间,可以使用高斯分布等连续概率分布来表示策略。
以下是一个简单的基于TensorFlow的Actor - Critic算法实现示例,用于解决OpenAI Gym的CartPole-v1环境:
import tensorflow as tfimport numpy as npimport gym# 定义Actor网络class Actor(tf.keras.Model):def __init__(self, num_actions):super(Actor, self).__init__()self.dense1 = tf.keras.layers.Dense(64, activation='relu')self.dense2 = tf.keras.layers.Dense(num_actions, activation='softmax')def call(self, inputs):x = self.dense1(inputs)return self.dense2(x)# 定义Critic网络class Critic(tf.keras.Model):def __init__(self):super(Critic, self).__init__()self.dense1 = tf.keras.layers.Dense(64, activation='relu')self.dense2 = tf.keras.layers.Dense(1)def call(self, inputs):x = self.dense1(inputs)return self.dense2(x)# 定义Actor - Critic代理class ActorCriticAgent:def __init__(self, num_actions, learning_rate_actor=0.001, learning_rate_critic=0.005, gamma=0.99):self.actor = Actor(num_actions)self.critic = Critic()self.optimizer_actor = tf.keras.optimizers.Adam(learning_rate=learning_rate_actor)self.optimizer_critic = tf.keras.optimizers.Adam(learning_rate=learning_rate_critic)self.gamma = gammadef select_action(self, state):state = np.expand_dims(state, axis=0)action_probs = self.actor(state)action = np.random.choice(len(action_probs[0]), p=action_probs[0].numpy())return actiondef train_step(self, state, action, reward, next_state, done):state = np.expand_dims(state, axis=0)next_state = np.expand_dims(next_state, axis=0)with tf.GradientTape() as tape_actor, tf.GradientTape() as tape_critic:# 计算Critic的价值估计value = self.critic(state)next_value = self.critic(next_state)# 计算时间差分误差if done:target = rewardelse:target = reward + self.gamma * next_valuedelta = target - value# 计算Actor的损失action_probs = self.actor(state)action_mask = tf.one_hot(action, len(action_probs[0]))log_prob = tf.math.log(tf.reduce_sum(action_mask * action_probs, axis=1))actor_loss = -log_prob * delta# 计算Critic的损失critic_loss = 0.5 * tf.square(delta)# 更新Actor的参数gradients_actor = tape_actor.gradient(actor_loss, self.actor.trainable_variables)self.optimizer_actor.apply_gradients(zip(gradients_actor, self.actor.trainable_variables))# 更新Critic的参数gradients_critic = tape_critic.gradient(critic_loss, self.critic.trainable_variables)self.optimizer_critic.apply_gradients(zip(gradients_critic, self.critic.trainable_variables))# 训练代理env = gym.make('CartPole-v1')num_actions = env.action_space.nagent = ActorCriticAgent(num_actions)num_episodes = 500for episode in range(num_episodes):state = env.reset()total_reward = 0done = Falsewhile not done:action = agent.select_action(state)next_state, reward, done, _ = env.step(action)agent.train_step(state, action, reward, next_state, done)state = next_statetotal_reward += rewardprint(f"Episode {episode + 1}: Total Reward = {total_reward}")env.close()
Actor - Critic算法通过结合策略梯度算法和基于价值的方法,充分发挥了两者的优势。它减少了策略梯度估计的方差,提高了学习效率,并且可以处理连续动作空间。在实际应用中,Actor - Critic算法已经在许多领域取得了成功,如机器人控制、自动驾驶、游戏等。通过不断的研究和改进,Actor - Critic算法有望在更多复杂的强化学习任务中发挥更大的作用。