使用 Python 探索强化学习

pythonserver side programmingprogramming

在本教程中,我们将使用 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 环境中可视化了其行为。


相关文章