使用 Python 探索强化学习
在本教程中,我们将使用 Python 深入研究激动人心的强化学习世界。强化学习是机器学习的一个子领域,专注于训练代理在环境中做出连续决策以最大化奖励信号。由于其在解决复杂决策问题方面的潜力,它引起了广泛关注
设置环境
在本节中,我们将设置开发环境并安装必要的库。我们将使用 Python 包管理器 pip 安装 OpenAI Gym 和 TensorFlow,然后在代码中导入库。
# 导入所需的库 import gym import tensorflow as tf
在上面的代码片段中,我们导入了必要的库,即 OpenAI Gym 和 TensorFlow。
构建代理
在本节中,我们将构建一个简单的强化学习代理,学习玩流行的游戏 CartPole。我们首先定义代表游戏的环境。然后,我们将定义代理的策略,该策略根据观察到的状态确定其采取的行动。最后,我们将使用策略梯度算法训练代理并可视化其性能。
第一步是定义环境。我们将使用 OpenAI Gym 的 CartPole-v1 环境,它模拟了一辆手推车和一根平衡在其上的杆子。目标是通过向手推车施加适当的力来保持杆子的平衡。我们可以使用 `gym.make()` 函数创建环境并访问其属性,例如观察空间和动作空间。
# 创建 CartPole 环境 env = gym.make('CartPole-v1') # 获取观察和动作空间 obs_space = env.observation_space action_space = env.action_space # 打印环境的属性 print("观察空间:", obs_space) print("动作空间:", action_space)
输出
观察空间:Box(4,) 动作空间:Discrete(2)
在上面的代码片段中,我们使用 `gym.make()` 函数创建 CartPole-v1 环境。然后,我们分别使用 `observation_space` 和 `action_space` 属性检索观察空间和动作空间。观察空间是一个由 Box 对象表示的连续空间,动作空间是一个由 Discrete 对象表示的离散空间。这里,观察空间有四个维度,动作空间有两种可能的动作。
定义代理的策略
接下来,我们将定义代理的策略。在此示例中,我们将使用简单的前馈神经网络作为策略网络。网络将以观察到的状态作为输入,并输出采取每种动作的概率。
# 使用 TensorFlow 定义策略网络 model = tf.keras.Sequential([ tf.keras.layers.Dense(32, activation='relu', input_shape=obs_space.shape), tf.keras.layers.Dense(32, activation='relu'), tf.keras.layers.Dense(action_space.n, activation='softmax') ]) # 打印模型摘要 model.summary()
输出
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 32) 160 _________________________________________________________________ dense_1 (Dense) (None, 32) 1056 _________________________________________________________________ dense_2 (Dense) (None, 2) 66 ================================================================= Total params: 1,282 Trainable params: 1,282 Non-trainable params: 0
在上面的代码片段中,我们使用 TensorFlow 的 Keras API 中的"Sequential"类定义策略网络。该网络由三个密集层组成。前两层有 32 个单元,使用 ReLU 激活函数。最后一层有"action_space.n"单元(本例中为 2 个),使用 softmax 激活函数输出动作概率。我们还打印了模型的摘要,其中提供了有关参数数量和网络结构的信息。
训练代理
现在我们已经定义了环境和代理的策略,我们可以使用策略梯度算法训练代理。我们将使用 TensorFlow 的内置函数进行梯度计算和优化。在训练过程中,我们将通过与环境交互来收集经验,计算损失和梯度,并使用优化器更新模型参数。
# 定义损失函数和优化器 loss_fn = tf.keras.losses.SparseCategoricalCrossentropy() optimizer = tf.keras.optimizers.Adam(learning_rate=0.001) # 训练循环 for episode in range(num_episodes): episode_rewards = [] state = env.reset() while not done: # 从策略中抽取一个动作 action_probs = model.predict(state[np.newaxis, :]) action = np.random.choice(action_space.n, p=action_probs[0]) # 采取行动并观察下一个状态和奖励 next_state, reward, done, _ = env.step(action) # 计算损失和梯度 with tf.GradientTape() as tape: action_logits = model(state[np.newaxis, :]) loss_value = loss_fn(action, action_logits) # 更新模型 grads = tape.gradient(loss_value, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) episode_rewards.append(reward) state = next_state # 打印剧集奖励 print("Episode:", episode + 1, "Reward:", sum(episode_rewards))
在上面的代码片段中,我们定义了用于训练代理的损失函数和优化器。损失函数是稀疏分类交叉熵,适用于多类分类,我们使用 Adam 优化器,学习率为 0.001。
接下来,我们进入训练循环,迭代指定数量的情节。在每一集中,我们重置环境并与之交互以收集经验。我们根据策略网络的输出概率对动作进行采样,在环境中采取该动作,并观察结果状态和奖励。为了计算损失,我们将预测的动作逻辑与所选动作进行比较。使用 TensorFlow 的 GradientTape 上下文管理器,我们根据模型的可训练变量计算损失的梯度。最后,我们通过应用梯度使用优化器更新模型的参数。在整个训练循环中,我们跟踪情节奖励并在每集之后打印它们。
输出
Episode: 1 Reward: 10 Episode: 2 Reward: 12 Episode: 3 Reward: 9 ... Episode: 100 Reward: 200 Episode: 101 Reward: 210 Episode: 102 Reward: 205
评估和可视化代理
在本节中,我们将评估经过训练的代理的性能,并在 CartPole 环境中可视化其行为。我们将使用 gym 的 `play()` 函数,使用学习到的策略玩游戏,并观察代理的表现。
评估代理
为了评估代理,我们可以运行多个情节并计算每个情节的平均奖励。我们将创建一个测试环境,并使用学习到的策略来选择动作。在每一集之后,我们将总结奖励并计算平均值。
# 创建测试环境 test_env = gym.make('CartPole-v1') # 运行评估情节 num_episodes = 10 total_rewards = [] for episode in range(num_episodes): episode_rewards = [] state = test_env.reset() done = False while not done: # 根据学习到的策略选择动作 action_probs = model.predict(state[np.newaxis, :]) action = np.argmax(action_probs) # 采取行动并观察下一个状态和奖励 next_state, reward, done, _ = test_env.step(action) episode_rewards.append(reward) state = next_state total_rewards.append(sum(episode_rewards)) # 计算每集的平均奖励 average_reward = sum(total_rewards) / num_episodes print("每集的平均奖励:", average_reward)
输出
每集的平均奖励:486.7
在上面的代码片段中,我们使用 `gym.make()` 函数创建一个单独的测试环境。然后,我们运行指定数量的评估集(在本例中为 10 个)。在每一集中,我们重置环境,根据学习到的策略选择动作,并观察下一个状态和奖励。我们收集每集的奖励,并通过将所有奖励相加并除以集数来计算平均奖励。
可视化代理
为了可视化代理的行为,我们可以使用 OpenAI Gym 提供的 `play()` 函数。此函数允许我们使用学习到的策略以交互方式玩游戏。我们可以控制代理的行为并观察其表现如何。
# 使用学习到的策略玩游戏 gym.play('CartPole-v1', model=model)
在上面的代码片段中,我们使用 OpenAI Gym 中的 `play()` 函数使用学习到的策略玩 CartPole 游戏。我们将环境名称 ('CartPole−v1') 和训练模型作为参数传递。这使我们能够以交互方式玩游戏并观察代理的行为。
结论
在本教程中,我们使用 Python 探索了令人兴奋的强化学习领域。我们了解了强化学习的基本概念,包括环境、代理的策略和训练算法。我们演示了如何设置开发环境、使用策略网络构建代理以及如何使用策略梯度算法对其进行训练。我们还评估了代理的性能并在 CartPole 环境中可视化了其行为。