TMRL
tmrl
是一个全面的分布式强化学习框架,专为机器人学设计,旨在帮助您在实时应用中训练深度强化学习AI。
tmrl
附带了TrackMania 2020视频游戏的自动驾驶示例流程。
简介:
-
:red_car: AI和TM爱好者:
tmrl
使您能够轻松地在TrackMania中训练AI。这里有专门为你们准备的教程,预训练AI的视频,以及SAC算法的初学者介绍。 -
:rocket: 机器学习开发者/机器人专家:
tmrl
是一个Python库,旨在简化工业应用中特定强化学习流程的实施,特别是实时控制。这里有最小示例,这里有完整教程,这里有文档。 -
:ok_hand: 对学习这个庞大系统不感兴趣但热爱TM的机器学习开发者:
tmrl
为TrackMania提供了一个易于使用的Gymnasium环境。这里有为你们准备的快速通道。 -
:earth_americas: 所有人:
tmrl
主办TrackMania机器人赛车联赛,这是一个基于视觉的AI竞赛,参与者在TrackMania 2020视频游戏中设计实时自动赛车AI。
快速链接
TMRL项目
介绍
tmrl
是一个Python框架,旨在帮助您通过深度强化学习在实时应用(机器人、视频游戏、高频控制等)中训练人工智能(AI)。
作为基于视觉的自动驾驶的有趣且安全的机器人代理,tmrl
为TrackMania 2020赛车视频游戏提供了一个现成实现的示例流程。
注:在强化学习的背景下,AI被称为策略。
用户功能(以TrackMania为例的流水线):
-
训练算法:
tmrl
自带一个现成实现的示例流水线,让您可以轻松地使用最先进的深度强化学习算法(如Soft Actor-Critic (SAC)和Randomized Ensembled Double Q-Learning (REDQ))在TrackMania 2020中训练策略。 这些算法将收集到的样本存储在一个大型数据集中,称为回放内存。 同时,这些样本被用来训练一个人工神经网络(策略),将观察(图像、速度等)映射到相关动作(加速、刹车、转向角度等)。 -
从截图进行模拟控制:
tmrl
示例流水线训练的策略能够从实时捕获的原始截图进行驾驶。 对于初学者,我们还提供了更简单的测距仪("LIDAR")观察,这种观察不太强大但更容易学习。 示例流水线通过虚拟游戏手柄控制游戏,实现模拟动作。 -
模型: 为处理LIDAR测量,
tmrl
示例流水线使用多层感知器(MLP)。 为处理原始摄像机图像(快照),它使用卷积神经网络(CNN)。 这些模型从等时间间隔的观察历史中学习游戏的物理规律。
开发者功能(Python中的实际应用):
-
Python库:
tmrl
是一个完整的框架,旨在帮助您成功实现实际应用的特定强化学习流水线。它具有安全远程训练、细粒度可定制性,并且完全兼容实时环境(如机器人等)。 它基于单服务器/多客户端架构,使得可以从一个到任意多个worker本地收集样本,并在高性能计算集群上远程训练。 这里提供了一个完整教程,指导您为特定应用实现这一点。 -
TrackMania Gymnasium环境:
tmrl
附带了一个基于rtgym的TrackMania 2020 Gymnasium环境。安装库后,在您自己的训练框架中使用此环境很容易。这里有更多信息。 -
外部库:
tmrl
衍生出一些更具普遍意义的子项目,这些子项目被剥离并打包成独立的Python库。 特别是,rtgym可以在实时应用中实现Gymnasium环境, vgamepad可以模拟虚拟游戏控制器, tlspyo可以通过互联网安全地传输Python对象。
TMRL在媒体中:
-
在法国节目Underscore_ (2022-06-08)中,我们使用基于视觉(LIDAR)的策略与TrackMania世界冠军对抗。剧透:我们的策略远远落后(意料之中:smile:);在
tmrl-test
赛道上,超人目标设定为约32秒,而训练的策略平均表现约为45.5秒。我们在节目中使用的Gymnasium环境可在此处获得。 -
2023年,我们受邀到育碧蒙特利尔进行演讲,描述视频游戏如何在不久的将来成为基于视觉的自动驾驶的视觉模拟器。
安装
详细的安装说明可在此链接找到。
入门
关于在TrackMania 2020中设置环境、测试预训练权重以及初学者友好的训练、测试和微调自己模型的教程,可在此链接找到。
TMRL Python库
一个高级教程,指导您为自己的实时任务实现自己的特定优化训练流水线,可在这里找到。
安全性
:warning: 重要提示:在公共网络上使用tmrl
之前,请阅读并理解本节内容。
从安全角度来看,tmrl
基于tlspyo。
默认情况下,tmrl
通过非加密TCP传输对象,以实现开箱即用。
只要您在自己的私有网络上使用tmrl
,这就没问题。
然而,如果您开始在公共网络上使用tmrl
,这将是一个安全漏洞。
要在公共网络(例如互联网)上安全地使用tmrl
,请启用传输层安全(TLS)。
为此,请在所有机器上按照以下说明操作:
- 打开
config.json
; - 将
"TLS"
条目设置为true
; - 将
"PASSWORD"
条目替换为您自己的强密码(在所有机器上使用相同的密码); - 在托管
Server
的机器上,生成 TLS 密钥和证书(按照 tlspyo 说明进行操作); - 将生成的证书复制到所有其他机器上(可以放在默认的 tlspyo 凭证目录中,或者放在您选择的目录中);
- 如果您在上一步中使用了自己的目录,请将
"TLS_CREDENTIALS_DIRECTORY"
条目替换为该目录的路径。
如果由于某种原因您不想使用 TLS(不推荐),在通过公共网络进行训练时,您至少应该在 config.json
中使用自定义密码。
但是,切勿使用您在其他应用程序中使用的密码。
这是因为,如果没有 TLS 加密,这个密码将可以在您的机器通过网络发送的数据包中被读取,并可能被拦截。
TrackMania 中的自动驾驶
TrackMania 机器人竞赛联盟
我们主办 TrackMania 机器人竞赛联盟,这是一种在 TrackMania 2020 视频游戏中对自动赛车方法进行基准测试的有趣方式。 点击链接了解有关竞赛的信息,包括当前排行榜和参与说明。
无论是否想要参赛,机器学习开发者都会发现竞赛教程脚本对于在 TrackMania 中创建高级训练流程很有帮助。
TrackMania Gymnasium 环境
如果您只想在自己的训练框架中使用 tmrl
为 TrackMania 提供的实时 Gym 环境,可以通过 get_environment()
方法实现:
(注意:需要按照入门指南中的说明设置游戏)
from tmrl import get_environment
from time import sleep
import numpy as np
# LIDAR 观测的形状为:((1,), (4, 19), (3,), (3,))
# 分别表示:(速度, 最近4次LIDAR扫描, 2个先前动作)
# 动作为 [油门, 刹车, 转向],模拟值在 -1.0 到 +1.0 之间
def model(obs):
"""
LIDAR 观测的简单策略
"""
deviation = obs[1].mean(0)
deviation /= (deviation.sum() + 0.001)
steer = 0
for i in range(19):
steer += (i - 9) * deviation[i]
steer = - np.tanh(steer * 4)
steer = min(max(steer, -1.0), 1.0)
return np.array([1.0, 0.0, steer])
# 让我们获取 TMRL Gymnasium 环境。
# 从 get_environment() 获得的环境取决于 config.json 的内容
env = get_environment()
sleep(1.0) # 仅为了在启动脚本后有时间聚焦 TM20 窗口
obs, info = env.reset() # 重置环境
for _ in range(200): # rtgym 默认确保以 20Hz 运行
act = model(obs) # 计算动作
obs, rew, terminated, truncated, info = env.step(act) # 执行步骤(rtgym 确保健康的时间步长)
if terminated or truncated:
break
env.wait() # rtgym 特定方法,在需要时人为"暂停"环境
可以通过更改 TmrlData\config\config.json
中 ENV
条目的内容来选择和自定义环境类型:
(注意:不要直接复制粘贴示例,原始 .json 文件不支持注释)
完整环境:
环境的这个版本提供完整的屏幕截图,可以用于例如 CNN 处理。 此外,这个版本还提供速度、档位和 RPM 信息。 这适用于任何赛道,使用任何(合理的)摄像机配置。
{
"ENV": {
"RTGYM_INTERFACE": "TM20FULL", // TrackMania 2020全屏截图
"WINDOW_WIDTH": 256, // 游戏窗口宽度(最小: 256)
"WINDOW_HEIGHT": 128, // 游戏窗口高度(最小: 128)
"SLEEP_TIME_AT_RESET": 1.5, // 每次重置后环境休眠的时间
"IMG_HIST_LEN": 4, // 观察中图像历史长度(RNN设为1)
"IMG_WIDTH": 64, // 观察中图像实际(调整后)宽度
"IMG_HEIGHT": 64, // 观察中图像实际(调整后)高度
"IMG_GRAYSCALE": true, // true为灰度图像,false为彩色图像
"RTGYM_CONFIG": {
"time_step_duration": 0.05, // 时间步长
"start_obs_capture": 0.04, // 捕获观察前的持续时间
"time_step_timeout_factor": 1.0, // 时间步长最大弹性
"act_buf_len": 2, // 观察中动作历史长度(RNN设为1)
"benchmark": false, // 设为true启用环境基准测试
"wait_on_done": true, // true
"ep_max_length": 1000 // 超过此步数后截断回合
},
"REWARD_CONFIG": {
"END_OF_TRACK": 100.0, // 到达终点线的奖励
"CONSTANT_PENALTY": 0.0, // 每个时间步的固定奖励
"CHECK_FORWARD": 500, // 从上一点计算的最大前进距离
"CHECK_BACKWARD": 10, // 从上一点计算的最大后退距离
"FAILURE_COUNTDOWN": 10, // 此时间步数后提前终止
"MIN_STEPS": 70, // 提前终止生效前的时间步数
"MAX_STRAY": 100.0 // 距离示范轨迹过远时提前终止
}
}
}
请注意,人类玩家可以看到或听到此环境提供的特征:我们不提供任何会使方法无法迁移到真实世界的"作弊"手段。 不过,如果你确实想作弊,你可以很容易地从我们的rtgym接口获得灵感,为TrackMania构建自己的自定义环境。
Full
环境用于官方TMRL比赛,而自定义环境则出现在"非官方"比赛中 :wink:
LIDAR环境:
在此版本的环境中,截图被简化为19束激光雷达,以便使用例如MLP进行处理。 此外,该版本还包含速度(人类玩家可以看到)。 这只适用于带有黑色边界的普通道路,使用前置摄像头且隐藏车辆。
{
"ENV": {
"RTGYM_INTERFACE": "TM20LIDAR", // TrackMania 2020 LIDAR观察
"WINDOW_WIDTH": 958, // 游戏窗口宽度(最小: 256)
"WINDOW_HEIGHT": 488, // 游戏窗口高度(最小: 128)
"SLEEP_TIME_AT_RESET": 1.5, // 每次重置后环境休眠的时间
"IMG_HIST_LEN": 4, // 观察中LIDAR测量历史长度(RNN设为1)
"RTGYM_CONFIG": {
"time_step_duration": 0.05, // 时间步长
"start_obs_capture": 0.04, // 捕获观察前的持续时间
"time_step_timeout_factor": 1.0, // 时间步长最大弹性
"act_buf_len": 2, // 观察中动作历史长度(RNN设为1)
"benchmark": false, // 设为true启用环境基准测试
"wait_on_done": true, // true
"ep_max_length": 1000 // 超过此步数后截断回合
},
"REWARD_CONFIG": {
"END_OF_TRACK": 100.0, // 到达终点线的奖励
"CONSTANT_PENALTY": 0.0, // 每个时间步的固定奖励
"CHECK_FORWARD": 500, // 从上一点计算的最大前进距离
"CHECK_BACKWARD": 10, // 从上一点计算的最大后退距离
"FAILURE_COUNTDOWN": 10, // 此时间步数后提前终止
"MIN_STEPS": 70, // 提前终止生效前的时间步数
"MAX_STRAY": 100.0 // 距离示范轨迹过远时提前终止
}
}
}
带赛道进度的LIDAR
如果你看过Underscore_脱口秀的2022年6月8日一集(法语),请注意你看到的策略是在LIDAR环境的一个稍微增强版本中训练的:除了LIDAR和速度值外,我们还添加了一个代表赛道完成百分比的值,这样模型就可以提前知道转弯情况,类似于人类在特定赛道上练习。
这个环境不会在比赛中被接受,因为它事实上降低了泛化性。
然而,如果你希望使用这个环境,例如,为了打破我们的记录,你可以使用以下config.json
:
{
"ENV": {
"RTGYM_INTERFACE": "TM20LIDARPROGRESS", // TrackMania 2020带激光雷达和完成百分比
"WINDOW_WIDTH": 958, // 游戏窗口宽度(最小:256)
"WINDOW_HEIGHT": 488, // 游戏窗口高度(最小:128)
"SLEEP_TIME_AT_RESET": 1.5, // 每次重置后环境休眠的时间
"IMG_HIST_LEN": 4, // 观察中激光雷达测量历史记录的长度(对RNN设为1)
"RTGYM_CONFIG": {
"time_step_duration": 0.05, // 时间步长的持续时间
"start_obs_capture": 0.04, // 开始捕获观察前的持续时间
"time_step_timeout_factor": 1.0, // 时间步长的最大弹性
"act_buf_len": 2, // 观察中动作历史记录的长度(对RNN设为1)
"benchmark": false, // 设为true时启用环境基准测试
"wait_on_done": true, // true
"ep_max_length": 1000 // 超过这个时间步数后截断回合
},
"REWARD_CONFIG": {
"END_OF_TRACK": 100.0, // 到达终点线的奖励
"CONSTANT_PENALTY": 0.0, // 每个时间步的恒定奖励
"CHECK_FORWARD": 500, // 从上一点计算的最大前进距离
"CHECK_BACKWARD": 10, // 从上一点计算的最大后退距离
"FAILURE_COUNTDOWN": 10, // 这个时间步数后提前终止
"MIN_STEPS": 70, // 提前终止开始生效前的时间步数
"MAX_STRAY": 100.0 // 距离演示轨迹太远时提前终止
}
}
}
TrackMania训练细节
在示例的tmrl
流程中,一个对驾驶甚至对道路一无所知的AI(策略)被放置在赛道的起点。它的目标是通过探索自身能力和环境来学习如何尽可能快地完成赛道。
汽车将图像等观察结果输入人工神经网络,该网络必须从这些观察结果中输出最佳可能的控制。这意味着AI必须以某种方式理解其环境。为了实现这种理解,它会探索世界几个小时(最多几天),逐渐获得如何有效行动的认知。这是通过深度强化学习(RL)实现的。
强化学习基础
大多数RL算法都基于一种称为马尔可夫决策过程(MDP)的环境数学描述。通过RL训练的策略与MDP的交互如下:
在这个图示中,策略被表示为火柴人,时间被表示为固定持续时间的时间步。在每个时间步,策略根据观察结果计算一个动作(油门、刹车和转向的浮点值)。该动作被应用于环境,在转换结束时产生新的观察结果。
为了训练这个策略,环境还提供另一个信号,称为"奖励"。RL受行为主义启发,行为主义依赖于一个基本思想,即智能是正面和负面刺激历史的结果。AI在每个时间步收到的奖励是衡量其表现好坏的指标。
为了学习如何驾驶,AI尝试对传入的观察结果做出随机动作,获得正面或负面奖励,并优化其策略以最大化长期奖励。
软演员-评论家算法
(介绍视频)
(完整论文)
软演员-评论家(SAC)算法能够学习连续的随机控制器。
具体来说,SAC使用两个独立的人工神经网络(NNs)来实现这一点:
- 第一个称为"策略网络"(或在文献中称为"演员"),是用户最终感兴趣的NN:汽车的控制器。它以观察结果为输入,输出动作。
- 第二个称为"价值网络"(或在文献中称为"评论家"),用于训练策略网络。它以观察结果
x
和动作a
为输入,输出一个价值。这个价值是AI观察到x
,选择a
,然后永远使用策略网络的预期未来奖励总和的估计(还有一个折扣因子,使这个总和不是无限的)。
两个网络使用彼此并行训练。奖励信号用于训练价值网络,价值网络用于训练策略网络。
SAC相对于其他现有方法的优势如下:
- 它能够将转换存储在一个巨大的循环缓冲区中,称为"重放记忆",并在训练期间多次重用这些转换。这对于TrackMania等应用来说是一个重要特性,因为由于实时环境的性质,只能收集相对少量的转换。
- 它能够输出模拟控制。我们在虚拟游戏手柄上使用这一特性。
- 它最大化学习策略的熵。这意味着策略在最大化奖励的同时会尽可能随机。这一特性有助于探索环境,并且已知能产生对外部扰动具有鲁棒性的策略,这在现实世界的自动驾驶场景中至关重要。
随机化集成双Q学习
(完整论文)
REDQ是一种更新的方法,可以提高像SAC这样的基于价值的算法的性能。 REDQ的改进主要包括训练一组并行的价值网络集合,在训练过程中从中随机抽样一个子集来评估目标值。作者表明,这能够实现低偏差的更新,样本效率可与基于模型的算法相媲美,同时计算成本更低。
默认情况下,tmrl
使用普通的SAC来训练策略。要使用REDQ-SAC,请在用于训练的机器上编辑TmrlData\config\config.json
,将"ALGORITHM"
条目中的"SAC"
值替换为"REDQSAC"
。你还需要为"REDQ_N"
,"REDQ_M"
和"REDQ_Q_UPDATES_PER_POLICY_UPDATE"
条目设置值,其中"REDQ_N"
是并行评论者的数量,"REDQ_M"
是子集的大小,"REDQ_Q_UPDATES_PER_POLICY_UPDATE"
是每次演员更新之间发生的评论者更新次数。
例如,使用REDQ-SAC的有效"ALG"
条目如下:
"ALG": {
"ALGORITHM": "REDQSAC",
"LEARN_ENTROPY_COEF":false,
"LR_ACTOR":0.0003,
"LR_CRITIC":0.00005,
"LR_ENTROPY":0.0003,
"GAMMA":0.995,
"POLYAK":0.995,
"TARGET_ENTROPY":-7.0,
"ALPHA":0.37,
"REDQ_N":10,
"REDQ_M":2,
"REDQ_Q_UPDATES_PER_POLICY_UPDATE":20
},
巧妙的奖励
如前所述,需要一个奖励函数来评估策略的表现。
可以使用多种奖励函数。例如,可以直接使用汽车的原始速度作为奖励。这是有道理的,因为汽车在撞车时会减速,而在表现良好时会快速行驶。
然而,这种方法过于简单。赛车的实际目标并不是尽可能快地移动。相反,我们希望在最短的时间内完成最长的赛道部分。这并不等同于考虑最佳轨迹,可能需要在急转弯时减速以便通过每个弯道的顶点。
在TrackMania 2020中,我们使用了一个更先进且概念上更有趣的奖励函数:
对于给定的赛道,我们记录一条单一的示范轨迹。这不必是一个好的示范,只需要沿着赛道行驶即可。一旦记录了示范轨迹,它会自动被分割成等距的点。
在训练过程中,每个时间步的奖励就是自上一个时间步以来汽车通过的这些点的数量。简而言之,之前的奖励函数是测量汽车的速度有多快,而这个新的奖励函数则是测量汽车在给定时间内覆盖赛道大部分的能力。
可用的动作空间
在tmrl
中,可以通过两种不同的方式控制汽车:
- 策略可以通过模拟XBox360控制器来使用模拟输入控制汽车,这要归功于vgamepad库。
- 策略可以输出简单的(二进制)箭头按键。
可用的观察空间
TrackMania管道中提供了不同的观察空间:
- 原始截图的历史记录(通常是4张)。
- 在带有黑色边界的赛道中,从原始截图计算得出的LIDAR测量历史记录。
此外,管道还提供速度范数作为观察空间的一部分。
TrackMania Nations Forever中tmrl
环境的示例,使用单个LIDAR测量:
在TrackMania Nations Forever中,我们曾经使用1-NN算法从截图中计算原始速度。
在TrackMania 2020中,我们现在使用OpenPlanet API直接获取原始速度。
结果
在以下实验中,除了原始速度外,蓝色汽车使用单个LIDAR测量,而红色汽车使用4个LIDAR测量的历史记录。 这个动画中两辆车的位置是以恒定的时间间隔捕捉的:
蓝色汽车学会了以恒定速度行驶,这是它从简单的观察空间中能做到的最好结果。相比之下,红色汽车能够从4个LIDAR的历史记录中推断出高阶动态,成功学会了刹车、通过弯道顶点,然后在这个急转弯后再次加速,在这种情况下稍微表现得更好。
框架细节
实时Gym框架:
本项目使用Real-Time Gym (rtgym
),这是一个简单的Python框架,可以在实际应用中高效实现延迟马尔可夫决策过程。
rtgym
对发送动作和检索观察的时间进行了如下约束:
时间步被弹性地限制在其标称持续时间内。当无法满足这种弹性约束时,上一个时间步会超时,新的时间步从当前时间戳开始。
tmrl
使用的Trackmania自定义rtgym
接口在custom_gym_interfaces.py中实现。
远程训练架构:
tmrl
基于tlspyo构建。
其客户端-服务器架构类似于Ray RLlib。
tmrl
并非旨在与Ray竞争,但它更容易适应以实现特定的流程,并且可以同时在Windows和Linux上运行。
tmrl
从多个rollout工作节点(通常是多台计算机和/或机器人)收集训练样本。
每个rollout工作节点将收集的样本存储在本地缓冲区中,并定期将此重放缓冲区发送到中央服务器。
每个rollout工作节点还会定期从中央服务器接收新的策略权重并更新其策略网络。
中央服务器可以位于其中一台rollout工作节点计算机的本地主机上,也可以位于本地网络的另一台计算机上,或者位于互联网上的另一台计算机上。 它从所有连接的rollout工作节点收集样本,并将这些样本存储在本地缓冲区中。 然后,这个缓冲区会被发送到训练器接口。 中央服务器从训练器接口接收更新后的策略权重,并将其广播到所有连接的rollout工作节点。
训练器接口通常位于本地网络中的非rollout工作节点计算机上,或者位于互联网上的另一台机器上(例如,GPU集群)。 当然,在需要时也可以将所有内容都放在本地主机上。 训练器接口定期接收中央服务器收集的样本,并将这些样本附加到重放内存中。 它会定期将新的策略权重发送到中央服务器。
这些机制总结如下:
开发路线图:
欢迎对tmrl
做出贡献。
请考虑以下方面:
- 进一步的性能分析和代码优化,
- 找到最清晰的方法来支持
Memory
中的序列以进行RNN训练。
您可以在讨论区讨论贡献项目。
作者:
在贡献时,请提交一个PR,在贡献者列表中添加您的名字和简短说明。
维护者:
- Yann Bouteiller
- Edouard Geze
贡献者:
- Simon Ramstedt - 初始代码库
- AndrejGobeX - 屏幕捕捉优化(TrackMania)
- Pius - Linux支持(TrackMania)
许可证
MIT,Bouteiller和Geze。
赞助商:
非常感谢我们的赞助商的支持!