深度 Q 学习(DQN)是一种强化学习方法,用于在连续状态空间中学习最优策略。本文通过 PyTorch 介绍如何使用 DQN 在 CartPole-v1 环境中训练智能体。首先,设置环境并配置 ReplayMemory 来存储智能体与环境的交互。接着,构建 DQN 模型,结合神经网络拟合 Q 函数与经验回放池以提高学习效率和稳定性。最后,实现训练流程与评估,通过训练多个回合来优化智能体性能,并通过可视化奖励曲线评估学习效果。此教程为 DQN 在实际应用中的实践提供了一套完整指南。
强化学习(DQN)教程 — PyTorch教程 2.4.0+cu124
引入与任务目标
在本教程中,我们将基于PyTorch,使用深度Q学习(DQN)算法在CartPole-v1环境中训练一个智能体。CartPole任务是一个经典的强化学习问题,目标是在每次时间步长中根据推车和杆的状态选择向左或向右推动的动作,以维持杆不倒下。
环境配置与视觉化
首先,我们需要导入所需的包,并创建环境:
import gymnasium as gym
env = gym.make("CartPole-v1")
为了直观理解环境的状态和动作空间,我们可以打印它们:
print("Observation Space:", env.observation_space)
print("Action Space:", env.action_space)
经验回放内存
为了训练DQN,我们需要一个经验回放内存来存储智能体与环境交互的转换。这将帮助我们避免过度拟合,并在训练过程中引入多样性和随机性。以下是 ReplayMemory
类的实现:
import random
class ReplayMemory:
def __init__(self, capacity):
self.capacity = capacity
self.memory = []
def push(self, state, action, reward, next_state, done):
self.memory.append((state, action, reward, next_state, done))
if len(self.memory) > self.capacity:
self.memory.pop(0)
def sample(self, batch_size):
return random.sample(self.memory, batch_size)
def __len__(self):
return len(self.memory)
模型构建与算法原理
接下来,构建DQN模型,并理解其背后的算法原理:
import torch
import torch.nn as nn
import torch.nn.functional as F
class DQN(nn.Module):
def __init__(self, input_size, output_size):
super(DQN, self).__init__()
self.fc1 = nn.Linear(input_size, 64)
self.fc2 = nn.Linear(64, 64)
self.fc3 = nn.Linear(64, output_size)
def forward(self, x):
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
return self.fc3(x)
理解算法原理:
- Q-learning:传统的方法,适用于离散状态与动作空间,但无法处理连续状态空间。
- 神经网络拟合Q函数(NFQ):通过神经网络拟合Q函数,用于估计连续状态空间下每个动作的期望回报。
- DQN:结合了上述两种方法,使用神经网络拟合Q函数,并引入经验回放池,提高了学习效率和稳定性。
训练与评估
最后,我们将实现DQN的训练流程,并评估智能体的表现:
class Agent:
def __init__(self, state_size, action_size, device):
self.state_size = state_size
self.action_size = action_size
self.device = device
self.q_network = DQN(state_size, action_size).to(device)
self.optimizer = torch.optim.Adam(self.q_network.parameters(), lr=0.001)
def act(self, state):
state = torch.tensor(state, dtype=torch.float).unsqueeze(0).to(self.device)
return self.q_network(state).max(1)[1].item()
def learn(self, states, actions, rewards, next_states, dones):
states = torch.stack(states).to(self.device)
actions = torch.tensor(actions).to(self.device)
rewards = torch.tensor(rewards).to(self.device)
next_states = torch.stack(next_states).to(self.device)
dones = torch.tensor(dones).to(self.device)
q_values = self.q_network(states).gather(1, actions.unsqueeze(-1)).squeeze(-1)
next_q_values = self.q_network(next_states).max(1)[0].detach()
targets = rewards + (1 - dones) * 0.99 * next_q_values
loss = torch.mean((q_values - targets) ** 2)
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
return loss.item()
def train_dqn(agent, num_episodes, memory, batch_size):
rewards = []
for episode in range(num_episodes):
state, _ = env.reset()
state = torch.tensor(state, dtype=torch.float).unsqueeze(0)
done = False
total_reward = 0
while not done:
action = agent.act(state)
next_state, reward, done, _, _ = env.step(action)
next_state = torch.tensor(next_state, dtype=torch.float).unsqueeze(0)
memory.push(state, action, reward, next_state, done)
state = next_state
total_reward += reward
if len(memory) > batch_size:
states, actions, rewards, next_states, dones = memory.sample(batch_size)
loss = agent.learn(states, actions, rewards, next_states, dones)
rewards.append(total_reward)
return rewards
环境与模型实例化
import numpy as np
n_observations = env.observation_space.shape[0]
n_actions = env.action_space.n
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
agent = Agent(n_observations, n_actions, device)
memory = ReplayMemory(10000)
训练与评估模型
num_episodes = 500
batch_size = 32
rewards = train_dqn(agent, num_episodes, memory, batch_size)
结论
通过上述步骤,我们构建了一个基于PyTorch的DQN模型,用于在CartPole-v1环境中训练智能体。训练结束后,我们可以使用评估函数来测试智能体的性能,并可视化奖励曲线以理解学习进程。
实践示例
要运行完整代码,请确保已经安装了gymnasium
和torch
包。在本地环境中,确保已安装好上述库,并按照上述代码块逐步执行每个操作。如果在云平台或在线IDE中运行,确保所有依赖包已正确安装。
代码下载
代码和更多资源可以从 GitHub 或其他开源平台下载获取,以便于本地实验和学习。建议访问官方文档或相关社区论坛,获取详细的代码实现和更多教程资源。
共同學習,寫下你的評論
評論加載中...
作者其他優質文章