深度强化学习课程文档
训练你的第一个深度强化学习智能体 🤖
并获得增强的文档体验
开始使用
训练你的第一个深度强化学习智能体 🤖
既然您已经学习了强化学习的基础知识,那么您就可以训练您的第一个智能体,并通过 Hub 🔥 与社区分享:一个将学习如何在月球 🌕 上正确着陆的 Lunar Lander 智能体

最后,您将把这个训练好的智能体上传到 Hugging Face Hub 🤗,这是一个免费开放的平台,人们可以在这里分享机器学习模型、数据集和演示。
感谢我们的排行榜,您将能够将您的结果与其他同学进行比较,并交流最佳实践以提高您的智能体的分数。谁将赢得单元 1 🏆 的挑战?
为了验证单元 1 的认证过程实践环节,您需要将您训练好的模型推送到 Hub,并获得 >= 200 的结果。
要查找您的结果,请转到排行榜并找到您的模型,结果 = 平均奖励 - 奖励标准差
如果您找不到您的模型,请转到页面底部并单击刷新按钮。
有关认证过程的更多信息,请查看此部分 👉 https://huggingface.co/deep-rl-course/en/unit0/introduction#certification-process
您可以在此处查看您的进度 👉 https://huggingface.co/spaces/ThomasSimonini/Check-my-progress-Deep-RL-Course
那么,让我们开始吧!🚀
要开始实践环节,请点击“在 Colab 中打开”按钮 👇
我们强烈建议学生使用 Google Colab 进行实践练习,而不是在他们的个人电脑上运行。
通过使用 Google Colab,您可以专注于学习和实验,而无需担心设置环境的技术方面。
单元 1:训练你的第一个深度强化学习智能体 🤖

在本 notebook 中,您将训练您的第一个深度强化学习智能体,一个 Lunar Lander 智能体,它将学习在月球 🌕 上正确着陆。使用 Stable-Baselines3 这个深度强化学习库,与社区分享它们,并尝试不同的配置
环境 🎮
使用的库 📚
我们一直在努力改进我们的教程,所以如果您在本 notebook 中发现任何问题,请在 Github 仓库上开启 issue。
本 notebook 的目标 🏆
在本 notebook 结束时,您将能够
- 能够使用 Gymnasium,环境库。
- 能够使用 Stable-Baselines3,深度强化学习库。
- 能够将您训练好的智能体推送到 Hub,并附带精彩的视频回放和评估分数 🔥。
本 notebook 来自深度强化学习课程

在这个免费课程中,您将
- 📖 在理论和实践中学习深度强化学习。
- 🧑💻 学习使用著名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、CleanRL 和 Sample Factory 2.0。
- 🤖 在独特的环境中训练智能体
- 🎓 完成 80% 的作业即可获得结业证书。
以及更多!
查看 📚 教学大纲 👉 https://simoninithomas.github.io/deep-rl-course
不要忘记注册课程(我们正在收集您的电子邮件,以便能够在每个单元发布时向您发送链接,并向您提供有关挑战和更新的信息)。
保持联系和提问的最佳方式是加入我们的 discord 服务器,与社区和我们交流 👉🏻 https://discord.gg/ydHrjt3WP5
先决条件 🏗️
在深入学习 notebook 之前,您需要
🔲 📝 阅读单元 0,其中提供了有关课程的所有信息,并帮助您入门 🤗
🔲 📚 通过阅读单元 1,培养对强化学习基础知识的理解(MC、TD、奖励假设…)。
深度强化学习小结 📚

让我们简要回顾一下我们在第一个单元中学到的内容
强化学习是一种从行动中学习的计算方法。我们构建一个智能体,通过试错法与环境互动并接收奖励(负面或正面)作为反馈,从而从环境中学习。
任何强化学习智能体的目标都是最大化其预期累积奖励(也称为预期回报),因为强化学习是基于奖励假设,即所有目标都可以描述为最大化预期累积奖励。
强化学习过程是一个循环,输出状态、行动、奖励和下一个状态的序列。
为了计算预期累积奖励(预期回报),我们对奖励进行折扣:较早到来的奖励(在游戏开始时)更有可能发生,因为它们比长期的未来奖励更可预测。
为了解决强化学习问题,您需要找到最优策略;策略是您 AI 的“大脑”,它会告诉我们在给定状态下应采取什么行动。最优策略是为您提供最大化预期回报的行动的策略。
有 两种 找到最优策略的方法
通过直接训练您的策略:基于策略的方法。
通过训练一个价值函数,该函数告诉我们智能体在每个状态下将获得的预期回报,并使用该函数来定义我们的策略:基于价值的方法。
最后,我们谈到了深度强化学习,因为我们引入了深度神经网络来估计要采取的行动(基于策略)或估计状态的价值(基于价值),因此得名“深度”。
让我们训练我们的第一个深度强化学习智能体并将其上传到 Hub 🚀
获得证书 🎓
为了验证单元 1 的认证过程实践环节,您需要将您训练好的模型推送到 Hub,并获得 >= 200 的结果。
要查找您的结果,请转到排行榜并找到您的模型,结果 = 平均奖励 - 奖励标准差
有关认证过程的更多信息,请查看此部分 👉 https://huggingface.co/deep-rl-course/en/unit0/introduction#certification-process
设置 GPU 💪
- 为了加速智能体的训练,我们将使用 GPU。为此,请转到
运行时 > 更改运行时类型

硬件加速器 > GPU

安装依赖项并创建虚拟屏幕 🔽
第一步是安装依赖项,我们将安装多个依赖项。
gymnasium[box2d]
:包含 LunarLander-v2 环境 🌛stable-baselines3[extra]
:深度强化学习库。huggingface_sb3
:Stable-baselines3 的附加代码,用于从 Hugging Face 🤗 Hub 加载和上传模型。
为了简化操作,我们创建了一个脚本来安装所有这些依赖项。
apt install swig cmake
pip install -r https://raw.githubusercontent.com/huggingface/deep-rl-class/main/notebooks/unit1/requirements-unit1.txt
在 notebook 期间,我们需要生成一个回放视频。为此,使用 colab,我们需要有一个虚拟屏幕才能渲染环境(从而记录帧)。
因此,以下单元格将安装虚拟屏幕库,并创建和运行虚拟屏幕 🖥
sudo apt-get update apt install python3-opengl apt install ffmpeg apt install xvfb pip3 install pyvirtualdisplay
为了确保使用新安装的库,有时需要重启 notebook 运行时。下一个单元格将强制运行时崩溃,因此您需要重新连接并从此处开始运行代码。多亏了这个技巧,我们将能够运行我们的虚拟屏幕。
import os
os.kill(os.getpid(), 9)
# Virtual display
from pyvirtualdisplay import Display
virtual_display = Display(visible=0, size=(1400, 900))
virtual_display.start()
导入软件包 📦
我们导入的另一个库是 huggingface_hub,以便能够从 hub 上传和下载训练好的模型。
Hugging Face Hub 🤗 作为一个中心位置,任何人都可以共享和探索模型和数据集。它具有版本控制、指标、可视化和其他功能,可让您轻松地与他人协作。
您可以在此处查看所有可用的深度强化学习模型 👉 https://huggingface.co/models?pipeline_tag=reinforcement-learning&sort=downloads
import gymnasium
from huggingface_sb3 import load_from_hub, package_to_hub
from huggingface_hub import (
notebook_login,
) # To log to our Hugging Face account to be able to upload models to the Hub.
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。您将在深度强化学习中大量使用 Gymnasium。
Gymnasium 是 Gym 库的新版本 由 Farama 基金会维护。
Gymnasium 库提供两件事
- 一个允许您创建强化学习环境的接口。
- 一个 环境集合(gym-control、atari、box2D…)。
让我们看一个例子,但首先让我们回顾一下强化学习循环。

在每个步骤中
- 我们的智能体从环境接收一个 状态 (S0) — 我们收到游戏的第一帧(环境)。
- 基于该状态 (S0),智能体采取一个行动 (A0) — 我们的智能体将向右移动。
- 环境转换为一个新的 状态 (S1) — 新帧。
- 环境给智能体一些 奖励 (R1) — 我们没有死 (正奖励 +1)。
使用 Gymnasium
1️⃣ 我们使用 gymnasium.make()
创建我们的环境
2️⃣ 我们使用 observation = env.reset()
将环境重置为初始状态
在每个步骤中
3️⃣ 使用我们的模型获取一个行动(在我们的示例中,我们采取随机行动)
4️⃣ 使用 env.step(action)
,我们在环境中执行此行动并获得
observation
:新状态 (st+1)reward
:我们在执行行动后获得的奖励terminated
:指示 episode 是否终止(智能体到达终止状态)truncated
:在此新版本中引入,它指示时间限制,或者例如智能体是否超出环境边界。info
:提供附加信息的字典(取决于环境)。
有关更多说明,请查看 👉 https://gymnasium.org.cn/api/env/#gymnasium.Env.step
如果 episode 终止
- 我们使用
observation = env.reset()
将环境重置为其初始状态
让我们看一个例子! 确保阅读代码
import gymnasium as gym
# First, we create our environment called LunarLander-v2
env = gym.make("LunarLander-v2")
# Then we reset this environment
observation, info = env.reset()
for _ in range(20):
# Take a random action
action = env.action_space.sample()
print("Action taken:", action)
# Do this action in the environment and get
# next_state, reward, terminated, truncated and info
observation, reward, terminated, truncated, info = env.step(action)
# If the game is terminated (in our case we land, crashed) or truncated (timeout)
if terminated or truncated:
# Reset the environment
print("Environment is reset")
observation, info = env.reset()
env.close()
创建 LunarLander 环境 🌛 并了解其工作原理
环境 🎮
在第一个教程中,我们将训练我们的智能体,一个 Lunar Lander,在月球上正确着陆。为此,智能体需要学习调整其速度和位置(水平、垂直和角度),以便正确着陆。
💡 当您开始使用环境时,一个好的习惯是查看其文档
👉 https://gymnasium.org.cn/environments/box2d/lunar_lander/
让我们看看环境是什么样的
# We create our environment with gym.make("<name_of_the_environment>")
env = gym.make("LunarLander-v2")
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 Shape (8,)
中看到,观察是一个大小为 8 的向量,其中每个值包含有关着陆器的不同信息
- 水平着陆垫坐标 (x)
- 垂直着陆垫坐标 (y)
- 水平速度 (x)
- 垂直速度 (y)
- 角度
- 角速度
- 左腿接触点是否已接触地面(布尔值)
- 右腿接触点是否已接触地面(布尔值)
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
行动空间(智能体可以采取的可能行动的集合)是离散的,有 4 个可用行动 🎮
- 行动 0:什么都不做,
- 行动 1:启动左侧方向引擎,
- 行动 2:启动主引擎,
- 行动 3:启动右侧方向引擎。
奖励函数(将在每个时间步给予奖励的函数)💰
每一步之后都会给予奖励。一个 episode 的总奖励是该 episode 中所有步骤的奖励总和。
对于每个步骤,奖励
- 随着着陆器靠近/远离着陆垫而增加/减少。
- 随着着陆器移动速度变慢/变快而增加/减少。
- 随着着陆器倾斜度增加(角度不水平)而减少。
- 对于每个与地面接触的腿增加 10 分。
- 每帧侧引擎启动时减少 0.03 分。
- 每帧主引擎启动时减少 0.3 分。
对于坠毁或安全着陆,episode 将分别获得 -100 或 +100 分的额外奖励。
如果 episode 得分至少为 200 分,则被视为解决方案。
向量化环境
- 我们创建了一个向量化环境(一种将多个独立环境堆叠成一个单一环境的方法),包含 16 个环境。通过这种方式,我们将在训练期间获得更多样化的经验。
# Create the environment
env = make_vec_env("LunarLander-v2", n_envs=16)
创建模型 🤖
我们已经研究了我们的环境,并且理解了问题:通过控制左、右和主方向引擎,使月球着陆器正确降落在着陆垫上。现在让我们构建我们将用来解决这个问题的算法 🚀。
为此,我们将使用我们的第一个深度强化学习库 Stable Baselines3 (SB3)。
SB3 是一组 PyTorch 中强化学习算法的可靠实现。
💡 使用新库时的一个好习惯是首先深入研究文档:https://stable-baselines3.readthedocs.io/en/master/,然后尝试一些教程。

为了解决这个问题,我们将使用 SB3 PPO。PPO(又名近端策略优化)是您将在本课程中学习的 SOTA(最先进)深度强化学习算法之一。
PPO 是以下方法的组合:
- 基于价值的强化学习方法:学习一个动作价值函数,它将告诉我们 在给定状态和动作的情况下,要采取的最有价值的动作。
- 基于策略的强化学习方法:学习一个策略,它将 给出我们动作的概率分布。
Stable-Baselines3 易于设置:
1️⃣ 你 创建你的环境(在我们的例子中,上面已经完成)
2️⃣ 你定义 你想使用的模型并实例化这个模型 model = PPO("MlpPolicy")
3️⃣ 你使用 model.learn
训练智能体 并定义训练时间步数
# Create environment
env = gym.make('LunarLander-v2')
# Instantiate the agent
model = PPO('MlpPolicy', env, verbose=1)
# Train the agent
model.learn(total_timesteps=int(2e5))
# TODO: Define a PPO MlpPolicy architecture
# We use MultiLayerPerceptron (MLPPolicy) because the input is a vector,
# if we had frames as input we would use CnnPolicy
model =
解决方案
# SOLUTION
# We added some parameters to accelerate the training
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,
)
训练 PPO 智能体 🏃
- 让我们训练我们的智能体 1,000,000 个时间步,不要忘记在 Colab 上使用 GPU。这将大约需要 20 分钟,但如果您只想试用,可以使用更少的时间步。
- 在训练期间,休息一下 ☕,这是您应得的 🤗
# TODO: Train it for 1,000,000 timesteps
# TODO: Specify file name for model and save the model to file
model_name = "ppo-LunarLander-v2"
解决方案
# SOLUTION
# Train it for 1,000,000 timesteps
model.learn(total_timesteps=1000000)
# Save the model
model_name = "ppo-LunarLander-v2"
model.save(model_name)
评估智能体 📈
- 记住将环境包装在 Monitor 中。
- 现在我们的月球着陆器智能体已经训练完成 🚀,我们需要 检查它的性能。
- Stable-Baselines3 提供了一种方法来做到这一点:
evaluate_policy
。 - 要完成这部分,您需要 查看文档
- 在下一步中,我们将看到 如何自动评估和分享您的智能体以参加排行榜竞赛,但现在让我们自己来做
💡 当您评估您的智能体时,您不应该使用您的训练环境,而是创建一个评估环境。
# TODO: Evaluate the agent
# Create a new environment for evaluation
eval_env =
# Evaluate the model with 10 evaluation episodes and deterministic=True
mean_reward, std_reward =
# Print the results
解决方案
# @title
eval_env = Monitor(gym.make("LunarLander-v2"))
mean_reward, std_reward = evaluate_policy(model, eval_env, n_eval_episodes=10, deterministic=True)
print(f"mean_reward={mean_reward:.2f} +/- {std_reward}")
- 就我而言,在训练 100 万步后,我获得了
200.20 +/- 20.80
的平均奖励,这意味着我们的月球着陆器智能体已准备好在月球上着陆 🌛🥳。
在 Hub 上发布我们训练好的模型 🔥
现在我们看到训练后获得了良好的结果,我们可以通过一行代码将我们训练好的模型发布到 hub 🤗。
📚 库文档 👉 https://github.com/huggingface/huggingface_sb3/tree/main#hugging-face—x-stable-baselines3-v20
这是一个模型卡片的示例(使用太空侵略者游戏):
通过使用 package_to_hub
,您可以评估、录制回放、生成您的智能体的模型卡片并将其推送到 hub。
通过这种方式:
- 您可以 展示我们的工作成果 🔥
- 您可以 可视化您的智能体玩游戏 👀
- 您可以 与社区分享其他人可以使用的智能体 💾
- 您可以 访问排行榜 🏆 以查看您的智能体与您的同学相比表现如何 👉 https://huggingface.co/spaces/huggingface-projects/Deep-Reinforcement-Learning-Leaderboard
为了能够与社区分享您的模型,还需要遵循三个步骤:
1️⃣(如果尚未完成)在 Hugging Face 上创建一个帐户 ➡ https://huggingface.co/join
2️⃣ 登录,然后您需要存储来自 Hugging Face 网站的身份验证令牌。
- 创建一个新令牌 (https://huggingface.co/settings/tokens),具有写入权限

- 复制令牌
- 运行下面的单元格并粘贴令牌
notebook_login()
!git config --global credential.helper store
如果您不想使用 Google Colab 或 Jupyter Notebook,您需要使用此命令代替:huggingface-cli login
3️⃣ 我们现在准备使用 package_to_hub()
函数将我们训练好的智能体推送到 🤗 Hub 🔥
让我们填写 package_to_hub
函数:
model
:我们训练好的模型。model_name
:我们在model_save
中定义的训练模型名称model_architecture
:我们使用的模型架构,在我们的例子中是 PPOenv_id
:环境的名称,在我们的例子中是LunarLander-v2
eval_env
:在 eval_env 中定义的评估环境repo_id
:将要创建/更新的 Hugging Face Hub 仓库的名称(repo_id = {username}/{repo_name})
💡 一个好的名称是 {username}/{model_architecture}-{env_id}
commit_message
:提交消息
import gymnasium as gym
from stable_baselines3.common.vec_env import DummyVecEnv
from stable_baselines3.common.env_util import make_vec_env
from huggingface_sb3 import package_to_hub
## TODO: Define a repo_id
## repo_id is the id of the model repository from the Hugging Face Hub (repo_id = {organization}/{repo_name} for instance ThomasSimonini/ppo-LunarLander-v2
repo_id =
# TODO: Define the name of the environment
env_id =
# Create the evaluation env and set the render_mode="rgb_array"
eval_env = DummyVecEnv([lambda: gym.make(env_id, render_mode="rgb_array")])
# TODO: Define the model architecture we used
model_architecture = ""
## TODO: Define the commit message
commit_message = ""
# method save, evaluate, generate a model card and record a replay video of your agent before pushing the repo to the hub
package_to_hub(model=model, # Our trained model
model_name=model_name, # The name of our trained model
model_architecture=model_architecture, # The model architecture we used: in our case PPO
env_id=env_id, # Name of the environment
eval_env=eval_env, # Evaluation Environment
repo_id=repo_id, # id of the model repository from the Hugging Face Hub (repo_id = {organization}/{repo_name} for instance ThomasSimonini/ppo-LunarLander-v2
commit_message=commit_message)
解决方案
import gymnasium as gym
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv
from stable_baselines3.common.env_util import make_vec_env
from huggingface_sb3 import package_to_hub
# PLACE the variables you've just defined two cells above
# Define the name of the environment
env_id = "LunarLander-v2"
# TODO: Define the model architecture we used
model_architecture = "PPO"
## Define a repo_id
## repo_id is the id of the model repository from the Hugging Face Hub (repo_id = {organization}/{repo_name} for instance ThomasSimonini/ppo-LunarLander-v2
## CHANGE WITH YOUR REPO ID
repo_id = "ThomasSimonini/ppo-LunarLander-v2" # Change with your repo id, you can't push with mine 😄
## Define the commit message
commit_message = "Upload PPO LunarLander-v2 trained agent"
# Create the evaluation env and set the render_mode="rgb_array"
eval_env = DummyVecEnv([lambda: Monitor(gym.make(env_id, render_mode="rgb_array"))])
# PLACE the package_to_hub function you've just filled here
package_to_hub(
model=model, # Our trained model
model_name=model_name, # The name of our trained model
model_architecture=model_architecture, # The model architecture we used: in our case PPO
env_id=env_id, # Name of the environment
eval_env=eval_env, # Evaluation Environment
repo_id=repo_id, # id of the model repository from the Hugging Face Hub (repo_id = {organization}/{repo_name} for instance ThomasSimonini/ppo-LunarLander-v2
commit_message=commit_message,
)
恭喜 🥳,您刚刚训练并上传了您的第一个深度强化学习智能体。上面的脚本应该显示一个模型仓库的链接,例如 https://huggingface.co/osanseviero/test_sb3。当您转到此链接时,您可以:
- 在右侧看到您的智能体的视频预览。
- 单击“文件和版本”以查看仓库中的所有文件。
- 单击“在 stable-baselines3 中使用”以获取代码片段,该代码片段显示如何加载模型。
- 模型卡片 (
README.md
文件),其中提供了模型的描述
在底层,Hub 使用基于 git 的仓库(如果您不知道 git 是什么,请不要担心),这意味着您可以在实验和改进智能体时使用新版本更新模型。
使用排行榜 🏆 将您的 LunarLander-v2 的结果与您的同学进行比较 👉 https://huggingface.co/spaces/huggingface-projects/Deep-Reinforcement-Learning-Leaderboard
从 Hub 🤗 加载已保存的 LunarLander 模型
感谢 ironbar 的贡献。
从 Hub 加载已保存的模型非常容易。
转到 https://huggingface.co/models?library=stable-baselines3 以查看所有 Stable-baselines3 已保存模型的列表。
- 选择一个并复制其 repo_id

- 然后我们只需要使用 load_from_hub 和:
- repo_id
- 文件名:仓库内已保存的模型及其扩展名 (*.zip)
因为我从 Hub 下载的模型是使用 Gym(Gymnasium 的前身版本)训练的,所以我们需要安装 shimmy,这是一个 API 转换工具,可以帮助我们正确运行环境。
Shimmy 文档:https://github.com/Farama-Foundation/Shimmy
!pip install shimmy
from huggingface_sb3 import load_from_hub
repo_id = "Classroom-workshop/assignment2-omar" # The repo_id
filename = "ppo-LunarLander-v2.zip" # The model filename.zip
# When the model was trained on Python 3.8 the pickle protocol is 5
# But Python 3.6, 3.7 use protocol 4
# In order to get compatibility we need to:
# 1. Install pickle5 (we done it at the beginning of the colab)
# 2. Create a custom empty object we pass as parameter to PPO.load()
custom_objects = {
"learning_rate": 0.0,
"lr_schedule": lambda _: 0.0,
"clip_range": lambda _: 0.0,
}
checkpoint = load_from_hub(repo_id, filename)
model = PPO.load(checkpoint, custom_objects=custom_objects, print_system_info=True)
让我们评估这个智能体:
# @title
eval_env = Monitor(gym.make("LunarLander-v2"))
mean_reward, std_reward = evaluate_policy(model, eval_env, n_eval_episodes=10, deterministic=True)
print(f"mean_reward={mean_reward:.2f} +/- {std_reward}")
一些额外的挑战 🏆
最好的学习方法 就是自己尝试! 正如您所见,当前的智能体表现不佳。作为第一个建议,您可以训练更多步数。 通过 1,000,000 步,我们看到了一些很棒的结果!
在 排行榜 中,您会找到您的智能体。 您能登上榜首吗?
以下是一些实现此目标的想法:
- 训练更多步数
- 为
PPO
尝试不同的超参数。您可以在 https://stable-baselines3.readthedocs.io/en/master/modules/ppo.html#parameters 中查看它们。 - 查看 Stable-Baselines3 文档 并尝试另一种模型,例如 DQN。
- 将您新的训练好的模型推送到 Hub 🔥
使用 排行榜 🏆 将您的 LunarLander-v2 的结果与您的同学进行比较
登月对您来说太无聊了吗? 尝试 更改环境,为什么不使用 MountainCar-v0、CartPole-v1 或 CarRacing-v0? 查看它们如何工作 使用 gym 文档 并享受乐趣 🎉。
恭喜您完成本章! 这是最大的一章,而且有很多信息。
如果您仍然对所有这些元素感到困惑……这完全正常! 我和所有学习 RL 的人都一样。
在继续之前花时间真正 掌握材料并尝试额外的挑战。 掌握这些要素并拥有坚实的基础非常重要。
当然,在课程中,我们将更深入地研究这些概念,但 最好现在就对它们有很好的理解,然后再深入研究下一章。
下一次,在奖励单元 1 中,您将训练 Huggy 小狗去叼回木棍。
