当前位置: 首页 > news >正文

月球着陆器DQN训练实战包:TensorFlow 2.10实现,含训练/测试/视频录制与预训练模型

本文还有配套的精品资源,点击获取

简介:直接运行就能上手的LunarLander强化学习项目,基于TensorFlow 2.10和Python开发,内置完整训练流程(Lunar_Lander.py)、独立测试验证脚本(Lunar_Lander_test.py)、封装好的工具函数(Lunar_Lander_utils.py)以及已训练好的DQN模型文件(lunar_lander_model.h5)。支持自动录制训练过程视频,输出到Lunar_Lander_videos目录,附带演示效果视频lunar_lander.mp4。requirements.txt列明全部依赖,环境配置简单,无需修改即可启动训练、评估和策略回放。代码模块划分清晰,适合作为DQN算法在连续控制任务中的教学范例或二次开发基础,也兼容PPO等其他主流RL算法的快速适配改造。

1. 项目概述:为什么这个 LunarLander DQN 实战包值得你花 15 分钟跑通一次

如果你刚学完 Q 网络的基本公式,却卡在“写完网络结构后不知道下一步该喂什么数据、怎么算 loss、reward 怎么回传”;或者你反复调参三天,训练曲线还是像心电图一样上下乱跳,最后 agent 在月球表面不是垂直砸坑里,就是横着翻滚着飞出画面——那你不是代码写错了,而是缺一个真正“能跑起来”的锚点。这个 LunarLander DQN 实战包,就是我过去三年带二十多届强化学习入门学员时,亲手打磨出来的那个“第一块踏脚石”。它不讲抽象的贝尔曼方程推导,也不堆砌最新论文里的 trick,而是把整个 DQN 训练闭环——从环境交互采样、经验回放缓冲区构建、目标网络软更新、ε-greedy 探索调度、到 loss 计算与梯度裁剪——全部封装进一个不到 400 行主逻辑的Lunar_Lander.py里。关键词LunarLander不是玩具,它是 OpenAI Gym 中少有的、同时具备连续动作空间(2D 推力+旋转)、稀疏奖励(只在着陆成功/坠毁/超界时给分)、强物理约束(重力、燃料、姿态动力学)的真实感控制任务;而DQN在这里也不是教科书里的离散动作模板,我们用双层全连接网络输出 4 个离散动作(左/右旋转 + 开/关引擎),再通过 action masking 技术屏蔽非法组合(比如“关引擎+左转”在悬停阶段其实无效),让算法真正学会在物理规则下做决策。TensorFlow2.10 的选择很务实:它稳定支持 Keras 高阶 API,避免 TF 1.x 的 session 管理混乱,又比 TF 2.15+ 新增的 eager mode 优化更轻量,实测在 RTX 3060 笔记本上单 episode 平均耗时 180ms,训练 2000 episode 只需 2 小时出头。你拿到手的不是一个 demo,而是一套可调试、可打断、可复现的完整工程骨架:lunar_lander_model.h5是我在 3 台不同配置机器上交叉验证过的收敛模型,测试得分稳定在 +240±15;Lunar_Lander_test.py不只是加载模型跑几轮,它内置了 5 种失败模式诊断(如 reward 泄露检测、动作震荡分析);连Lunar_Lander_videos目录下的每一段视频,都按 episode 编号+最终得分命名,方便你一眼定位“第 1872 轮为什么突然崩溃”。这不是让你复制粘贴的脚本,而是给你一把解剖刀——切开强化学习黑箱的第一刀,就从这个包开始。

2. 整体设计与思路拆解:为什么选 DQN 而不是 PPO?为什么坚持用 TensorFlow?

2.1 算法选型:DQN 是 LunarLander 的“最小可行解”,不是妥协

很多人看到 LunarLander 就默认上 PPO,觉得“连续控制当然用策略梯度”。但我在实际教学中发现,这种直觉恰恰是新手最大的认知陷阱。PPO 的优势在于高维连续动作(比如机械臂关节扭矩),而 LunarLander 的官方动作空间是离散的 4 维:[do_nothing, fire_left_engine, fire_right_engine, fire_main_engine]。强行用 PPO 建模连续动作不仅增加网络复杂度(需额外输出均值/方差),还会因动作空间膨胀导致探索效率暴跌——我试过用 PPO 直接输出[thrust_x, thrust_y, rotation],结果 agent 在前 500 episode 里 92% 的时间都在原地打转,因为随机采样连续值命中有效推力组合的概率太低。DQN 则天然匹配:4 个动作对应 4 个 Q 值输出,loss 计算直接明了(loss = (Q_target - Q_pred)^2),且能利用经验回放打破数据相关性。更重要的是,DQN 的训练过程是“可观察”的:你可以实时打印每个 batch 的 TD error 分布,当 error 从 12.7 降到 0.8 时,你知道网络正在收敛;而 PPO 的 clip ratio 和 entropy loss 往往需要结合 reward 曲线才能判断是否健康。这个包里所有 DQN 特有模块的设计,都服务于一个目标——让初学者能“看见”学习过程。比如Lunar_Lander_utils.py中的ExperienceReplayBuffer类,它不是简单存(s,a,r,s')元组,而是额外记录done_flagepisode_step,这样在计算 target Q 时,就能严格区分 terminal state(r + γ * max Q(s',a'))和非 terminal state(r + γ * max Q(s',a')),避免因s'是终止状态却错误叠加未来 reward 导致的 Q 值爆炸。再比如 ε-greedy 的衰减策略,我们没用简单的线性衰减,而是采用ε = ε_min + (ε_max - ε_min) * exp(-decay_rate * episode),因为指数衰减能让 agent 在早期快速探索(ε=1.0),中期聚焦优化(ε=0.3),后期精细微调(ε=0.05),实测比线性衰减早 300 episode 达到稳定策略。

2.2 框架选择:TensorFlow 2.10 的“稳”字诀,不是守旧

选择 TensorFlow 2.10 而非 PyTorch 或更新版 TF,是经过三轮硬件压测后的决定。PyTorch 的动态图确实灵活,但 LunarLander 的训练循环中存在大量重复张量操作(比如每 step 都要对 84×84 观测图像做归一化、resize、stack),PyTorch 的 eager mode 在 CPU 上会频繁触发内存分配,导致单 step 耗时波动达 ±40ms;而 TF 2.10 的@tf.function装饰器能将整个train_step()编译为静态图,在 RTX 4090 上实测平均耗时稳定在 112ms/step,标准差仅 3.2ms。更重要的是,TF 2.10 对 Keras Model 的保存/加载兼容性极佳——lunar_lander_model.h5文件在 Windows/Mac/Linux 三平台加载零报错,而 TF 2.15+ 的 SavedModel 格式在某些旧版 CUDA 驱动下会出现Failed to find dynamic library错误。这个包里的模型保存逻辑也做了双重保险:Lunar_Lander.py默认用model.save('lunar_lander_model.h5'),但Lunar_Lander_test.py同时支持tf.keras.models.load_model('lunar_lander_model.h5')tf.keras.models.load_model('lunar_lander_model')(SavedModel 格式),确保你即使手动导出新模型也能无缝接入。至于为什么不用 JAX?它的函数式编程范式对初学者门槛太高,一个jit编译错误往往需要查半小时文档,而这个包的核心价值是“降低启动成本”,不是炫技。

2.3 工程结构:模块化不是为了炫技,是为了让你改得明白

看目录树里那些文件名,别被.gitignore.inscode这类隐藏文件干扰,真正关键的只有四个 Python 文件。Lunar_Lander.py是心脏,但它只负责 orchestrating(编排):环境初始化、主训练循环、经验回放采样、网络训练、日志记录——所有具体实现都下沉到Lunar_Lander_utils.py。这个工具模块被我刻意设计成“无状态”:所有函数都是纯函数式,输入参数明确(比如compute_td_target(rewards, dones, next_q_values, gamma=0.99)),不依赖全局变量或类实例。这样做的好处是,当你想把 DQN 换成 Double DQN 时,只需修改compute_td_target函数里的一行代码(把max(next_q_values)换成next_q_values[np.argmax(q_values)]),其他逻辑完全不动。Lunar_Lander_test.py更是反套路设计:它不叫evaluate.py,因为“评估”这个词太模糊。它实际干三件事:一是加载模型后运行 100 个 episode 并统计成功率(着陆得分 > 200)、平均得分、最大连续成功轮次;二是生成诊断报告,比如检测是否存在 reward 泄露(某 episode 中 reward 总和远超理论最大值 300);三是自动录制视频,但视频命名规则是episode_1872_score_243.mp4,而不是test_run_001.mp4,这样你一眼就能知道哪段视频值得回看。这种命名哲学贯穿整个包——所有设计都指向一个目标:减少你的认知负荷,让你把精力集中在算法理解上,而不是 debug 环境配置。

3. 核心细节解析与实操要点:从环境观测到动作映射的每一处魔鬼细节

3.1 LunarLander 环境的“真实感”陷阱:观测向量到底包含什么?

很多教程说 LunarLander 的观测是 “8 维向量”,但没告诉你这 8 个数字背后藏着多少物理陷阱。打开gym.envs.box2d.lunar_lander.LunarLander源码,你会发现self.state实际返回的是一个 12 维数组,但我们只取前 8 维:[x, y, vx, vy, theta, vtheta, left_leg_contact, right_leg_contact]。这里的x,y是着陆器中心坐标(单位:米),vx,vy是速度(米/秒),theta是角度(弧度),vtheta是角速度(弧度/秒)。初学者常犯的错误是直接把这些原始值喂给网络——结果训练崩溃。为什么?因为x的范围是 [-1, 1],而vx的范围是 [-5, 5],theta是 [-π, π],数值尺度差异太大,导致梯度更新失衡。我们在Lunar_Lander_utils.pypreprocess_state(state)函数里做了四层标准化:第一层是物理量纲归一化(x /= 1.0,vx /= 5.0,theta /= np.pi);第二层是 Z-score 标准化(减均值除标准差,均值/标准差来自 1000 episode 的统计);第三层是 clipping(把超出 [-5, 5] 的值截断,防止异常值污染);第四层是添加小偏置(+ 1e-6)避免除零。这四步看似繁琐,但实测能让训练稳定性提升 3 倍——没有这一步,agent 在第 200 episode 就开始出现“抽搐式”动作(连续 5 步内疯狂切换左右引擎)。另一个魔鬼细节是left_leg_contactright_leg_contact:它们不是布尔值,而是浮点数(0.0 或 1.0),但 Gym 的 Box2D 物理引擎有时会返回 0.9999999 或 1.0000001,所以我们用np.round(contact, decimals=5)强制二值化。这个细节在Lunar_Lander_test.py的诊断模块里有专门检测:如果某 episode 中 contact 值出现非 0/1 的浮点数,会立即报警并跳过该 episode 的统计,避免污染评估结果。

3.2 DQN 动作空间的“合法化”设计:为什么不能直接用 4 个离散动作?

LunarLander 官方定义的动作空间确实是 4 个离散动作,但物理上并非所有组合都合理。比如在着陆器已触地(contact == [1,1])时,继续fire_main_engine会导致反冲起飞,这违反任务目标;又比如在高速下坠时fire_left_engine可能引发侧翻。如果我们不做任何约束,DQN 会学到“在触地瞬间猛推引擎以获取额外 reward”的作弊策略——这在训练时得分很高(+100),但实际部署会失败。因此,我们在Lunar_Lander_utils.pyget_valid_actions(state)函数中实现了动态动作掩码(action masking):根据当前statecontactvy值,实时计算哪些动作是物理合法的。具体逻辑是:若contact[0]==1 and contact[1]==1(双足着陆),则只允许do_nothing;若vy < -1.0(高速下坠),则禁止fire_left/right_engine(避免侧翻);否则开放全部 4 个动作。这个掩码不是加在 loss 计算里,而是在select_action()函数中直接过滤掉非法动作的 Q 值——即q_values[invalid_actions] = -np.inf,再用np.argmax(q_values)选择。这样做的好处是,网络依然学习所有动作的 Q 值,但决策时自动规避风险,相当于给 agent 装了一个“物理安全阀”。你在Lunar_Lander_test.py的诊断报告里能看到这个机制的效果:合法动作占比从无掩码时的 68% 提升到 99.2%,且所有失败 episode 中,92% 是因vy过大触发了引擎禁用,而非网络误判。

3.3 经验回放缓冲区的“冷热分离”策略:为什么不用 FIFO 而用优先级?

标准 DQN 用 FIFO(先进先出)缓冲区,但 LunarLander 的 reward 极其稀疏——1000 步里可能只有最后 3 步有非零 reward(着陆成功 +100,坠毁 -100,超界 -100)。如果用 FIFO,大量无 reward 的 transition 会淹没关键样本,导致学习缓慢。我们采用改进的优先级经验回放(Prioritized Experience Replay, PER),但做了轻量化处理:不引入复杂的 sum-tree 数据结构,而是用两个独立缓冲区——“热区”(hot_buffer)存最近 1000 个 transition,“冷区”(cold_buffer)存历史 transition。采样时,80% 概率从热区采样(保证新鲜经验),20% 从冷区采样(保留历史多样性)。热区的 transition 权重设为|td_error| + 1e-5,冷区权重固定为 1.0。这个设计在Lunar_Lander_utils.pysample_batch()函数里只有 12 行代码,却让 TD error 收敛速度提升 40%。更重要的是,我们给每个 transition 添加了priority字段,并在Lunar_Lander_test.py的诊断模块中输出热区/冷区的平均 TD error 对比——如果你看到热区 error 持续高于冷区,说明 agent 正在学习新知识;如果两者趋同,则可能进入平台期,需要调整 learning rate。

4. 实操过程与核心环节实现:从零运行到录制视频的完整链路

4.1 环境配置:requirements.txt 里的每一个依赖都有明确使命

不要跳过requirements.txt直接pip install -r requirements.txt,先打开文件看看这 7 行依赖的深意:

gym==0.26.2 box2d-py==2.3.5 tensorflow==2.10.0 numpy==1.23.5 opencv-python==4.8.0.76 matplotlib==3.7.1 Pillow==9.5.0

gym==0.26.2是关键版本锁:0.26.x 是最后一个支持gym.make('LunarLander-v2')且无需gymnasium迁移的版本,0.27+ 已废弃该环境;box2d-py==2.3.5必须匹配,因为 LunarLander 的物理引擎基于 Box2D,版本不一致会导致contact值计算错误(我踩过这个坑,现象是 agent 永远无法识别着陆);tensorflow==2.10.0前面已解释;opencv-python用于视频录制,但注意不是opencv-contrib-python(后者含冗余模块,安装慢且易冲突);matplotlib仅用于训练曲线绘图,Pillow用于图像预处理。安装时建议创建干净虚拟环境:python -m venv lunar_env && source lunar_env/bin/activate(Mac/Linux)或lunar_env\Scripts\activate.bat(Windows),然后逐行安装——特别是box2d-py,在 Windows 上需先装 Visual Studio Build Tools,否则编译失败。实测在 M1 Mac 上,pip install box2d-py会报clang: error: unsupported option '-fopenmp',解决方案是export OPENMP=0 && pip install box2d-py。这些细节都写在README.md的 Troubleshooting 小节里,但很多人懒得看,结果卡在第一步。

4.2 训练流程:Lunar_Lander.py 的 5 个核心阶段详解

运行python Lunar_Lander.py后,你会看到类似这样的输出:

[INFO] Episode 1 | Score: -152.3 | Epsilon: 1.000 | Buffer: 64/10000 [INFO] Episode 100 | Score: -42.7 | Epsilon: 0.923 | Buffer: 8240/10000 ... [INFO] Episode 2000 | Score: 243.1 | Epsilon: 0.050 | Buffer: 10000/10000

这背后是Lunar_Lander.py的五个精密咬合阶段:

阶段一:环境与网络初始化(第 1-50 行)
创建gym.make('LunarLander-v2')环境时,我们传入render_mode='rgb_array'(而非'human'),这是视频录制的前提;网络用 Keras Sequential 构建:Input(8) -> Dense(128, relu) -> Dense(128, relu) -> Dense(4),最后一层不加激活函数,因为 Q 值可正可负。特别注意target_network的初始化:不是随机权重,而是用main_network.get_weights()拷贝,确保初始 target Q 与 main Q 一致,避免训练初期 TD error 爆炸。

阶段二:主训练循环(第 51-200 行)
每个 episode 从env.reset()开始,state = preprocess_state(obs)处理观测。关键在for step in range(max_steps)循环内:先action = select_action(state, epsilon),再next_obs, reward, done, _ = env.step(action),然后next_state = preprocess_state(next_obs),最后buffer.add(state, action, reward, next_state, done)。这里有个易错点:done是布尔值,但buffer.add()需要int(done),否则在 NumPy 数组中会被转为 float,导致后续dones数组类型不一致。

阶段三:经验采样与训练(第 201-250 行)
每 4 步执行一次训练(if step % 4 == 0 and len(buffer) > batch_size:)。采样batch = buffer.sample(batch_size=64)后,用tf.GradientTape()计算 loss:with tf.GradientTape() as tape: q_pred = main_network(states); q_target = rewards + gamma * tf.reduce_max(target_network(next_states), axis=1) * (1 - dones); loss = tf.keras.losses.mse(q_target, tf.reduce_sum(q_pred * tf.one_hot(actions, 4), axis=1))。注意tf.one_hot(actions, 4)是关键——它把动作索引转为 one-hot 向量,再与q_pred点乘,只提取对应动作的 Q 值,避免错误计算所有动作的 loss。

阶段四:目标网络更新(第 251-260 行)
采用 soft update:target_weights = [tau * w1 + (1-tau) * w2 for w1, w2 in zip(main_network.weights, target_network.weights)]tau=0.001。相比 hard update(每 C 步全量拷贝),soft update 更平滑,实测能减少 15% 的训练震荡。

阶段五:日志与保存(第 261-300 行)
每 100 episode 保存一次模型(main_network.save('lunar_lander_model.h5')),并生成training_log.csv记录episode, score, epsilon, avg_td_error。这个 CSV 文件是调试神器——用 Excel 打开,画出score折线图,如果出现锯齿状波动,说明epsilon衰减太快;如果avg_td_error长期高于 5.0,可能是 learning rate 太大(默认 1e-3)。

4.3 视频录制:如何让 Lunar_Lander_videos 目录下的视频真正有价值?

Lunar_Lander_test.py的视频录制不是简单调用env.render(),而是深度集成到评估流程中。核心逻辑在record_episode_video()函数:先env = gym.make('LunarLander-v2', render_mode='rgb_array'),然后在每个 step 执行frame = env.render()(返回 numpy array),再用cv2.VideoWriter写入帧。但关键细节是帧率控制:LunarLander 的物理仿真步长是 1/50 秒,所以视频必须设为fps=50,否则播放时动作会变慢。我们用cv2.VideoWriter_fourcc(*'mp4v')编码,确保兼容性。更实用的是,视频录制时同步记录episode_scorefinal_state,并在视频末尾 2 秒叠加文字水印:“Score: 243 | Contact: [1,1] | Steps: 187”,这样你不用打开视频就能判断质量。Lunar_Lander_videos目录下的文件名规则是episode_{i}_score_{score:.1f}.mp4,其中score保留一位小数,避免243.000000这种冗余。附带的lunar_lander.mp4是第 1987 轮的录制,那一轮 agent 在触地前 0.3 秒精准关闭主引擎,实现了近乎完美的软着陆——这是我们特意挑选的“教科书案例”。

5. 常见问题与排查技巧实录:那些文档里不会写的血泪教训

5.1 训练不收敛的 5 种典型症状及根因定位

训练过程中最让人抓狂的不是报错,而是 reward 曲线毫无规律。根据我整理的 137 份学员训练日志,以下是高频问题速查表:

症状可能根因快速验证方法解决方案
Score 长期卡在 -150~-200ε-greedy 衰减过快,agent 过早放弃探索检查training_log.csvepsilon列,若第 100 轮已 < 0.3,则过快修改Lunar_Lander.py第 32 行EPSILON_DECAY = 0.9950.999
Score 在 -100 和 +100 间剧烈震荡Target network 更新频率不当,Q 值预测漂移查看training_log.csvavg_td_error,若波动 > 10.0,则不稳定TARGET_UPDATE_FREQ = 10005000,或改用 soft update(第 255 行)
前 500 轮 score 全为 0Observation 预处理错误,网络输入全为 0select_action()中打印state,检查是否全 0确认preprocess_state()中的np.clip()是否误删了有效值(第 87 行)
训练中途突然 crash,报CUDA out of memoryBatch size 过大,GPU 显存溢出运行nvidia-smi查看显存占用,若 > 95%,则溢出BATCH_SIZE = 6432(第 25 行),或改用 CPU 训练(注释掉tf.config.set_visible_devices([], 'GPU')
Video 录制为空白黑屏OpenCV 编码器不兼容,或帧尺寸错误检查record_episode_video()frame.shape,应为(600, 800, 3)确保env = gym.make(..., render_mode='rgb_array'),而非'human'

提示:所有验证方法都可在 2 分钟内完成,无需重启训练。比如检查epsilon,直接tail -n 10 training_log.csv即可。

5.2 模型加载失败的三大隐形杀手

Lunar_Lander_test.py加载lunar_lander_model.h5时报ValueError: Unknown layer: Functional?这不是模型损坏,而是 TensorFlow 版本错配。lunar_lander_model.h5是用 TF 2.10.0 保存的,如果你用 TF 2.15 加载,Keras 会尝试解析新版本的层类型。解决方案只有两个:降级 TF(pip install tensorflow==2.10.0),或用tf.keras.models.load_model('lunar_lander_model.h5', compile=False)跳过编译,再手动model.compile(optimizer='adam', loss='mse')。第二个杀手是路径问题:Lunar_Lander_test.py默认从当前目录加载模型,但如果你在src/子目录下运行,需修改第 15 行model_path = '../lunar_lander_model.h5'。第三个杀手最隐蔽——gym版本不一致。lunar_lander_model.h5是在gym==0.26.2下训练的,如果你用gym==0.27.0加载,env.observation_space.shape会变成(12,)而非(8,),导致model.predict()输入维度不匹配。此时Lunar_Lander_test.py的第 42 行assert state.shape == (8,)会抛出 AssertionError,提示你检查 gym 版本。

5.3 二次开发避坑指南:想换成 PPO?先改这 3 个接口

这个包的设计哲学是“最小改动适配新算法”。如果你想把 DQN 换成 PPO,不需要重写整个工程,只需修改三个接口:

第一,替换网络结构:在Lunar_Lander_utils.py中新建PPOActorCritic类,继承tf.keras.Model,输出actor_logits(4 维)和critic_value(1 维),替代原来的DQNNetwork

第二,重写训练逻辑:修改Lunar_Lander.py的训练循环,用PPOActorCritic替代main_network/target_network,loss 改为actor_loss + 0.5 * critic_loss - 0.01 * entropy,并加入 GAE(Generalized Advantage Estimation)计算。

第三,调整动作选择select_action()函数不再用argmax(Q),而是tf.random.categorical(actor_logits, 1)采样,并记录 log_prob 用于 PPO loss。

注意:PPO 的 batch size 应设为2048(而非 DQN 的64),因为 PPO 需要大 batch 估计 advantage。这些修改在Lunar_Lander_utils.pyppo_template.py示例中有完整注释,但被注释掉了——你只需取消注释并按提示修改即可。

6. 实战心得与延伸思考:从 LunarLander 到真实世界的跨越

跑通这个 LunarLander DQN 包,只是强化学习实践的起点,不是终点。我在带学员做项目时发现,真正拉开差距的,不是谁先跑出 +240 分,而是谁能在跑通后问出更尖锐的问题。比如,当你看着lunar_lander.mp4里 agent 完美着陆时,有没有想过:这个策略在真实月球上能用吗?答案是否定的——因为 LunarLander 环境的物理参数是简化的:重力恒为 1.0(月球实际是 1.62 m/s²),没有尘埃干扰,传感器无噪声。所以,我建议你在跑通后立刻做三件事:第一,在Lunar_Lander_utils.pypreprocess_state()里给state添加高斯噪声(state += np.random.normal(0, 0.01, state.shape)),观察 reward 曲线下降幅度,这就是鲁棒性测试;第二,修改env的重力参数(需 fork gym 源码),训练一个适应 1.62 重力的模型,对比迁移效果;第三,用Lunar_Lander_test.py的诊断模块分析动作序列,统计fire_main_engine的持续时间分布——如果 90% 的着陆都发生在 3~5 步内,说明策略过于激进,真实火箭需要更平缓的推力曲线。这些延伸不是炫技,而是把玩具任务拉回工程现实的锚点。最后分享一个小技巧:每次训练前,先用python Lunar_Lander_test.py --model_path lunar_lander_model.h5 --episodes 10快速验证模型,如果 10 轮里有 3 轮 score < 0,说明模型已退化,直接删掉重训,别浪费时间看训练曲线。强化学习没有银弹,但有清晰的反馈——你的 reward 就是最好的老师。

本文还有配套的精品资源,点击获取

简介:直接运行就能上手的LunarLander强化学习项目,基于TensorFlow 2.10和Python开发,内置完整训练流程(Lunar_Lander.py)、独立测试验证脚本(Lunar_Lander_test.py)、封装好的工具函数(Lunar_Lander_utils.py)以及已训练好的DQN模型文件(lunar_lander_model.h5)。支持自动录制训练过程视频,输出到Lunar_Lander_videos目录,附带演示效果视频lunar_lander.mp4。requirements.txt列明全部依赖,环境配置简单,无需修改即可启动训练、评估和策略回放。代码模块划分清晰,适合作为DQN算法在连续控制任务中的教学范例或二次开发基础,也兼容PPO等其他主流RL算法的快速适配改造。


本文还有配套的精品资源,点击获取

http://www.jsqmd.com/news/928701/

相关文章:

  • 深度解析:UABEA跨平台Unity资源处理工具的技术架构与实践
  • 手把手教你用THB6128驱动模块搞定两相四线步进电机(附PWM控制与细分设置避坑指南)
  • 2026宁波黄金回收优选|三十年老店收的顶,价透秤准变现无忧 - 奢侈品回收测评
  • 如何快速部署智慧树学习助手:3步实现高效自动化学习方案
  • 告别继电器!用MOS管给单片机做个‘电源开关’,实测电路与避坑指南
  • UE4本地多人游戏避坑指南:分屏模式下视口渲染异常、UI错位问题排查与修复
  • 2026年西北钢结构工程材料采购:宁夏源头工厂直供 vs 跨省物流踩坑全对比 - 优质企业观察收录
  • 保姆级教程:用tippecanoe和Mapbox GL JS把OSM数据变成可交互的矢量地图(附完整代码)
  • 2026南宁包包回收实地深度测评,添价收包包回收实测出圈 - 薛定谔的梨花猫
  • SCREME框架:内存可靠性技术的创新与优化
  • 别再手动K帧了!UE4 Sequence粒子系统批量控制与时间轴优化全攻略
  • S2.1触发设计:如何成为用户的默认选择
  • 哔哩下载姬:5步掌握B站视频下载的终极解决方案
  • 海投票教程:微信投票如何发起?新手快速上手方法 - 微信投票小程序
  • Vue项目里那个‘滚动到哪从哪开始’的炫酷效果,我是用@david-j/vue-j-scroll插件实现的
  • 告别netstat命令:图形化神器TCPView让你的Windows网络连接一目了然
  • TC264智能车实战:用逐飞库的PIT定时器和编码器实现精准速度闭环控制
  • 惠州本地黄金回收怎么选 避坑认准余生黄金回收连锁门店 - 余生黄金回收
  • 宝宝起名哪里好?五维命名法给出专业解决方案 - 速递信息
  • 碧蓝航线自动化脚本完整指南:如何让游戏自己运行24小时不间断?
  • Arm Compiler 6中RTTI机制解析与嵌入式优化实践
  • Cobimetinib考比替尼联合维莫非尼治疗BRAF V600E突变黑色素瘤效果
  • 2026 安徽蚌埠市(全区域服务)本地人必选彩钢瓦金属屋面防水防腐公司避坑指南 TOP5 推荐 - 本地便民网
  • ⑯ AI教育与培训:知识变现的智能化升级#
  • 不止于启动:用RealSense和ROS Noetic玩转3D点云可视化与Rviz调试
  • Arm Ethos-U85 NPU架构与指令集深度解析
  • S2.2行动设计:让行为小到不可能失败
  • 树莓派4B Ubuntu22.04下,用Archiconda搞定Dronekit-Python2.7环境(避坑指南)
  • 小红书视频文案提取工具有哪些?2026保姆级教程+推荐一看就会
  • 深入Linux驱动:手把手分析Xilinx ZynqMP RPU Remoteproc驱动加载与启动流程