尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
DQN 算法 PyTorch 2.0 实战:CartPole-v1 环境 200 分训练完整代码
DQN算法PyTorch 2.0实战从零实现CartPole-v1智能控制深度强化学习正在重塑我们解决复杂决策问题的方式。想象一下一个完全自主的AI系统能够在几小时内掌握人类需要数月才能精通的技能——这正是深度Q网络(DQN)展现出的惊人潜力。本文将带您从零开始使用PyTorch 2.0框架构建一个完整的DQN智能体并训练它在经典的CartPole-v1环境中达到200分的完美表现。1. 环境准备与问题定义CartPole-v1是OpenAI Gym中最具代表性的控制问题之一。这个环境模拟了一个小车上的倒立摆系统智能体需要通过左右移动小车来保持杆子竖直不倒。状态空间包含4个连续变量小车位置(x)小车速度(v)杆子角度(θ)杆子角速度(ω)动作空间则是离散的向左施加力(0)或向右施加力(1)。当杆子倾斜超过15度、小车移动超出2.4个单位距离或者持续200个时间步时回合结束。import gym import torch import numpy as np from collections import deque import random import matplotlib.pyplot as plt # 创建环境 env gym.make(CartPole-v1) state_dim env.observation_space.shape[0] # 4 action_dim env.action_space.n # 2 print(f状态空间维度: {state_dim}, 动作空间维度: {action_dim})提示PyTorch 2.0引入了torch.compile()等新特性可以显著提升神经网络训练速度。在后续代码中我们会充分利用这些新功能。2. DQN核心组件实现2.1 Q网络架构设计我们的Q网络采用三层全连接结构使用ReLU激活函数。网络输入是4维状态向量输出是2个动作对应的Q值。import torch.nn as nn import torch.nn.functional as F class QNetwork(nn.Module): def __init__(self, state_size, action_size, seed42): super(QNetwork, self).__init__() self.seed torch.manual_seed(seed) self.fc1 nn.Linear(state_size, 64) self.fc2 nn.Linear(64, 64) self.fc3 nn.Linear(64, action_size) # 使用PyTorch 2.0的编译功能 self.compiled_forward torch.compile(self._forward) def _forward(self, x): x F.relu(self.fc1(x)) x F.relu(self.fc2(x)) return self.fc3(x) def forward(self, x): return self.compiled_forward(x)2.2 经验回放缓冲区经验回放是DQN稳定训练的关键技术它通过存储和随机采样过去的经验来打破数据间的相关性。class ReplayBuffer: def __init__(self, buffer_size, batch_size, devicecpu): self.memory deque(maxlenbuffer_size) self.batch_size batch_size self.device device def add(self, state, action, reward, next_state, done): self.memory.append((state, action, reward, next_state, done)) def sample(self): experiences random.sample(self.memory, kself.batch_size) states torch.tensor( np.array([e[0] for e in experiences]), dtypetorch.float32, deviceself.device ) actions torch.tensor( np.array([e[1] for e in experiences]), dtypetorch.long, deviceself.device ) rewards torch.tensor( np.array([e[2] for e in experiences]), dtypetorch.float32, deviceself.device ) next_states torch.tensor( np.array([e[3] for e in experiences]), dtypetorch.float32, deviceself.device ) dones torch.tensor( np.array([e[4] for e in experiences]), dtypetorch.float32, deviceself.device ) return (states, actions, rewards, next_states, dones) def __len__(self): return len(self.memory)2.3 ε-贪心策略探索-利用权衡是强化学习的核心挑战。我们使用ε-贪心策略随着训练逐步降低探索率。class EpsilonGreedy: def __init__(self, start1.0, end0.01, decay0.995): self.start start self.end end self.decay decay self.epsilon start def get_action(self, q_values, trainingTrue): if training and random.random() self.epsilon: return random.randint(0, len(q_values)-1) return torch.argmax(q_values).item() def update(self): self.epsilon max(self.end, self.epsilon * self.decay)3. 完整训练流程实现3.1 超参数配置合理的超参数对训练成功至关重要。以下是经过调优的参数设置参数值说明BUFFER_SIZE100000经验回放缓冲区大小BATCH_SIZE64每次训练的样本数GAMMA0.99未来奖励折扣因子TAU1e-3目标网络软更新系数LR1e-3学习率UPDATE_EVERY4网络更新频率EPS_START1.0初始探索率EPS_END0.01最小探索率EPS_DECAY0.995探索率衰减率# 初始化组件 device torch.device(cuda if torch.cuda.is_available() else cpu) policy_net QNetwork(state_dim, action_dim).to(device) target_net QNetwork(state_dim, action_dim).to(device) target_net.load_state_dict(policy_net.state_dict()) target_net.eval() optimizer torch.optim.Adam(policy_net.parameters(), lr1e-3) memory ReplayBuffer(100000, 64, device) epsilon EpsilonGreedy(1.0, 0.01, 0.995)3.2 训练循环实现训练过程分为以下几个关键步骤与环境交互收集经验从回放缓冲区采样计算当前Q值和目标Q值计算损失并更新网络定期同步目标网络def train(n_episodes500, max_t1000): scores [] scores_window deque(maxlen100) for i_episode in range(1, n_episodes1): state env.reset() score 0 for t in range(max_t): # 选择并执行动作 state_tensor torch.tensor(state, dtypetorch.float32).unsqueeze(0).to(device) q_values policy_net(state_tensor) action epsilon.get_action(q_values) next_state, reward, done, _ env.step(action) # 存储经验 memory.add(state, action, reward, next_state, done) state next_state score reward # 学习阶段 if len(memory) memory.batch_size: experiences memory.sample() states, actions, rewards, next_states, dones experiences # 计算当前Q值 current_q policy_net(states).gather(1, actions.unsqueeze(1)) # 计算目标Q值 next_q target_net(next_states).max(1)[0].detach() target_q rewards (GAMMA * next_q * (1 - dones)) # 计算损失并更新 loss F.mse_loss(current_q.squeeze(), target_q) optimizer.zero_grad() loss.backward() optimizer.step() # 更新探索率 epsilon.update() # 软更新目标网络 for target_param, policy_param in zip(target_net.parameters(), policy_net.parameters()): target_param.data.copy_(TAU*policy_param.data (1.0-TAU)*target_param.data) if done: break scores.append(score) scores_window.append(score) print(f\rEpisode {i_episode}\tAverage Score: {np.mean(scores_window):.2f}, end) if i_episode % 100 0: print(f\rEpisode {i_episode}\tAverage Score: {np.mean(scores_window):.2f}) if np.mean(scores_window) 200.0: print(f\nEnvironment solved in {i_episode-100} episodes!) torch.save(policy_net.state_dict(), dqn_model.pth) break return scores3.3 训练结果可视化训练完成后我们可以绘制奖励曲线来观察学习过程scores train() # 绘制训练曲线 plt.figure(figsize(10,5)) plt.plot(np.arange(len(scores)), scores) plt.ylabel(Score) plt.xlabel(Episode #) plt.title(DQN Training Progress on CartPole-v1) plt.show()典型训练曲线会显示分数从随机水平(20-30)逐步提升到稳定的200分。当连续100轮平均分达到200时我们认为问题已解决。4. 高级技巧与优化建议4.1 目标网络更新策略对比目标网络的更新方式直接影响训练稳定性。以下是三种常见策略的比较更新策略优点缺点硬更新(周期同步)实现简单可能导致训练不稳定软更新(每次小步更新)训练稳定收敛可能较慢混合更新平衡稳定性和速度需要调参我们的实现采用了软更新方式通过TAU参数控制更新幅度。4.2 探索策略优化除了基本的ε衰减策略还可以尝试以下高级探索技术自适应ε调整根据学习进度动态调整衰减率噪声网络在网络参数中注入噪声进行探索好奇心驱动添加内在奖励鼓励探索新状态# 自适应ε衰减示例 class AdaptiveEpsilon(EpsilonGreedy): def update(self, score): # 当表现提升时减缓衰减 if score self.last_score: self.decay min(0.999, self.decay * 1.01) else: self.decay max(0.9, self.decay * 0.99) self.last_score score super().update()4.3 性能优化技巧利用PyTorch 2.0的新特性可以进一步提升训练效率# 启用PyTorch 2.0的编译和自动混合精度 policy_net torch.compile(policy_net) target_net torch.compile(target_net) scaler torch.cuda.amp.GradScaler() # 自动混合精度 # 在训练循环中使用 with torch.cuda.amp.autocast(): current_q policy_net(states).gather(1, actions.unsqueeze(1)) next_q target_net(next_states).max(1)[0].detach() target_q rewards (GAMMA * next_q * (1 - dones)) loss F.mse_loss(current_q.squeeze(), target_q) optimizer.zero_grad() scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()在实际测试中这些优化可以使训练速度提升2-3倍特别是在GPU环境下。
RELATED

相关推荐

设备检测环境

设备检测环境

搞了些时间,自行修改系统,基本上也能过掉检测器的检测:感觉这玩意也不是那么容易搞

📅 2026/11/4 1:18:29
2026半年度总结

2026半年度总结

写在前面 2026年已经过半,半年报也在编写中了 啦!回望2026年写下的KPI,很多都被所谓的【紧急】给被迫搁浅。 整个部门的人的感觉就是一种都在备受煎熬无形压力。 虽然感觉一直在做事,但从来没有看到一个稳定的结果能够拿出来呈现。…

📅 2026/11/4 1:18:40
TC78H651AFNG与MK64FN1M0VDC12的直流有刷电机驱动方案解析

TC78H651AFNG与MK64FN1M0VDC12的直流有刷电机驱动方案解析

1. 下一代直流有刷驱动器的技术背景与市场需求在工业自动化和消费电子领域,直流有刷电机因其结构简单、控制方便、成本低廉等优势,仍然是许多应用场景的首选驱动方案。但随着终端设备对能效、体积和智能化要求的不断提高,传统分立式驱动方案已…

📅 2026/11/4 1:53:44
MORE NEWS

更多资讯

📰

MsCtfMonitor.dll文件在Windows系统中出现错误解决办法

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

📰

【维克】均值回归型CTA:期货的“弹簧效应“

"反者道之动,弱者道之用。"——《道德经第四十章》老子两千多年前就看透了:事物走到极点必然向反面运动。价格也一样——涨到离谱就会往回走;跌到离谱就会弹回来。这根"看不见的弹簧"就是均值回归的全部秘密。那个"…

📰

锂电池化成分容测试系统精度评估:指标定义、通道验证与数据追溯

一、问题背景在锂电池制造过程中,化成分容测试系统需要按照规定的工艺流程执行充放电控制,并记录电压、电流、时间及相关测试结果。对于设备工程师和工艺工程师而言,如何评估测试系统的测量能力,是设备选型、验收和后续维护中的重…

📰

《面包板电子制作 130 例》阅读笔记 1

《面包板电子制作 130 例》阅读笔记 第一章 元器件基础 第二节 面包板介绍 面包板是一种实验板,可以将常规电子元器件直接插入,搭接出各种实验电路。 常见的面包板有 130 线、120 线、46 线等多种规格。 本书的实验都采用 130 线规格的面包板&#xff0c…

📰

Codex CLI v0.166 更新:键盘流操作

不知道你们有没有经历过这种反人类的折磨: 你在终端里让 Codex 帮你生成了一段两百行的复杂代码,或者一大段极其精彩的排错思路。你心想:“这段我得复制下来,贴到 PR 描述或者 Notion 里。” 于是,你的右手离开了键盘&…

📰

基于multisim的简易数字电压表电路设计

任务要求: 简易数字电压表是采用数字化测量设计的电压仪表。在现代检测技术中,常需用数字电压表进行现场检测。该数字电压表通过完成电压采集、信号转换、存储、控制等电路,实现电压测量功能,并将测量结果通过显示电路进行显示。 …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬