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

Unit 2 训练你的第一个深度强化学习智能体 LunarLander-v3

Unit 2: Train your first Deep Reinforcement Learning Agent

训练一个深度强化学习智能体——一个月球着陆器智能体,它会学习如何在月球上正确着陆 🌕,并且使用深度强化学习库 Stable-Baselines3 来训练该智能体。

安装依赖项:

  • gymnasium[box2d]:包含 LunarLander-v3 环境。
  • stable-baselines3[extra]:深度强化学习库。

导入所需的包

import gymnasium
from stable_baselines3 import PPO
from stable_baselines3.common.env_util import make_vec_env
from stable_baselines3.common.evaluation import evaluate_policy
from stable_baselines3.common.monitor import Monitor

了解 Gymnasium 及其工作原理

Gymnasium 是由 Farama 基金会维护的 Gym 库的新版本,Gymnasium 库提供了以下两项功能:

  • 一个接口,允许你创建强化学习(RL)环境。
  • 一系列环境集合(如 gym-control、Atari、Box2D 等)。

使用 Gymnasium 时:

  1. 通过 gymnasium.make() 来创建环境。

  2. 使用 observation = env.reset() 将环境重置为其初始状态。

在每一步操作中:

  1. 使用模型获取一个动作(在本例中,我们采取一个随机动作)。

  2. 使用 env.step(action),我们在环境中执行该动作,并获取以下信息:

    • observation:新的状态(st+1)。
    • reward:执行该动作后获得的奖励。
    • terminated:指示该回合是否已结束(智能体是否到达了终止状态)。
    • truncated:这是新版本中引入的,它表示时间限制或智能体是否超出了环境边界等情况。
    • info:一个字典,提供额外的信息(具体内容取决于环境)。

如果回合已结束:

  • 使用 observation = env.reset() 将环境重置为其初始状态。
import gymnasium as gym# 首先,创建一个LunarLander-v3的环境
env = gym.make("LunarLander-v3")# 初始化环境
observation, info = env.reset()for _ in range(20):# 采取一个随机动作action = env.action_space.sample()print("Action taken:", action)# 执行这个动作,并获取# next_state, reward, terminated, truncated and infoobservation, reward, terminated, truncated, info = env.step(action)# 如果游戏终止(在我们的例子中,我们着陆、崩溃)或被截断(超时)if terminated or truncated:# 重置环境print("Environment is reset")observation, info = env.reset()env.close()
Action taken: 0
Action taken: 3
Action taken: 3
略略路
Action taken: 1
Action taken: 3
Action taken: 2
观察空间

状态是一个八维向量:包含着陆器在 x 轴和 y 轴上的坐标、在 x 轴和 y 轴上的线速度、角度、角速度,以及两个布尔值,分别表示着陆器的每条腿是否与地面接触。

# We create our environment with gym.make("<name_of_the_environment>")
env = gym.make("LunarLander-v3")
env.reset()
print("_____OBSERVATION SPACE_____ \n")
print("Observation Space Shape", env.observation_space.shape)
print("Sample observation", env.observation_space.sample())  # Get a random observation
_____OBSERVATION SPACE_____ Observation Space Shape (8,)
Sample observation [-0.39945436 -0.36198062 -7.3894777   7.566114   -4.997432    4.54730220.53182733  0.834311  ]
动作空间

有四个离散动作可供选择:

0:不执行任何操作(即保持当前状态)

1:启动左侧姿态调整引擎(即向左喷射)

2:启动主引擎(即向下喷射,提供主要推力)

3:启动右侧姿态调整引擎(即向右喷射)

print("\n _____ACTION SPACE_____ \n")
print("Action Space Shape", env.action_space.n)
print("Action Space Sample", env.action_space.sample())  # Take a random action
 _____ACTION SPACE_____ Action Space Shape 4
Action Space Sample 3
奖励机制

每一步操作后都会给予一个奖励。一个回合的总奖励是该回合内所有步骤奖励的总和。
对于每一步操作,奖励的计算方式如下:

  • 着陆器距离着陆平台越近,奖励增加;距离越远,奖励减少。
  • 着陆器移动速度越慢,奖励增加;移动速度越快,奖励减少。
  • 着陆器倾斜程度越大(角度非水平),奖励减少。
  • 着陆器的每条腿与地面接触时,奖励增加 10 分。
  • 侧边引擎每喷射一帧,奖励减少 0.03 分。
  • 主引擎每喷射一帧,奖励减少 0.3 分。

如果着陆器坠毁,该回合将获得 -100 分的额外惩罚;如果安全着陆,则获得 +100 分的额外奖励。
如果一个回合的得分至少达到 200 分,则认为该回合的解决方案是成功的。

回合终止条件

当出现以下情况时,回合结束:

  • 着陆器坠毁(着陆器主体与月球表面接触);
  • 着陆器飞出视野范围(x 坐标大于 1);
  • 着陆器处于“休眠”状态。根据 Box2D 的文档说明,一个处于非唤醒状态(not awake)的物体是指该物体既不移动也不与其他任何物体发生碰撞:

当 Box2D 判定一个物体(或一组物体)已经静止时,该物体会进入休眠状态,此时 CPU 开销非常小。
如果一个处于唤醒状态的物体与一个处于休眠状态的物体发生碰撞,那么休眠状态的物体会被唤醒。
此外,如果与物体相连的关节或接触点被销毁,该物体也会被唤醒。

向量化环境

创建一个包含 16 个独立环境的向量化环境(这是一种将多个独立环境叠加成一个单一环境的方法)。通过这种方式,我们在训练过程中将获得更多样化的经验。

# Create the environment
env = make_vec_env("LunarLander-v3", n_envs=16)
环境参数

Lunar Lander(月球着陆器)环境具有大量的参数,这些参数允许用户自定义环境的各个方面,以适应不同的训练需求和实验设置。

import gymnasium as gym
env = gym.make("LunarLander-v3", continuous=False, gravity=-10.0,enable_wind=False, wind_power=15.0, turbulence_power=1.5)
  • continuous 参数用于确定是使用离散动作还是连续动作(分别对应引擎的油门控制),动作空间将相应地设置为 Discrete(4)Box(-1, +1, (2,), dtype=np.float32)。对于连续动作,动作的第一个坐标决定主引擎的油门,而第二个坐标指定侧向助推器的油门。给定一个动作 np.array([main, lateral]),如果 main < 0,主引擎将完全关闭;当 0 <= main <= 1 时,油门会从 50% 线性变化到 100%(特别地,主引擎在功率低于 50% 时不会工作)。类似地,如果 -0.5 < lateral < 0.5,侧向助推器将完全不会启动。如果 lateral < -0.5,左侧助推器将启动;如果 lateral > 0.5,右侧助推器将启动。同样地,油门会在 -1 和 -0.5(以及 0.5 和 1)之间从 50% 线性变化到 100%。

  • gravity 参数用于设定重力常数,其取值范围被限定在 0 到 -12 之间。默认值为 -10.0。

  • enable_wind 参数用于确定是否对着陆器施加风力效果。风力是通过函数 tanh(sin(2 k (t+C)) + sin(pi k (t+C))) 生成的,其中 k 被设置为 0.01,而 C 是在 -9999 和 9999 之间随机采样的值。

  • wind_power 参数用于设定施加在飞行器上的线性风力的最大强度。wind_power 的推荐取值范围在 0.0 到 20.0 之间。

  • turbulence_power 参数用于设定施加在飞行器上的旋转风力的最大强度。turbulence_power 的推荐取值范围在 0.0 到 2.0 之间。

创建模型

使用深度强化学习库——Stable Baselines3(简称SB3)创建模型,SB3 是一套基于 PyTorch 的强化学习算法的可靠实现。我们将使用 SB3 中的 PPO 算法。PPO(即近端策略优化,Proximal Policy Optimization)是最先进的(SOTA,state of the art)深度强化学习算法之一。

PPO 结合了以下两种方法:

  • 基于价值的强化学习方法:学习一个动作价值函数,该函数能在给定状态和动作的情况下,告诉我们采取哪个动作最有价值。
  • 基于策略的强化学习方法:学习一个策略,该策略能为我们提供一个动作上的概率分布。

Stable-Baselines3 的设置非常简单:

  1. 创建自己的环境(在我们的例子中,这一步已经在上面完成了)。

  2. 你需要定义想要使用的模型,并实例化该模型,例如:model = PPO(“MlpPolicy”)。

  3. 使用 model.learn 来训练智能体,并定义训练的时间步数。

# Create environment
env = gym.make('LunarLander-v3')
# Instantiate the agent
model = PPO(policy="MlpPolicy",env=env,n_steps=1024,batch_size=64,n_epochs=4,gamma=0.999,gae_lambda=0.98,ent_coef=0.01,verbose=1,
)

训练模型

# SOLUTION
# Train it for 1,000,000 timesteps
model.learn(total_timesteps=1000000)
# Save the model
model_name = "ppo-LunarLander-v3"
model.save(model_name)
---------------------------------
| rollout/           |          |
|    ep_len_mean     | 94.2     |
|    ep_rew_mean     | -146     |
| time/              |          |
|    fps             | 567      |
|    iterations      | 1        |
|    time_elapsed    | 1        |
|    total_timesteps | 1024     |
---------------------------------
-------------------------------------------
| rollout/                |               |
|    ep_len_mean          | 90.5          |
|    ep_rew_mean          | -189          |
| time/                   |               |
|    fps                  | 524           |
|    iterations           | 2             |
|    time_elapsed         | 3             |
|    total_timesteps      | 2048          |
| train/                  |               |
|    approx_kl            | 0.00025148428 |
|    clip_fraction        | 0             |
|    clip_range           | 0.2           |
|    entropy_loss         | -1.39         |
|    explained_variance   | 0.000702      |
|    learning_rate        | 0.0003        |
|    loss                 | 1.81e+03      |
|    n_updates            | 4             |
|    policy_gradient_loss | -0.00137      |
|    value_loss           | 3.56e+03      |
-------------------------------------------略略略
------------------------------------------
| rollout/                |              |
|    ep_len_mean          | 921          |
|    ep_rew_mean          | 116          |
| time/                   |              |
|    fps                  | 539          |
|    iterations           | 249          |
|    time_elapsed         | 472          |
|    total_timesteps      | 254976       |
| train/                  |              |
|    approx_kl            | 0.0010052922 |
|    clip_fraction        | 0.00317      |
|    clip_range           | 0.2          |
|    entropy_loss         | -0.806       |
|    explained_variance   | 0.783        |
|    learning_rate        | 0.0003       |
|    loss                 | 39.9         |
|    n_updates            | 992          |
|    policy_gradient_loss | -0.000245    |
|    value_loss           | 244          |
------------------------------------------
------------------------------------------
| rollout/                |              |
|    ep_len_mean          

评估智能体并可视化智能体的表现

  • 记得要将环境封装在 Monitor 中。
  • 现在,月球着陆器智能体已经训练完成 🚀,我们需要检查它的性能表现。
  • Stable-Baselines3 提供了一个方法来实现这一点:evaluate_policy。

在接下来的步骤中,我们将看到如何自动评估你的智能体,在评估智能体时,你不应该使用训练时的环境,而是应该创建一个评估环境。

eval_env = Monitor(gym.make("LunarLander-v3"))
mean_reward, std_reward = evaluate_policy(model, eval_env, n_eval_episodes=10, deterministic=True)
print(f"mean_reward={mean_reward:.2f} +/- {std_reward}")
mean_reward=253.50 +/- 35.760438569719035

视频保存在./LunarLander-ppo目录下

eval_env = gym.wrappers.RecordVideo(gym.make("LunarLander-v3",render_mode="rgb_array"), video_folder="./LunarLander-ppo",disable_logger=True,fps=30)
observation, info = eval_env.reset()
while True:action = model.predict(observation)[0]observation, reward, terminated, truncated, info = eval_env.step(action)if terminated == True:break
eval_env.close()

LunarLander-v3

相关文章:

  • 慢接口优化万能公式-适合所有系统
  • 1.2 git使用
  • SIP协议之NACK(Negative Acknowledgement)
  • LLMs 系列实操科普(3)
  • 智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
  • 业财融合怎么做?如何把握业务与财务的边界?
  • crackme008
  • Unity | AmplifyShaderEditor插件基础(第八集:噪声波动shader)
  • Siri在WWDC中的缺席显得格外刺眼
  • day50python打卡
  • 通道注意力机制
  • spring jms使用
  • 上位机开发:C# 读写 PLC 数据块数据
  • 内存分配函数malloc kmalloc vmalloc
  • LeetCode 3442.奇偶频次间的最大差值 I:计数
  • gro文件和top文件介绍,以及如何合并两个gro文件或两个top文件
  • 天猫官方认证TP服务商——品融电商代运营全链路解析
  • WHAT - 组件库单入口打包和多入口打包
  • 基于FPGA的PID算法学习———实现PID比例控制算法
  • 大型活动交通拥堵治理的视觉算法应用
  • 传奇动态网站怎么做/缅甸在线今日新闻
  • 个人做外贸商城网站/域名查询seo
  • 网站空间和虚拟主机/代理推广
  • 那个网站做任务赚钱/批量关键词排名查询工具
  • 网站建设项目延期验收申请/百度软件商店
  • 厦门网站开发平台/seo的重要性