资讯动态

Unity ML-Agents Python Optimizer(优化器)机制全解析:TorchOptimizer 架构、奖励信号与价值估计实现

发布时间:2026/9/20 18:43:56 来源:尧图企业网站定制
人工智能强化学习深度学习机器学习游戏开发AI 应用【免费下载链接】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 Toolkitml-agents的训练管线中Optimizer优化器是连接 Policy策略网络、损失函数与奖励信号的枢纽它负责为某个具体训练算法创建价值网络Value/Q 网络与奖励信号辅助网络并在每个 minibatch 上驱动 Policy 的参数更新。本文以仓库内官方 API 文档 Python-Optimizer-Documentation.md 为骨架结合ml-agents/mlagents/trainers/optimizer/下的真实源码系统讲解Optimizer抽象基类与TorchOptimizer基类的设计、create_reward_signals与get_trajectory_value_estimates的核心方法语义并深入 PPO、SAC、POCA 三种内置优化器的实现细节与配置参数。读完本文你将理解 ML-Agents 训练循环中经验缓冲 → 价值估计 → 损失计算 → 参数更新的完整链路并能读懂或扩展自定义优化器。一、Optimizer 在训练管线中的角色在 ml-agents 的 PyTorch 训练实现中每个 trainer训练器都持有一个 Optimizer。优化器的职责在官方文档中定义得非常明确Creates loss functions and auxiliary networks (e.g. Q or Value) needed for training. Provides methods to update the Policy.也就是说Optimizer 承担两件事构建训练所需的辅助网络价值网络Value Network / Q Network、奖励信号网络如 Curiosity 的编码器、GAIL 的判别器、RND 的随机网络提供更新 Policy 的方法接收一个 minibatch计算出 loss执行反向传播与参数更新并返回训练统计信息。在 optimizer/optimizer.py 中基类被定义为抽象类class Optimizer(abc.ABC): Creates loss functions and auxillary networks (e.g. Q or Value) needed for training. Provides methods to update the Policy. def __init__(self): self.reward_signals {} abc.abstractmethod def update(self, batch: AgentBuffer, num_sequences: int) - Dict[str, float]: Update the Policy based on the batch that was passed in. :param batch: AgentBuffer that contains the minibatch of data used for this update. :param num_sequences: Number of recurrent sequences found in the minibatch. :return: A Dict containing statistics (name, value) from the update (e.g. loss) pass基类本身只维护一个reward_signals字典存储每个奖励信号对应的 reward provider 实例并声明了唯一的抽象方法update。任何具体算法优化器都必须实现update——这是训练循环每步都会调用的入口。从源码结构看ml-agents 当前仓库内置了三套具体优化器实现全部继承自TorchOptimizer优化器类对应算法源文件TorchPPOOptimizerPPO近端策略优化on-policyml-agents/mlagents/trainers/ppo/optimizer_torch.pyTorchSACOptimizerSAC软演员-评论家off-policyml-agents/mlagents/trainers/sac/optimizer_torch.pyTorchPOCAOptimizerPOCA多智能体协作on-policyml-agents/mlagents/trainers/poca/optimizer_torch.py它们分别对应仓库ml-agents/mlagents/trainers/下的ppo/、sac/、poca/三个训练器包与 Training-Configuration-File.md 中描述的trainer类型一一对应。二、TorchOptimizer 基类PyTorch 优化器的公共实现TorchOptimizer是文档重点讲解的基类位于 ml-agents/mlagents/trainers/optimizer/torch_optimizer.py定义如下class TorchOptimizer(Optimizer): def __init__(self, policy: TorchPolicy, trainer_settings: TrainerSettings): super().__init__() self.policy policy self.trainer_settings trainer_settings self.update_dict: Dict[str, torch.Tensor] {} self.value_heads: Dict[str, torch.Tensor] {} self.memory_in: torch.Tensor None self.memory_out: torch.Tensor None self.m_size: int 0 self.global_step torch.tensor(0) self.bc_module: Optional[BCModule] None self.create_reward_signals(trainer_settings.reward_signals) ...构造时它持有 Policy 与 TrainerSettings 的引用并在初始化阶段立刻调用create_reward_signals创建奖励信号同时它负责管理记忆memory相关的张量memory_in/memory_out/m_size、价值头value_heads以及可选的行为克隆模块bc_module当trainer_settings.behavioral_cloning非空时创建见 BCModule。TorchOptimizer提供了两类半成品实现子类只需补齐critic属性与update方法即可create_reward_signals奖励信号工厂get_trajectory_value_estimates/_evaluate_by_sequence/update_reward_signals轨迹级价值估计与奖励信号更新。2.1 create_reward_signals奖励信号工厂官方文档给出的签名create_reward_signals(reward_signal_configs: Dict[RewardSignalType, RewardSignalSettings]) - NoneCreate reward signalsArguments:reward_signal_configs: Reward signal config.源码实现位于 torch_optimizer.py#L53-L64def create_reward_signals( self, reward_signal_configs: Dict[RewardSignalType, RewardSignalSettings] ) - None: Create reward signals :param reward_signal_configs: Reward signal config. for reward_signal, settings in reward_signal_configs.items(): # Name reward signals by string in case we have duplicates later self.reward_signals[reward_signal.value] create_reward_provider( reward_signal, self.policy.behavior_spec, settings )它遍历配置字典对每个RewardSignalType调用create_reward_provider工厂函数以奖励信号类型字符串reward_signal.value为 key 存入self.reward_signals。注意 key 使用字符串而非枚举值注释说明这是为了避免后续出现重复信号名。工厂函数位于 reward_provider_factory.pyNAME_TO_CLASS: Dict[RewardSignalType, Type[BaseRewardProvider]] { RewardSignalType.EXTRINSIC: ExtrinsicRewardProvider, RewardSignalType.CURIOSITY: CuriosityRewardProvider, RewardSignalType.GAIL: GAILRewardProvider, RewardSignalType.RND: RNDRewardProvider, } def create_reward_provider( name: RewardSignalType, specs: BehaviorSpec, settings: RewardSignalSettings ) - BaseRewardProvider: rcls NAME_TO_CLASS.get(name) if not rcls: raise UnityTrainerException(fUnknown reward signal type {name}) class_inst rcls(specs, settings) return class_inst可见当前仓库支持四种奖励信号类型对应 settings.py#L180-L184 中定义的枚举class RewardSignalType(Enum): EXTRINSIC: str extrinsic GAIL: str gail CURIOSITY: str curiosity RND: str rndextrinsic环境直接给出的奖励默认信号ExtrinsicRewardProvidercuriosity基于状态预测误差的内在好奇心奖励CuriosityRewardProvidergail生成对抗模仿学习奖励GAILRewardProviderrnd随机网络蒸馏Random Network Distillation奖励RNDRewardProvider。每个奖励信号的通用配置在RewardSignalSettingssettings.py#L196-L200中定义gamma0.99折扣因子、strength1.0奖励强度系数、network_settings该信号网络的隐层配置。GAIL、Curiosity、RND 还各自带learning_rate、encoding_size、demo_path、use_vail、use_actions等专属字段。TorchPOCAOptimizer覆写了create_reward_signalspoca/optimizer_torch.py#L215-L234除 extrinsic 外的其余奖励信号会打印警告POCA 官方不支持结果可能异常同时会给 ExtrinsicRewardProvider 打开add_groupmate_rewards让智能体学习帮助队友达成个体目标这正是 POCA 多智能体协作特性的体现。2.2 get_trajectory_value_estimates轨迹价值估计与记忆产出官方文档给出的签名get_trajectory_value_estimates(batch: AgentBuffer, next_obs: List[np.ndarray], done: bool, agent_id: str ) - Tuple[Dict[str, np.ndarray], Dict[str, float], Optional[AgentBufferField]]Get value estimates and memories for a trajectory, in batch form.Arguments:batch: An AgentBuffer that consists of a trajectory.next_obs: the next observation (after the trajectory). Used for bootstrapping if this is not a terminal trajectory.done: Set true if this is a terminal trajectory.agent_id: Agent ID of the agent that this trajectory belongs to.Returns: A Tuple of the Value Estimates as a Dict of [name, np.ndarray(trajectory_len)], the final value estimate as a Dict of [name, float], and optionally (if using memories) an AgentBufferField of initial critic memories to be used during update.该方法的完整实现在 torch_optimizer.py#L141-L211。它解决的是强化学习训练中一个经典问题一条完整的 trajectory 结束后如何为其中的每一步计算价值估计value estimate与收益return并为下一条轨迹接续记忆。关键流程如下取初始 critic 记忆以agent_id为 key 从critic_memory_dict中取出上一条轨迹结束时的记忆若该 agent 尚无记忆且 Policy 使用循环网络LSTM则用torch.zeros((1, 1, self.critic.memory_size))初始化torch_optimizer.py#L161-L168。观测转张量通过ObsUtil.from_buffer从 AgentBuffer 读取当前观测next_obs同样转张量并unsqueeze(0)增加 batch 维度。价值前向计算整个计算被包裹在torch.no_grad()中注释明确说明这是为了防止 memory leak 并提升性能torch_optimizer.py#L181-L182使用 LSTM 时调用_evaluate_by_sequence按policy.sequence_length将轨迹切成等长序列逐段评估收集所有中间记忆非循环网络则一次性对整条轨迹做critic.critic_pass。bootstrap 下一步价值对next_obs再做一次critic.critic_pass(..., sequence_length1)得到最终价值估计next_value_estimate——这正是文档所说的Used for bootstrapping。终止轨迹处理若doneTrue对所有不应忽略终止的奖励信号not self.reward_signals[k].ignore_done将next_value_estimate置 0并把该 agent 的记忆从字典中弹出轨迹结束记忆不再延续。返回三件套整条轨迹的value_estimatesDict[name, np.ndarray(trajectory_len)]、最终价值next_value_estimateDict[name, float]、以及使用记忆时返回的all_next_memoriesAgentBufferField作为后续更新时的 critic 初始记忆。_evaluate_by_sequenceLSTM 轨迹的分段评估在循环网络场景下轨迹长度不一定能被sequence_length整除。_evaluate_by_sequencetorch_optimizer.py#L66-L133先把轨迹切成若干完整序列段再单独处理尾部余数段leftover_seq_len num_experiences % sequence_length完整段按[start:end]切片并携带上一段输出的_mem递进评估尾段用轨迹末尾的记忆做初始记忆、以leftover_seq_len为序列长度评估。最终把各段价值torch.cat成每信号一个完整张量返回。该逻辑与训练器写入 buffer 时对最后一段做 padding 的行为是对应的。update_reward_signalstorch_optimizer.py#L135-L139则负责在训练时依次调用每个 reward provider 的update(batch)汇总返回的统计信息def update_reward_signals(self, batch: AgentBuffer) - Dict[str, float]: update_stats: Dict[str, float] {} for reward_provider in self.reward_signals.values(): update_stats.update(reward_provider.update(batch)) return update_stats三、update 抽象方法三种算法优化器的落地Optimizer.update(batch, num_sequences)是训练循环的核心调用点。三种内置优化器各自实现了不同的损失函数与更新策略。3.1 TorchPPOOptimizeron-policy 的信任区域更新PPO 优化器的超参由PPOSettingsppo/optimizer_torch.py#L23-L32定义这也是你可以在 YAML 配置的hyperparameters段中直接书写的字段attr.s(auto_attribsTrue) class PPOSettings(OnPolicyHyperparamSettings): beta: float 5.0e-3 # 熵正则系数 epsilon: float 0.2 # 裁剪阈值 lambd: float 0.95 # GAE 参数 num_epoch: int 3 # 每个 minibatch 的更新轮数 shared_critic: bool False # 是否共享 actor/critic 网络 learning_rate_schedule: ScheduleType ScheduleType.LINEAR beta_schedule: ScheduleType ScheduleType.LINEAR epsilon_schedule: ScheduleType ScheduleType.LINEAR构造时PPO 优化器根据shared_critic决定价值网络为 False 时新建独立的ValueNetwork输出每个奖励信号的 value head为 True 时直接复用policy.actor作为 critic。learning_rate、epsilon、beta三个超参分别用ModelUtils.DecayedValue包装随训练步数从初始值线性衰减下限分别为 1e-10、0.1、1e-5。所有可训练参数统一交给单个torch.optim.Adam。updateppo/optimizer_torch.py#L99-L197的实现要点从 buffer 中读取旧价值old_values、收益returns、优势ADVANTAGES、旧动作对数概率old_log_probs以及循环网络的 actor/critic 记忆前向得到当前log_probs、entropy与values用ModelUtils.trust_region_value_loss计算价值损失、ModelUtils.trust_region_policy_loss计算带裁剪的 policy 损失均使用衰减后的epsilon作为裁剪阈值总损失 policy_loss 0.5 * value_loss - decay_beta * entropy先update_learning_rate再把 loss 反向传播并optimizer.step()返回统计字典包含Losses/Policy Loss注意代码对 policy loss 取绝对值以对齐旧 TensorFlow 行为、Losses/Value Loss、Policy/Learning Rate、Policy/Epsilon、Policy/Beta。3.2 TorchSACOptimizeroff-policy 的双 Q 与熵调节SAC 的超参由SACSettingssac/optimizer_torch.py#L28-L41定义attr.s(auto_attribsTrue) class SACSettings(OffPolicyHyperparamSettings): batch_size: int 128 buffer_size: int 50000 buffer_init_steps: int 0 tau: float 0.005 # 目标网络软更新系数 steps_per_update: float 1 save_replay_buffer: bool False init_entcoef: float 1.0 # 熵系数初值 reward_signal_steps_per_update: float attr.ib()SAC 优化器构造了四套网络sac/optimizer_torch.py#L44-L231q_networkPolicyValueNetwork内含两个独立的ValueNetworkQ1/Q2即 double-Q 结构可对每个奖励信号输出 Q 值target_network目标价值网络初始化时用ModelUtils.soft_update(self._critic, self.target_network, 1.0)直接拷贝 critic 参数_criticV 网络熵系数连续/离散动作分别用torch.nn.Parameter维护可学习的log_ent_coef并按动作空间自动计算目标熵离散分支0.2 * log(branch)连续维度-1.0 * dim。updatesac/optimizer_torch.py#L480-L642将损失拆分为四部分并分别用四个 Adam 优化器更新sac_q_lossQ1/Q2 与rewards (1 - dones * use_dones) * gamma * target_values的 MSEsac_value_lossV 网络对min(Q1,Q2) - 熵项的回归离散动作通过break_into_branches按分支计算期望sac_policy_loss最大化min Q加熵项reparameterization 思想sac_entropy_loss按目标熵 - 当前熵梯度调整可学习的熵系数。更新结束后通过ModelUtils.soft_update(self._critic, self.target_network, self.tau)以tau0.005软更新目标网络。返回值包括Losses/Policy Loss、Losses/Value Loss、Losses/Q1 Loss、Losses/Q2 Loss以及离散/连续熵系数。3.3 TorchPOCAOptimizer多智能体组的价值与基线POCAPolicy Optimization with Contribution-based Advantage面向多智能体协作场景。其POCAValueNetwork使用MultiAgentNetworkBodypoca/optimizer_torch.py#L54-L154处理变长智能体组value head 的输入维度为encoding_size 1多出的 1 维是归一化的智能体数量。POCA 的 critic 提供两种前向critic_pass用组内所有智能体的状态计算集中式价值函数baseline只给当前智能体的状态、但包含组友的状态-动作对从而边缘化当前智能体的动作——这就是 POCA 基线counterfactual baseline的核心。update中同时计算value_loss、baseline_loss与policy_losspoca/optimizer_torch.py#L332-L350总损失为policy_loss 0.5 * (value_loss 0.5 * baseline_loss) - beta * entropy。此外 POCA 覆写了get_trajectory_value_estimates保持类层次兼容并新增get_trajectory_and_baseline_value_estimates与_evaluate_by_sequence_team以同时产出 value、baseline 两组估计与两组中间记忆。四、奖励信号配置实战YAML 中的写法了解了create_reward_signals的底层机制后配置就非常直观了。仓库 config/ppo/、config/sac/、config/poca/ 目录下的 YAML 文件是可直接套用的示例。一个典型的reward_signals配置段形如reward_signals: extrinsic: gamma: 0.99 strength: 1.0 curiosity: gamma: 0.99 strength: 0.02 learning_rate: 0.0003 encoding_size: 256 gail: gamma: 0.99 strength: 0.01 learning_rate: 0.0003 demo_path: ./demos/Expert.demo rnd: gamma: 0.99 strength: 0.05 learning_rate: 0.0001要点说明顶层 key 必须是extrinsic/curiosity/gail/rnd之一与RewardSignalType枚举值严格对应settings.py中RewardSignalSettings.structuresettings.py#L202-L229负责把这段 YAML 结构化为Dict[RewardSignalType, RewardSignalSettings]extrinsic通常保留它是环境奖励的主通道Curiosity/GAIL/RND 作为内在奖励与 extrinsic 叠加最终各信号按strength加权旧版encoding_size字段已被弃用若同时未指定network_settings会回退为把encoding_size映射到network_settings.hidden_units并打印弃用警告开启记忆LSTM时get_trajectory_value_estimates返回的AgentBufferField会以CRITIC_MEMORY形式写入 buffer供update中取用参见 torch_optimizer.py#L137-L144 对BufferKey.CRITIC_MEMORY的处理。五、与训练器的协作价值估计如何进入训练循环get_trajectory_value_estimates由 trainer 在轨迹收集阶段调用。以 on-policy 训练器ml-agents/mlagents/trainers/trainer/on_policy_trainer.py与 off-policy 训练器ml-agents/mlagents/trainers/trainer/off_policy_trainer.py为例其典型流程为每条 trajectory 结束后trainer 调用optimizer.get_trajectory_value_estimates(batch, next_obs, done, agent_id)得到逐时刻价值估计与最终价值结合各奖励信号的gamma与 GAE 参数lambd在trajectory.py中计算 returns收益与 advantages优势值连同价值估计一起写回 AgentBuffer缓冲积累足够后trainer 按batch_size切分 minibatch反复调用optimizer.update(batch, num_sequences)每次update返回的统计字典汇总为训练日志最终输出到 TensorBoard对应仓库 Using-Tensorboard.md 中的Losses/Policy Loss、Losses/Value Loss等曲线。奖励信号网络Curiosity/GAIL/RND的更新同样发生在 trainer 的更新阶段通过optimizer.update_reward_signals(batch)完成保存/加载模型时get_modules()各优化器均实现会把优化器持有的网络与优化器对象暴露给 checkpoint 系统。六、如何扩展自定义优化器基于上述架构编写一个自定义 PyTorch 优化器只需三步对应 Training-Plugins.md 中提到的扩展机制继承TorchOptimizer在__init__中调用super().__init__(policy, trainer_settings)构建自己的 critic实现critic属性与优化器实现update(batch, num_sequences)从 AgentBuffer 读取观测/动作/优势/收益前向计算 loss反向传播并step()返回统计字典实现get_modules()把优化器持有的所有nn.Module与torch.optim.Optimizer对象注册进去保证断点续训时状态完整。Optimizer抽象基类中的reward_signals字典、TorchOptimizer中的create_reward_signals/get_trajectory_value_estimates/update_reward_signals均为公共机制子类可按需覆写如 POCA 所做而无需改动 trainer 的主循环。小结本文完整覆盖了官方 API 文档 Python-Optimizer-Documentation.md 中的全部内容Optimizer抽象基类与TorchOptimizer基类的方法签名、语义与返回值并下沉到 optimizer.py 与 torch_optimizer.py 的源码实现逐一还原了create_reward_signals的奖励信号工厂机制、get_trajectory_value_estimates的 bootstrap 与 done 处理、LSTM 场景下的_evaluate_by_sequence分段评估以及 PPO/SAC/POCA 三种内置优化器各自的超参、网络结构与损失构成。理解这一层你就掌握了 ML-Agents 训练引擎中价值估计—损失计算—参数更新的心脏地带无论是调参、排查训练曲线还是二次开发都有了源码级的依据。赞分享人工智能强化学习深度学习机器学习游戏开发AI 应用【免费下载链接】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点击查看免费下载相关推荐GLM-4V-9B技术架构解析深入理解90亿参数多模态模型的设计原理GLM 4V 9B技术架构解析深入理解90亿参数多模态模型的设计原理 GLM 4V 9B是智谱AI推出的最新一代开源多模态语言模型拥有90亿参数的强大视觉理5分钟快速上手Image-Downloader批量图片下载终极指南5分钟快速上手Image Downloader批量图片下载终极指南 在数字内容创作、学术研究和日常工作中我们经常需要批量获取高质量图片素材。无论是为博客文章网页爬虫verl奖励函数设计数据集奖励机制实现verl奖励函数设计数据集奖励机制实现 引言 在大语言模型LLM的强化学习训练中奖励函数设计是决定训练效果的关键因素。verlVolcano Engi人工智能大模型强化学习RLHF分布式训练微调创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价