ML-Agents 机器学习背景指南:从无监督学习到强化学习与 Unity 训练闭环
【免费下载链接】ml-agentsThe Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.项目地址: https://gitcode.com/gh_mirrors/ml/ml-agents
本文面向不熟悉机器学习(Machine Learning)背景的 Unity 开发者与 ML-Agents Toolkit 使用者,系统梳理机器学习的三大核心范式——无监督学习、监督学习与强化学习——并深入剖析与 ML-Agents 最密切相关的强化学习原理:策略(Policy)、观察(Observation)、动作(Action)与奖励信号(Reward Signal),最后结合训练(Training)与推理(Inference)两个阶段,讲解 ML-Agents 如何在 Unity 模拟环境中借助深度学习(PyTorch)完成智能体行为训练。读完本文,你将掌握 ML-Agents 底层所依赖的机器学习术语与概念,理解Agent、Behavior、奖励信号与训练配置(如gamma、lambd、batch_size)之间的对应关系,为后续阅读 Training-ML-Agents 训练指南、训练配置文件说明 打下坚实基础。
机器学习是人工智能的一个分支,核心目标是从数据中学习模式(patterns)。机器学习算法大致可以分为三大类:无监督学习(Unsupervised Learning)、监督学习(Supervised Learning)与强化学习(Reinforcement Learning),每一类算法从不同类型的数据中学习。下面分别对每一类算法进行概述,并给出贴近游戏与 Unity 场景的入门示例。
无监督学习:从无标签数据中发现结构
无监督学习的目标是对数据集中的相似条目进行分组或聚类(cluster)。考虑一个游戏中的玩家群体:我们可能希望根据玩家对游戏的参与度对其进行分组,从而对不同群体采取差异化运营策略(例如,对高参与度玩家邀请其成为新功能的内测用户,对低参与度玩家发送新手教程邮件)。
假设我们希望把玩家分成两组。首先定义玩家的基本属性(attributes),例如游戏时长(hours played)、内购总花费(total money spent)、通关关卡数(levels completed)。然后将这份数据集(每个玩家对应三个属性值)送入无监督学习算法,并指定分组数量为 2。算法会自动把玩家数据集切分成两组,组内玩家彼此相似。基于上述属性,输出结果通常语义上对应"高参与度玩家"与"低参与度玩家"两组。
值得注意的是,无监督学习中我们没有提供任何关于"哪些玩家算参与度高、哪些算参与度低"的示例标签,只定义了合适的属性,并依赖算法自行发现这两个分组。这类数据集通常被称为无标签数据集(unlabeled data set)。因此,当标签获取成本高昂或难以人工标注时,无监督学习非常有用。下一节将介绍监督学习——它在属性之外还接受输入标签。
监督学习:从属性-标签对学习映射
监督学习不满足于仅仅对相似条目分组,而是希望直接学习从每个条目到其所属分组(或类别)的映射(mapping)。回到玩家聚类的例子:现在我们希望预测哪些玩家即将流失(churn,即未来 30 天停止游玩)。我们可以查阅历史记录,构造一个数据集:包含玩家属性,外加一个标签(label),标明该玩家是否已经流失。注意,用于流失预测的属性与前面聚类任务所用的属性可能不同。
将这份"属性 + 标签"的数据集送入监督学习算法后,算法会学习从玩家属性到"是否流失"标签的映射。其内在直觉是:算法会学会哪些属性取值通常对应流失玩家、哪些对应未流失玩家(例如,它可能学到"消费极少且游戏时间极短的玩家最可能流失")。得到这个学习好的模型后,只要给它一个新玩家(如刚注册的玩家)的属性,它就能输出一个预测标签,即算法对该玩家是否会流失的预期。我们可以据此针对预期流失的玩家进行定向挽留。
细心的读者会发现,监督学习与无监督学习都涉及两个需要完成的任务:
- 属性选择(Attribute Selection),又称特征选择(Feature Selection):决定如何表示关注的实体(本例中是玩家);
- 模型选择(Model Selection):选择能较好完成任务的学习算法及其参数。
这两个任务都是机器学习研究的活跃方向,在实践中通常需要多次迭代才能获得良好性能。
强化学习:顺序决策与智能体行为训练
强化学习可以被看作一种**面向顺序决策(sequential decision making)**的学习形式,通常与控制机器人相关联(但事实上其适用范围远不止于此)。设想一个自主消防机器人,其任务是在一片区域内导航、发现火情并将其扑灭。在任意时刻,机器人通过传感器(摄像头、热敏、触觉)感知环境,处理这些信息并产生一个动作(向左移动、旋转水管、打开水阀)。换句话说,它基于自己对世界的感知(传感器输入)和目标(扑灭火情),持续不断地做出与环境交互的决策。训练一个成功的消防机器人,正是强化学习所擅长的事情。
策略、观察、动作与奖励信号:强化学习的四要素
更具体地说,强化学习的目标是学习一个策略(Policy)——本质上是从**观察(Observations)到动作(Actions)**的映射:
- 观察(Observation):机器人能从其**环境(Environment)**中测量到的内容(本例中为它的全部感官输入);
- 动作(Action):最原始的形式是对机器人配置的改变(例如底座位置、水管位置、水阀开关状态);
- 策略(Policy):在给定观察的情况下,选择动作的映射关系;
- 奖励信号(Reward Signal):强化学习任务中最后一块拼图。机器人被训练去学习一个能**最大化其累计奖励(overall rewards)**的策略。
训练消防机器人时,我们提供正负奖励来指示它在完成任务上的表现。注意,机器人在训练前并不知道如何灭火——它之所以学会目标,是因为扑灭火情时获得大的正奖励、而每流逝一秒获得一个小的负奖励。**奖励稀疏(sparse)**这一特性(奖励并非每步都提供,而是当机器人到达成功或失败局面时才给出)是强化学习的定义性特征,也正是在复杂环境中学习良好策略之所以困难(且耗时)的原因。
在 ML-Agents 中,这三个要素在 Unity 侧由 Agent.cs 及其子类承载:Agent 通过CollectObservations(VectorSensor)收集观察(对应 Observation),通过OnActionReceived(ActionBuffers)接收并执行动作(对应 Action,由 ActuatorManager.cs 在决策后统一分发到各 Actuator),并通过AddReward(float)/SetReward(float)增量式或覆盖式地给予当前步的奖励(对应 Reward Signal)。从源码注释可见,ML-Agents 明确要求奖励通常在OnActionReceived实现中、执行完动作并评估其成败之后进行分配,这正是"奖励反映目标达成程度"这一强化学习原则的落地。
强化学习生命周期:模拟器为何是理想训练场
下图展示了强化学习的完整生命周期:
学习一个策略通常需要大量试验与迭代式的策略更新。具体而言,机器人被置于多种火灾场景中,随着时间推移学到能够更有效灭火的(近似)最优策略。显然,我们不可能期望在真实世界中反复训练机器人——尤其当涉及火灾时。这正是Unity 作为模拟器成为学习此类行为理想训练场的原因:通过在 Unity 内生成成千上万次环境仿真,可以为非常复杂的环境(观察数量多、动作空间大的环境)学习策略。
虽然上文围绕机器人展开讨论,但机器人与游戏角色之间有着强烈的对应关系。事实上,在很多时候我们可以把非玩家角色(NPC)看作一个虚拟机器人:它有自己的环境观察、自己的动作集合、以及一个明确的目标。因此,在 Unity 中利用强化学习训练 NPC 行为是顺理成章的——这正是 ML-Agents Toolkit 所提供的能力。
与无监督学习、监督学习类似,强化学习同样涉及两个任务:属性选择(为机器人定义最能帮助其完成目标的观察集合)与模型选择(定义策略的形式——即从观察到动作的映射——及其参数)。实践中,训练行为是一个迭代过程,可能需要反复调整属性与模型的选择。
从源码结构看,ML-Agents 的强化学习训练器正是围绕"观察→动作→奖励→更新策略"这一闭环组织的:ml-agents/mlagents/trainers/trajectory.py中的Trajectory将单个智能体的一条经验轨迹(observation-action-reward 序列)打包,ml-agents/mlagents/trainers/buffer.py中的AgentBuffer负责存储与采样这些经验,而ml-agents/mlagents/trainers/agent_processor.py中的AgentProcessor则将环境返回的决策步(DecisionSteps)与终止步(TerminalSteps)转化为训练器可用的经验。这也印证了原文档所述:强化学习的数据集是一系列"观察-动作-奖励"三元组(observation-action-reward tuples)。
训练与推理:机器学习的三阶段共性
机器学习三个分支(无监督、监督、强化)的一个共同点是它们都包含训练阶段(Training Phase)与推理阶段(Inference Phase)。虽然三者的训练与推理细节各不相同,但从高层看:训练阶段是利用给定数据构建模型,推理阶段则是将模型应用于新的、未见过的数据。具体到三类算法:
- 无监督学习示例:训练阶段基于既有玩家数据学习最优的两个聚类;推理阶段把新玩家分配到这两个聚类之一。
- 监督学习示例:训练阶段学习从玩家属性到玩家标签(是否流失)的映射;推理阶段基于该映射预测新玩家是否会流失。
- 强化学习示例:训练阶段通过引导式试验学习最优策略;推理阶段智能体在真实场景中利用学到的策略进行观察并采取动作。
简而言之:三类算法都包含训练与推理阶段,以及属性选择与模型选择;真正区分它们的是可用于学习的数据类型——无监督学习的数据集是属性集合,监督学习的数据集是属性-标签对集合,强化学习的数据集是观察-动作-奖励三元组集合。
ML-Agents 中的训练与推理落地
在 ML-Agents 中,这一区分体现得非常直观。训练时,Unity 场景中所有 Agent 通过外部通信器(External Communicator)把观察发送给 Python 训练进程,Python 侧的训练器(Trainer)处理这些观察并回传动作;训练期间动作主要是探索性的,以帮助训练器学到最优策略。训练结束后,学习到的策略被导出为模型文件(.onnx);推理阶段 Agent 仍然产生观察,但不再发送给 Python,而是喂给嵌入 Unity 内部(基于 Sentis 推理引擎)的模型,直接生成每个时刻的最优动作。
从源码可以确认这条链路的两端:
- 训练端:learn.py 是 Python 侧命令行工具
mlagents-learn的入口;训练器按算法类型组织在ml-agents/mlagents/trainers/ppo/、ml-agents/mlagents/trainers/sac/、ml-agents/mlagents/trainers/poca/等目录下。以 ppo/trainer.py 中的PPOTrainer._process_trajectory为例,它依次完成:更新观察归一化、利用 Critic 网络估计轨迹各步的价值(value estimates)、评估各奖励信号(reward signals)并乘以强度(strength)、用 GAE(Generalized Advantage Estimation,get_gae)计算优势与回报(returns)、最后写入更新缓冲区供策略更新使用。 - 推理端:Unity 侧 Agent.cs 的
SetModel(behaviorName, model, inferenceDevice)接口将训练产出的模型绑定到 Agent 上并触发ReloadPolicy(),此后 Agent 的策略工厂将基于该模型生成内部推理策略(SentisPolicy),完成从"训练阶段"到"推理阶段"的切换。
奖励信号在训练器中的实现
原文档强调"奖励是任务目标向智能体传达的方式,最大化奖励即可生成期望的最优行为"。ML-Agents 把这一思想工程化为**模块化的奖励信号(Reward Signals)**机制:ml-agents/mlagents/trainers/reward_provider/目录下实现了外源奖励(extrinsic)、好奇心奖励(curiosity)、GAIL 奖励、RND 奖励等多种提供器,训练时每个信号的奖励会乘以各自的strength后累加(见 ppo/trainer.py 中evaluate_result = reward_signal.evaluate(...) * reward_signal.strength),其核心在于将环境定义的外源奖励与算法定义的内源奖励(intrinsic rewards)统一为智能体要最大化的总奖励。这与 ML-Agents-Overview.md 中对"外源奖励(由环境定义、对应达成目标)"与"内源奖励(在环境之外定义、用于引导行为或辅助学习)"的区分完全一致。
训练配置中的强化学习超参数
原文档指出模型选择(选择算法及其参数)是强化学习的核心任务之一。这一任务在 ML-Agents 中通过 YAML 训练配置文件落地,仓库内 config/ppo/3DBall.yaml 是一个典型示例:
behaviors: 3DBall: trainer_type: ppo hyperparameters: batch_size: 64 # 每次梯度更新使用的经验条数 buffer_size: 12000 # 更新缓冲区容量(收集多少经验后开始更新) learning_rate: 0.0003 # 学习率 beta: 0.001 # 熵正则项强度(鼓励探索) epsilon: 0.2 # PPO 裁剪范围 lambd: 0.99 # GAE 的 λ 参数(优势估计的偏差-方差权衡) num_epoch: 3 # 每次更新遍历缓冲区的轮数 learning_rate_schedule: linear network_settings: normalize: true hidden_units: 128 num_layers: 2 vis_encode_type: simple reward_signals: extrinsic: gamma: 0.99 # 折扣因子:衡量未来奖励的权重 strength: 1.0 # 奖励信号强度 keep_checkpoints: 5 max_steps: 500000 time_horizon: 1000 summary_freq: 12000其中与强化学习原理直接相关的参数包括:gamma(折扣因子,决定智能体对远期奖励的重视程度,对应"最大化未来累计奖励"中的"未来"权重)、lambd(GAE 的优势估计平滑参数)、beta(熵正则,鼓励探索以缓解"奖励稀疏导致学习困难"的问题)、epsilon(PPO 策略更新裁剪幅度,控制每次更新的激进程度)。这些参数在 settings.py 中定义了默认值与类型校验规则,并在 PPO 训练器的 GAE 计算中被实际使用(见 ppo/trainer.py 中get_gae(rewards=..., value_estimates=..., gamma=..., lambd=...))。
深度学习:从大量数据中学习复杂函数
深度学习是一族可用于解决上述任何一类问题的算法,它既能解决属性选择任务,也能解决模型选择任务。近年来深度学习广受欢迎,得益于其在多个困难机器学习任务上的出色表现,一个著名例子是 AlphaGo——一个借助深度学习的计算机围棋程序,它击败了围棋世界冠军李世石。
深度学习算法的关键特征是其从大量训练数据中学习非常复杂函数的能力。这使其天然适合强化学习任务——尤其是当数据可以通过模拟器(如 Unity)大量生成时。通过在 Unity 内生成数十万次环境仿真,我们可以为非常复杂的环境(智能体感知的观察数量多、可执行动作数量多的环境)学习策略。
ML-Agents 中的深度学习:PyTorch 与模型导出
原文档指出,ML-Agents 提供的许多算法都使用某种形式的深度学习,构建于开源库PyTorch之上。这与仓库结构完全吻合:
- Python 训练侧的神经网络实体(编码器、网络主体、动作模型、价值网络等)集中在
ml-agents/mlagents/trainers/torch_entities/目录(如networks.py中的NetworkBody、ActorCritic,encoders.py中的向量/视觉编码器,action_model.py中的动作采样模型); - PPO、SAC、POCA 等训练器的优化器均为 PyTorch 实现(见
ml-agents/mlagents/trainers/ppo/optimizer_torch.py等文件),PPOTrainer.create_policy中通过SimpleActor或SharedActorCritic构建策略网络(ppo/trainer.py); - 训练完成后,策略通过
ml-agents/mlagents/trainers/torch_entities/model_serialization.py的export_policy_model导出为.onnx 模型文件,供 Unity 推理阶段使用;Unity 侧由com.unity.ml-agents/Runtime/Inference/目录下的 Sentis 推理代码加载执行。
根据 Background-PyTorch.md 的说明:除非你自己实现新的算法,否则 PyTorch 的使用大多被抽象封装、在后台进行——训练一个 Agent 行为的直接产出就是一个 .onnx 模型文件,随后可将其关联到 Agent 上。
用 TensorBoard 观察训练中的超参数影响
用 PyTorch 训练模型的一个关键环节是为模型的部分属性(称为超参数(hyperparameters))设置取值,而找到合适的超参数取值通常需要多次迭代。为此,ML-Agents 借助可视化工具TensorBoard来观察训练过程中 Agent 的各类属性(例如奖励)的变化,这有助于建立对不同超参数的直觉,并为你的 Unity 环境设置最优取值。训练时每个训练器会周期性地(由配置文件中的summary_freq控制)把奖励、价值估计、损失等统计量写入 TensorBoard 事件文件(统计写入实现在ml-agents/mlagents/trainers/stats.py中)。更详细的超参数设置说明参见 Training-ML-Agents,TensorBoard 的具体使用方式参见 Using-Tensorboard 指南。
总结
回到本文开篇的问题:机器学习三大范式——无监督学习(聚类无标签数据)、监督学习(从属性-标签对学习映射)、强化学习(从观察-动作-奖励三元组学习策略)——共同构成了 ML-Agents Toolkit 的理论基石。其中与 ML-Agents 关系最紧密的强化学习,通过"策略 = 从观察到动作的映射"这一核心定义,与 Unity 场景中的 Agent、Behavior、观察传感器、动作执行器和奖励信号一一对应;而"训练阶段(在模拟器中用大量试验学习策略)→ 推理阶段(在游戏运行时用学到的模型做决策)"的划分,则对应 ML-Agents 中"Python 训练器 + PyTorch 训练产出 .onnx 模型"与"Unity 内嵌 Sentis 推理"的完整闭环。理解了这些基础概念,再阅读仓库文档中的 ML-Agents 理论总览、训练指南 与 训练配置文件说明,你将能够更快地进入实际的 Agent 设计与训练实践。
【免费下载链接】ml-agentsThe Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.项目地址: https://gitcode.com/gh_mirrors/ml/ml-agents
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考