ML-Agents 学习环境设计指南:从场景搭建到训练闭环的完整实践
【免费下载链接】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
导读
本文基于 Unity ML-Agents Toolkit 官方文档《Designing a Learning Environment》,系统讲解如何把一个普通 Unity 场景改造成可用于强化学习训练的学习环境(Learning Environment)。你将掌握:Academy 如何编排训练循环、如何组织场景与多训练区域、如何使用EnvironmentParameters配合课程学习与环境参数随机化、如何用StatsRecorder在 TensorBoard 中监控环境内统计指标,并了解从 Agent 到训练闭环的完整设计思路。文中所有结论均可在当前仓库的 Runtime 源码与示例环境中验证。
一、训练与仿真流程:Academy 如何驱动一个 Episode
ML-Agents 中,训练与仿真都以"步(step)"为单位推进,由 Academy 类统一编排。Academy 是场景中的单例,它不直接写游戏逻辑,而是通过事件与场景中所有 Agent 同步协作,保证"所有 Agent 先观测、再决策、后行动"的严格顺序。
从 Academy.cs 的EnvironmentStep()实现可以看到,每个环境步内部依次触发:AgentPreStep、AgentIncrementStep、AgentSendState(收集观测)、DecideAction(策略决策)、AgentAct(执行动作)。官方文档将其概括为以下循环:
- 调用 Academy 的
OnEnvironmentReset委托(仅在回合开始/重置时); - 对场景中每个 Agent 调用
OnEpisodeBegin(); - 收集场景信息:对每个 Agent 调用
CollectObservations(VectorSensor sensor),并更新其传感器、汇总观测; - 使用每个 Agent 的 Policy 决定下一步动作;
- 对每个 Agent 调用
OnActionReceived(),传入 Policy 选出的动作; - 若 Agent 达到
Max Step或自行调用EndEpisode(),则触发该 Agent 的OnEpisodeBegin()进入下一回合。
训练时,外部 Python 训练进程通过通信器与 Academy 交换数据,运行一系列回合(episode)来收集经验并优化神经网络模型;训练完成后,把导出的模型文件放进 Unity 项目即可用于推理。开发者需要做的是继承Agent类,按需实现上述方法。
从源码看,Academy的步进默认挂载在FixedUpdate阶段(Academy.cs 中的AcademyFixedUpdateStepper),可通过AutomaticSteppingEnabled属性关闭自动步进、改由用户手动调用Academy.EnvironmentStep(),这为回合制等特殊时序场景提供了灵活性。
二、组织 Unity 场景:Academy、多区域与环境重置
2.1 Academy:唯一编排者
Academy 是单例,同一时刻只存在一个实例(Academy.cs 中通过Lazy<Academy>模式实现)。首次访问Academy.Instance时触发初始化:注册环境参数与统计通道、尝试与 Python 训练进程建立通信,并决定当前是训练模式还是推理模式(Academy.cs)。
2.2 Academy 重置:在每回合开始前改造环境
要在每个 episode 开始时改变环境(例如重置 Agent 到初始位置、把目标随机摆放),把自定义方法挂到 Academy 的OnEnvironmentReset委托上:
public class MySceneBehavior : MonoBehaviour { public void Awake() { Academy.Instance.OnEnvironmentReset += EnvironmentReset; } void EnvironmentReset() { // Reset the scene here } }外部训练进程调用 Python 端UnityEnvironment的reset()方法时,就会触发环境重置。设计重置逻辑时,要思考哪些因素应该变化,以便训练结果具备泛化性。例如训练一个走迷宫 Agent,如果每个 episode 都用同一个迷宫,Agent 学到的只是"这一个迷宫"的解法,而不是"迷宫"这一类问题。
2.3 多训练区域(Multiple Areas):并行收集经验
许多示例环境会在场景中实例化多份训练区域,从而并行收集大量经验、显著加速训练。实现方式很简单:在同一场景中放置多个 Behavior Name 相同的 Agent 即可(相同 Behavior Name 的 Agent 共享同一套策略)。设计场景时应尽量考虑支持多区域。
两种常见的多区域做法:
- 手动复制:把整个训练区域(Floor/Agent/目标物)做成 Prefab,在场景中实例化多份、彼此不重叠;
- 自动复制:使用
TrainingAreaReplicator组件(位于 TrainingAreaReplicator.cs),指定Base Area、复制份数与区域间距,运行时自动复制。
更详细的从零搭建与多区域步骤见 Learning-Environment-Create-New.md。
三、训练环境(Environment)的三个硬性要求
当你创建训练环境时,场景必须能被外部训练进程完全控制,文档明确了三点要求:
- 自动启动:Unity 应用被训练进程启动后,训练场景必须自动开始运行;
- 可重置:每个训练回合开始时,Academy 必须把场景重置到合法的初始状态;
- 回合必须有终点:要么设置
Max Steps,要么由每个 Agent 在完成任务后手动调用EndEpisode()结束回合。
这三点缺一不可——没有明确终点的回合会让训练无法形成完整的 episode 结构,进而无法正确计算累积回报。
四、环境参数(Environment Parameters):衔接课程学习与参数随机化
课程学习(Curriculum Learning)与环境参数随机化(Environment Parameter Randomization)是两种通过"控制环境参数"来提升训练效果的方法。为了让 Unity 端及时拿到训练配置中定义的参数值,ML-Agents 暴露了EnvironmentParametersC# 类。
从 EnvironmentParameters.cs 的源码可以看到,它内部通过EnvironmentParametersChannel这一 Side Channel 接收训练进程发来的参数,核心 API 包括:
GetWithDefault(string key, float defaultValue):按 key 读取参数,不存在时返回默认值;RegisterCallback(string key, Action<float> action):注册回调,参数更新时自动触发;Keys():列出所有已收到值的参数 key。
文档建议在 Agent 的OnEpisodeBegin()中通过Academy.Instance.EnvironmentParameters读取并应用参数。WallJump 示例是标准用法——它根据no_wall_height、small_wall_height、big_wall_height三个参数在运行时调整墙的高度(见 WallJumpAgent.cs):
m_ResetParams = Academy.Instance.EnvironmentParameters; // ... var height = m_ResetParams.GetWithDefault("big_wall_height", 8); wall.transform.localScale = new Vector3(localScale.x, height, localScale.z);参数值来自训练配置,相关细节见 Training-ML-Agents.md 中关于 environment parameters 的部分。
五、Agent:观测、行动与回合生命周期
Agent类代表场景中"能观测环境并执行动作"的角色,通常挂载在代表该角色的 GameObject 上(足球比赛中的球员、车辆仿真中的汽车)。每个 Agent 都必须配置合适的Behavior Parameters。
创建 Agent 时,通常继承Agent类并实现两个核心方法:
CollectObservations(VectorSensor sensor):收集 Agent 对环境的状态观测;OnActionReceived():执行 Policy 选出的动作,并为当前状态分配奖励。
这两个方法的具体实现,决定了该 Agent 的Behavior Parameters如何配置(尤其是向量观测的 Space Size 与动作维度)。
回合生命周期方面,你需要在OnActionReceived()中判断任务完成/失败并调用EndEpisode()手动终止回合,或把Max Steps设为正值让 Agent 在走过指定步数后自动结束回合;OnEpisodeBegin()则用于为下一回合重置 Agent。关于 Agent 编程的完整细节(观测生成方式、动作定义、奖励设计、多智能体分组等)见 Learning-Environment-Design-Agents.md。
六、录制统计指标:让环境内部状态进入 TensorBoard
StatsRecorder允许从 Unity 环境内部记录统计值,这些值会在训练过程中被聚合与呈现。从 StatsRecorder.cs 源码看,核心 API 是:
public void Add( string key, float value, StatAggregationMethod aggregationMethod = StatAggregationMethod.Average)关键行为(源码注释中亦有说明):
- 统计值通过
StatsSideChannel发送,最终出现在 TensorBoard summary 与 trainer gauges 中; - 支持在 key 中用
/嵌套分组,例如"Agent/Health"与"Agent/Wallet"; - 统计值只在每个
summary_frequency步写入一次 TensorBoard,同一窗口内多次上报的值按StatAggregationMethod聚合; - 聚合方式共有四种(StatsRecorder.cs):
Average(默认):窗口内取平均;MostRecent:只保留最近一次值(多环境并行时仅跟踪 worker 0 的统计,避免冲突);Sum:窗口内求和;Histogram:以直方图形式报告。
FoodCollector 示例展示了标准用法(FoodCollectorSettings.cs)——在Awake()中取得Academy.Instance.StatsRecorder,每 100 帧上报一次总分:
m_Recorder = Academy.Instance.StatsRecorder; // ... if ((Time.frameCount % 100) == 0) { m_Recorder.Add("TotalScore", totalScore); }注释中特别说明:由于值会按summary_frequency聚合,无需每帧都发送。
七、设计要点总结
- 以 Academy 为编排核心:训练循环由 Academy.cs 统一驱动,开发者只需实现 Agent 的回调方法;
- 重置逻辑决定泛化能力:利用
OnEnvironmentReset在每个 episode 开始时随机化/重置场景要素,避免 Agent 只学会单一布局; - 多区域并行:相同 Behavior Name 的多个 Agent 天然共享策略、并行收集经验,是官方示例中最常见的加速手段;
- 环境参数:用
Academy.Instance.EnvironmentParameters.GetWithDefault(key, default)在OnEpisodeBegin()中读取课程学习/参数随机化产生的值(参考 WallJumpAgent.cs); - 统计监控:用
Academy.Instance.StatsRecorder.Add(key, value, aggregationMethod)上报环境内部指标,可在 TensorBoard 中按summary_frequency聚合查看(参考 FoodCollectorSettings.cs)。
若需要深入了解 Agent 的观测、动作与奖励设计,或从零搭建一个完整训练环境,请继续阅读同一文档目录下的 Learning-Environment-Design-Agents.md 与 Learning-Environment-Create-New.md。
【免费下载链接】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),仅供参考