深度強化學習課程文件
Godot RL Agents
並獲得增強的文件體驗
開始使用
Godot RL Agents
Godot RL Agents 是一個開源軟體包,它讓影片遊戲創作者、人工智慧研究人員和愛好者有機會**為其非玩家角色或代理學習複雜的行為**。
該庫提供
- Godot 引擎中建立的遊戲與 Python 中執行的機器學習演算法之間的介面。
- 針對四種知名強化學習框架的封裝器:StableBaselines3、CleanRL、Sample Factory 和 Ray 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,它是一款乒乓球遊戲,但球場是一個環形,球拍圍繞著環形移動。**目標是讓球在環內持續彈跳**。
安裝 Godot 遊戲引擎
Godot 遊戲引擎 是一個開源工具,用於**建立影片遊戲、工具和使用者介面**。
Godot 引擎是一個功能豐富、跨平臺的遊戲引擎,旨在透過統一介面建立 2D 和 3D 遊戲。它提供了一套全面的常用工具,因此使用者**可以專注於製作遊戲而無需重複造輪子**。遊戲可以一鍵匯出到許多平臺,包括主要的桌面平臺(Linux、macOS、Windows)以及移動平臺(Android、iOS)和基於網路的平臺(HTML5)。
雖然我們將指導您完成實現代理的步驟,但您可能希望瞭解更多關於 Godot 遊戲引擎的資訊。他們的文件很詳盡,YouTube 上也有許多教程,我們還推薦 GDQuest、KidsCanCode 和 Bramwell 作為資訊來源。
為了在 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 RL Agents,點選下載並取消選擇 LICENSE 和 README .md 檔案。然後點選安裝。
Godot RL Agents 外掛現已下載到您的計算機。現在點選專案 → 專案設定並啟用外掛。
新增 AI 控制器
我們現在想給遊戲新增一個 AI 控制器。開啟 player.tscn 場景,左側您應該看到一個節點層次結構,如下所示:
右鍵單擊**Player**節點並單擊**新增子節點**。這裡列出了許多節點,搜尋 AIController3D 並建立它。
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 節點,您會看到編輯器中公開了一個“加速”屬性
嘗試將此屬性設定為 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。
您很有可能在第一次嘗試時遇到錯誤。以下是幫助您解決錯誤的方案。
- 關於 `Invalid Call. Nonexistent function 'new' in base 'CSharpScript'` 的問題:解決方案
- 關於 macOS 上 `onnxruntime` 的錯誤:解決方案
還有更多!
我們才剛剛觸及 Godot RL Agents 能力的冰山一角,該庫包括自定義感測器和攝像頭,以豐富代理可獲得的資訊。檢視示例以瞭解更多資訊!
為了能夠將訓練好的模型匯出為 .onnx,以便您可以在 Godot 中直接執行推理而無需 Python 伺服器,以及其他有用的訓練選項,請檢視高階 SB3 教程。
作者
本節由 Edward Beeching 撰寫
< > 在 GitHub 上更新