深度强化学习课程文档

Godot RL Agents

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

Godot RL Agents

Godot RL Agents 是一个开源软件包,它让视频游戏创作者、人工智能研究人员和爱好者有机会**为其非玩家角色或代理学习复杂的行为**。

该库提供

  • Godot 引擎中创建的游戏与 Python 中运行的机器学习算法之间的接口。
  • 针对四种知名强化学习框架的封装器:StableBaselines3CleanRLSample FactoryRay RLLib
  • 支持基于内存的代理,带有 LSTM 或基于注意力的接口
  • 支持*2D 和 3D 游戏*
  • 一套*AI 传感器*,以增强代理观察游戏世界的能力
  • Godot 和 Godot RL Agents **完全免费且在非常宽松的 MIT 许可下开源**。无附加条件,无版税,无其他。

您可以在他们的 GitHub 页面或他们的 AAAI-2022 研讨会 论文中了解更多关于 Godot RL Agents 的信息。该库的创建者 Ed Beeching 是 Hugging Face 的一名研究科学家。

安装库很简单:`pip install godot-rl`

使用 Godot RL Agents 创建自定义 RL 环境

在本节中,您将**学习如何在 Godot 游戏引擎中创建自定义环境**,然后实现一个通过深度强化学习来学习玩游戏的 AI 控制器。

我们今天创建的示例游戏很简单,**但展示了 Godot 引擎和 Godot RL Agents 库的许多功能**。然后,您可以深入研究示例,了解更复杂的环境和行为。

我们今天将要构建的环境叫做 Ring Pong,它是一款乒乓球游戏,但球场是一个环形,球拍围绕着环形移动。**目标是让球在环内持续弹跳**。

Ring Pong

安装 Godot 游戏引擎

Godot 游戏引擎 是一个开源工具,用于**创建视频游戏、工具和用户界面**。

Godot 引擎是一个功能丰富、跨平台的游戏引擎,旨在通过统一界面创建 2D 和 3D 游戏。它提供了一套全面的常用工具,因此用户**可以专注于制作游戏而无需重复造轮子**。游戏可以一键导出到许多平台,包括主要的桌面平台(Linux、macOS、Windows)以及移动平台(Android、iOS)和基于网络的平台(HTML5)。

虽然我们将指导您完成实现代理的步骤,但您可能希望了解更多关于 Godot 游戏引擎的信息。他们的文档很详尽,YouTube 上也有许多教程,我们还推荐 GDQuestKidsCanCodeBramwell 作为信息来源。

为了在 Godot 中创建游戏,**您必须首先下载编辑器**。Godot RL Agents 支持 Godot 的最新版本 Godot 4.0。

可以从以下链接下载

加载起始项目

我们提供了两个版本的代码库

要加载项目,请在 Godot 项目管理器中单击**导入**,导航到文件所在的位置,然后加载 **project.godot** 文件。

如果您在编辑器中按 F5 或播放,您应该能够在人类模式下玩游戏。有多个游戏实例正在运行,这是因为我们希望通过许多并行环境来加速训练我们的 AI 代理。

安装 Godot RL Agents 插件

Godot RL Agents 插件可以从 Github 仓库安装,也可以在编辑器中使用 Godot Asset Lib 安装。

首先点击 AssetLib 并搜索“rl”

Godot

然后点击 Godot RL Agents,点击下载并取消选择 LICENSE 和 README .md 文件。然后点击安装。

Godot

Godot RL Agents 插件现已下载到您的计算机。现在点击项目 → 项目设置并启用插件。

Godot

添加 AI 控制器

我们现在想给游戏添加一个 AI 控制器。打开 player.tscn 场景,左侧您应该看到一个节点层次结构,如下所示:

Godot

右键单击**Player**节点并单击**添加子节点**。这里列出了许多节点,搜索 AIController3D 并创建它。

Godot

AI 控制器节点应该已经添加到场景树中,旁边有一个卷轴。点击它以打开附加到 AIController 的脚本。Godot 游戏引擎使用一种名为 GDScript 的脚本语言,它在语法上与 Python 相似。该脚本包含需要实现的方**法,以便使我们的 AI 控制器正常工作**。

#-- Methods that need implementing using the "extend script" option in Godot --#
func get_obs() -> Dictionary:
	assert(false, "the get_obs method is not implemented when extending from ai_controller")
	return {"obs":[]}

func get_reward() -> float:
	assert(false, "the get_reward method is not implemented when extending from ai_controller")
	return 0.0

func get_action_space() -> Dictionary:
	assert(false, "the get get_action_space method is not implemented when extending from ai_controller")
	return {
		"example_actions_continous" : {
			"size": 2,
			"action_type": "continuous"
		},
		"example_actions_discrete" : {
			"size": 2,
			"action_type": "discrete"
		},
		}

func set_action(action) -> void:
	assert(false, "the get set_action method is not implemented when extending from ai_controller")
# -----------------------------------------------------------------------------#

为了实现这些方法,我们需要创建一个继承自 AIController3D 的类。这在 Godot 中很容易做到,被称为“扩展”一个类。

右键单击 AIController3D 节点,然后单击“扩展脚本”,并将新脚本命名为 `controller.gd`。您现在应该有一个几乎为空的脚本文件,如下所示

extends AIController3D

# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass

我们现在将实现缺少的 4 种方法,删除这段代码,并替换为以下内容

extends AIController3D

# Stores the action sampled for the agent's policy, running in python
var move_action : float = 0.0

func get_obs() -> Dictionary:
	# get the balls position and velocity in the paddle's frame of reference
	var ball_pos = to_local(_player.ball.global_position)
	var ball_vel = to_local(_player.ball.linear_velocity)
	var obs = [ball_pos.x, ball_pos.z, ball_vel.x/10.0, ball_vel.z/10.0]

	return {"obs":obs}

func get_reward() -> float:
	return reward

func get_action_space() -> Dictionary:
	return {
		"move_action" : {
			"size": 1,
			"action_type": "continuous"
		},
		}

func set_action(action) -> void:
	move_action = clamp(action["move_action"][0], -1.0, 1.0)

我们现在定义了代理的观测,即球在其局部坐标空间中的位置和速度。我们还定义了代理的动作空间,它是一个范围从 -1 到 +1 的单一连续值。

下一步是更新玩家的脚本以使用 AIController 的动作,通过单击玩家节点旁边的滚动条编辑玩家的脚本,将 `Player.gd` 中的代码更新为以下内容

extends Node3D

@export var rotation_speed = 3.0
@onready var ball = get_node("../Ball")
@onready var ai_controller = $AIController3D

func _ready():
	ai_controller.init(self)

func game_over():
	ai_controller.done = true
	ai_controller.needs_reset = true

func _physics_process(delta):
	if ai_controller.needs_reset:
		ai_controller.reset()
		ball.reset()
		return

	var movement : float
	if ai_controller.heuristic == "human":
		movement = Input.get_axis("rotate_anticlockwise", "rotate_clockwise")
	else:
		movement = ai_controller.move_action
	rotate_y(movement*delta*rotation_speed)

func _on_area_3d_body_entered(body):
	ai_controller.reward += 1.0

我们现在需要在 Godot 中运行的游戏和在 Python 中训练的神经网络之间进行同步。Godot RL agents 提供了一个节点来完成这项工作。打开 train.tscn 场景,右键单击根节点,然后单击“添加子节点”。然后,搜索“sync”并添加一个 Godot RL Agents Sync 节点。这个节点处理 Python 和 Godot 之间通过 TCP 的通信。

您可以通过首先使用 `gdrl` 启动 Python 训练,在编辑器中实时运行训练。

在这个简单的例子中,一个合理的策略在几分钟内就能学会。您可能希望加快训练速度,单击训练场景中的 Sync 节点,您会看到编辑器中公开了一个“加速”属性

Godot

尝试将此属性设置为 8 以加快训练速度。这在更复杂的环境中会带来巨大的好处,例如我们将在下一章中学习的多人 FPS 游戏。

导出模型

参考文档

现在我们暂时把 Godot 编辑器放一边。我们需要使用终端运行一些命令来保存我们训练过的模型。

Godot RL 库的最新版本为 Stable Baselines 3、rllib 和 CleanRL 训练框架提供了对 onnx 模型的实验性支持。

例如,让我们使用 Stable Baselines 3 作为框架。使用 sb3 示例 (使用脚本的说明) 训练您的代理,启用选项 `--onnx_export_path=model.onnx`

以下是执行示例命令行

cd <....> # go into this Godot project directory
python stable_baselines3_example.py --timesteps=100_000 --onnx_export_path=model.onnx --save_model_path=model.zip --save_checkpoint_frequency=20_000 --experiment_name=exp1

如果一切正常,您应该会在终端中看到如下消息

No game binary has been provided, please press PLAY in the Godot editor
waiting for remote GODOT connection on port 11008

如果您在 stable_baselines3_example 脚本中遇到关于导入错误的失败:“ImportError: cannot import name ‘export_model_as_onnx’ from ‘godot_rl.wrappers.onnx.stable_baselines_export’”,请按照 此问题 中的答案进行操作。

现在是时候切换回 Godot 编辑器,然后点击右上角的“播放”。一旦点击,游戏场景将弹出,显示 AI 训练。同时,终端将开始打印指标。等待训练完成,如果一切正常,您应该能够在 Godot 项目目录中找到文件 `model.onnx`。

在游戏中应用 AI!

现在让我们将这个训练好的模型应用到游戏中!

在 Godot 编辑器中,找到 `train.tscn` 中的 Sync 节点

  • 将控制模式从下拉菜单更改为 `Onnx 推理`
  • 将 `Onnx 模型路径` 设置为模型文件名,在本例中为 `model.onnx`

要运行这个游戏,我们需要 Godot 编辑器的 Mono 版本(即 .NET 版本),您可以从 Godot 官方页面下载。我们还需要安装 .NET

您很有可能在第一次尝试时遇到错误。以下是帮助您解决错误的方案。

  1. 关于 `Invalid Call. Nonexistent function 'new' in base 'CSharpScript'` 的问题:解决方案
  2. 关于 macOS 上 `onnxruntime` 的错误:解决方案

还有更多!

我们才刚刚触及 Godot RL Agents 能力的冰山一角,该库包括自定义传感器和摄像头,以丰富代理可获得的信息。查看示例以了解更多信息!

为了能够将训练好的模型导出为 .onnx,以便您可以在 Godot 中直接运行推理而无需 Python 服务器,以及其他有用的训练选项,请查看高级 SB3 教程

作者

本节由 Edward Beeching 撰写

< > 在 GitHub 上更新