手记

强化学习入门:使用 TorchRL 和 PyTorch 实现 PPO 算法


引入与背景

强化学习是机器学习的重要分支,旨在通过与环境的交互来学习最优策略。TorchRL 是一个用于强化学习的 PyTorch 库,提供了一种直观的方式来定义环境、构建策略和价值函数,以及优化策略。近端策略优化 (PPO) 是一种流行的策略梯度方法,它允许在在线环境下学习策略,同时通过近端约束来减少策略的不稳定性和收敛速度。

前置依赖与环境设置

首先,确保安装了必要的依赖库:

pip install torchrl
pip install gym[mujoco]
pip install tqdm

接下来,在 Google Colab 或本地环境中运行以下代码以设置环境:

import torch

# 确保使用 GPU 进行计算(如果可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 引入所需的 TorchRL 和 PyTorch 模块
from torchrl.collectors import SyncDataCollector
from torchrl.data.replay_buffers import ReplayBuffer
from torchrl.environments import TransformedEnv, GymEnv, DoubleToFloat, ObservationNorm, StepCounter
from torchrl.envs.libs.gym import GymEnv
from torchrl.objectives import ClipPPOLoss
from torchrl.modules import ProbabilisticActor, TanhNormal, ValueOperator
from torchrl.objectives.value import GAE
from torch.nn import functional as F
from torch.optim import Adam
from torch.optim.lr_scheduler import CosineAnnealingLR
from torchrl.utils import check_env_specs
from tqdm.auto import tqdm
import numpy as np
import gymnasium as gym

环境与数据收集器构建

使用 Gymnasium 创建环境,并配置必要的转换器:

# 创建 Gym 环境
env_name = "CartPole-v1"  # 示例环境名称
env = GymEnv(env_name)

# 添加转换器
env = TransformedEnv(
    env,
    transforms=[
        DoubleToFloat(),
        ObservationNorm(),
        StepCounter()
    ]
)

# 检查环境规范
check_env_specs(env)

在环境中运行随机动作并进行归一化训练:

# 运行一些随机动作以收集环境统计数据
num_iter = 1000
for _ in range(num_iter):
    obs, info = env.reset()
    for _ in range(1000):
        action = env.action_space.sample()  # 随机动作
        next_obs, reward, terminated, truncated, info = env.step(action)
        env.close()

env.transform[0].init_stats(num_iter=1000, reduce_dim=0, cat_dim=0)

策略与价值函数设计

设计策略和价值函数:

# 策略网络
class MLPActor(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(MLPActor, self).__init__()
        self.fc1 = nn.Linear(input_dim, 256)
        self.fc2 = nn.Linear(256, 256)
        self.fc3 = nn.Linear(256, output_dim)

    def forward(self, observation):
        x = F.relu(self.fc1(observation))
        x = F.relu(self.fc2(x))
        action_mean = self.fc3(x)
        return action_mean

# 值函数网络
class MLPValue(nn.Module):
    def __init__(self, input_dim):
        super(MLPValue, self).__init__()
        self.fc1 = nn.Linear(input_dim, 256)
        self.fc2 = nn.Linear(256, 256)
        self.fc3 = nn.Linear(256, 1)

    def forward(self, observation):
        x = F.relu(self.fc1(observation))
        x = F.relu(self.fc2(x))
        value = self.fc3(x)
        return value

# 创建策略和价值函数实例
actor_net = MLPActor(env.observation_space.shape[0], env.action_space.shape[0])
critic_net = MLPValue(env.observation_space.shape[0])

# 将策略和价值函数与 TorchRL 兼容
actor_module = ProbabilisticActor(
    module=actor_net,
    spec=env.action_space,
    in_keys=["observation"],
    distribution_class=TanhNormal,
)
critic_module = ValueOperator(
    module=critic_net,
    in_keys=["observation"],
)

损失函数与训练循环

定义 PPO 损失并配置训练循环:

# 定义 GAE 模块
gae_module = GAE(gamma=0.99, lmbda=0.95, value_network=critic_module, average_gae=True)

# 创建张量字典损失模块
loss_module = ClipPPOLoss(
    actor_network=actor_module,
    critic_network=critic_module,
    clip_epsilon=0.2,
    entropy_bonus=True,
)
loss_module.to(device)

# 定义优化器
optimizer = torch.optim.Adam(loss_module.parameters(), lr=3e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, 100000, eta_min=0)

结果分析与评估

在训练循环期间,收集奖励和评估策略性能:

# 重置环境和策略模块
env.reset()

# 训练循环
n_episodes = 2000
for episode in range(n_episodes):
    # 在每轮开始时重置环境
    obs, _ = env.reset()

    # 训练循环
    for step in range(1000):  # 每个时间步长的游戏限制
        action = actor_module(obs)[0].argmax(dim=0)  # 选择动作
        next_obs, reward, done, _, _ = env.step(action)
        gae_module(obs)  # 计算 GAE 损失
        loss_module(obs)  # 计算 PPO 损失
        optimizer.step()
        obs = next_obs

        if done:
            break

    scheduler.step()

    # 评估策略
    test_rewards = []
    for _ in range(10):
        _, done = env.reset()
        episode_reward = 0
        while not done:
            action = actor_module(obs)[0].argmax(dim=0)
            obs, reward, done, _, _ = env.step(action)
            episode_reward += reward.item()
        test_rewards.append(episode_reward)
    print(f"Episode {episode+1}: Average Test Reward = {np.mean(test_rewards)}")

结论

通过本教程,我们深入了解了如何使用 TorchRL 和 PyTorch 实现 PPO 算法,并构建了一个完整的强化学习系统,从环境创建到策略优化。这个流程展示了如何将理论知识转化为实际代码,并通过实验评估策略的有效性。强化学习领域的实践和理论知识相结合,使得这种方法在自动化、游戏AI、机器人控制等领域具有广泛的应用前景。

0人推荐
随时随地看视频
慕课网APP