微信登录

策略梯度算法 - REINFORCE - 基于策略的学习

策略梯度算法 - REINFORCE - 基于策略的学习

一、引言

在强化学习领域,主要存在基于价值(Value - based)和基于策略(Policy - based)两种不同的学习方法。基于价值的方法,如 Q - learning,通过学习状态 - 动作对的价值函数来间接得到最优策略。而基于策略的方法则直接对策略进行参数化,并通过优化策略参数来最大化累积奖励。REINFORCE 算法作为策略梯度算法的经典代表,为基于策略的强化学习奠定了重要基础。

二、强化学习基础回顾

强化学习描述的是智能体(Agent)在环境中通过不断地与环境进行交互来学习最优行为策略的过程。智能体在每个时间步 $t$ 接收环境的状态 $st$,根据当前策略 $\pi$ 选择动作 $a_t$,环境根据智能体的动作转移到新的状态 $s{t + 1}$ 并给予智能体一个奖励 $rt$。智能体的目标是学习一个策略 $\pi$,使得在整个交互过程中累积的奖励最大化。累积奖励通常用折扣回报 $R_t=\sum{k = t}^{T}\gamma^{k - t}r_k$ 来表示,其中 $\gamma\in[0, 1]$ 是折扣因子,$T$ 是终止时间步。

三、基于策略的学习思想

基于策略的学习方法直接对策略进行参数化,通常将策略表示为 $\pi{\theta}(a|s)$,其中 $\theta$ 是策略的参数。例如,在连续动作空间中,$\pi{\theta}(a|s)$ 可以是一个高斯分布,$\theta$ 则是该分布的均值和方差等参数;在离散动作空间中,$\pi{\theta}(a|s)$ 可以是一个 softmax 函数输出的概率分布。基于策略的学习目标是找到一组最优的参数 $\theta^*$,使得智能体在环境中获得的期望折扣回报最大化,即:
J(\theta)=\mathbb{E}
{\tau\sim\pi_{\theta}}[R(\tau)]
其中 $\tau=(s_0,a_0,r_0,s_1,a_1,r_1,\cdots)$ 是一个完整的轨迹,$R(\tau)$ 是该轨迹的折扣回报。

四、REINFORCE 算法原理

4.1 策略梯度定理

策略梯度定理给出了目标函数 $J(\theta)$ 关于参数 $\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)R_t\right]
该定理表明,策略梯度可以通过对轨迹上每个时间步的策略对数概率的梯度乘以该时间步之后的折扣回报进行求和,并取期望得到。

4.2 REINFORCE 算法推导

REINFORCE 算法使用蒙特卡罗方法来估计策略梯度。具体来说,通过与环境进行交互收集一系列的轨迹 ${\tau^1,\tau^2,\cdots,\tau^N}$,然后用这些轨迹的样本均值来近似策略梯度:
\nabla{\theta}J(\theta)\approx\frac{1}{N}\sum{i = 1}^{N}\sum{t = 0}^{T}\nabla{\theta}\log\pi_{\theta}(a_t^i|s_t^i)R_t^i
其中 $N$ 是轨迹的数量,$a_t^i$ 和 $s_t^i$ 分别是第 $i$ 条轨迹在时间步 $t$ 的动作和状态,$R_t^i$ 是第 $i$ 条轨迹在时间步 $t$ 之后的折扣回报。

得到策略梯度的估计值后,使用梯度上升法来更新策略参数:
\theta\leftarrow\theta+\alpha\nabla_{\theta}J(\theta)
其中 $\alpha$ 是学习率。

4.3 算法伪代码

  1. 初始化策略参数 $\theta$
  2. for 迭代次数 = 1 to M:
  3. 收集 N 条轨迹 $\{\tau^1,\tau^2,\cdots,\tau^N\}$
  4. 对于每条轨迹 $\tau^i$:
  5. 计算每个时间步 $t$ 的折扣回报 $R_t^i$
  6. 计算策略梯度估计值 $\nabla_{\theta}J(\theta)\approx\frac{1}{N}\sum_{i = 1}^{N}\sum_{t = 0}^{T}\nabla_{\theta}\log\pi_{\theta}(a_t^i|s_t^i)R_t^i$
  7. 更新策略参数 $\theta\leftarrow\theta+\alpha\nabla_{\theta}J(\theta)$

五、使用 TensorFlow 实现 REINFORCE 算法

以下是一个使用 TensorFlow 实现 REINFORCE 算法解决 CartPole 环境问题的简单示例:

  1. import tensorflow as tf
  2. import numpy as np
  3. import gym
  4. # 创建 CartPole 环境
  5. env = gym.make('CartPole-v1')
  6. state_dim = env.observation_space.shape[0]
  7. action_dim = env.action_space.n
  8. # 定义策略网络
  9. model = tf.keras.Sequential([
  10. tf.keras.layers.Dense(64, activation='relu', input_shape=(state_dim,)),
  11. tf.keras.layers.Dense(action_dim, activation='softmax')
  12. ])
  13. # 定义优化器
  14. optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
  15. # 定义折扣因子
  16. gamma = 0.99
  17. def run_episode():
  18. states, actions, rewards = [], [], []
  19. state = env.reset()
  20. done = False
  21. while not done:
  22. state = np.expand_dims(state, axis=0)
  23. action_probs = model(state)
  24. action = np.random.choice(action_dim, p=action_probs.numpy()[0])
  25. next_state, reward, done, _ = env.step(action)
  26. states.append(state)
  27. actions.append(action)
  28. rewards.append(reward)
  29. state = next_state
  30. return states, actions, rewards
  31. def compute_discounted_rewards(rewards):
  32. discounted_rewards = []
  33. running_total = 0
  34. for r in reversed(rewards):
  35. running_total = r + gamma * running_total
  36. discounted_rewards.insert(0, running_total)
  37. return discounted_rewards
  38. def train_step():
  39. states, actions, rewards = run_episode()
  40. discounted_rewards = compute_discounted_rewards(rewards)
  41. discounted_rewards = np.array(discounted_rewards)
  42. discounted_rewards = (discounted_rewards - np.mean(discounted_rewards)) / (np.std(discounted_rewards) + 1e-7)
  43. with tf.GradientTape() as tape:
  44. loss = 0
  45. for state, action, disc_reward in zip(states, actions, discounted_rewards):
  46. state = tf.convert_to_tensor(state, dtype=tf.float32)
  47. action_probs = model(state)
  48. log_prob = tf.math.log(action_probs[0, action])
  49. loss += -log_prob * disc_reward
  50. gradients = tape.gradient(loss, model.trainable_variables)
  51. optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  52. # 训练过程
  53. num_episodes = 1000
  54. for episode in range(num_episodes):
  55. train_step()
  56. if episode % 100 == 0:
  57. print(f"Episode {episode} completed.")
  58. env.close()

代码解释

  1. 策略网络定义:使用 tf.keras.Sequential 定义一个简单的全连接神经网络作为策略网络,输入是环境状态,输出是每个动作的概率。
  2. 轨迹收集run_episode 函数用于与环境进行交互,收集一个完整轨迹的状态、动作和奖励。
  3. 折扣回报计算compute_discounted_rewards 函数根据收集到的奖励计算每个时间步的折扣回报。
  4. 训练步骤train_step 函数计算策略梯度并更新策略网络的参数。

六、REINFORCE 算法的优缺点

6.1 优点

  • 直接优化策略:直接对策略进行参数化和优化,避免了基于价值方法中值函数估计不准确的问题,尤其适用于连续动作空间。
  • 探索能力强:策略网络输出的是动作的概率分布,天然具有探索能力。

6.2 缺点

  • 高方差:使用蒙特卡罗方法估计策略梯度会导致梯度估计的方差较大,训练过程不稳定,收敛速度慢。
  • 样本效率低:需要大量的轨迹样本来准确估计策略梯度,样本效率较低。

七、总结

REINFORCE 算法作为策略梯度算法的基础,为基于策略的强化学习提供了重要的理论和实践基础。尽管它存在一些缺点,但后续的许多策略梯度算法,如 Actor - Critic 算法、A2C、A3C 等,都是在 REINFORCE 算法的基础上进行改进和优化的。通过不断地研究和改进,基于策略的强化学习方法在机器人控制、自动驾驶、游戏等领域取得了广泛的应用。

策略梯度算法 - REINFORCE - 基于策略的学习