关于ML-Agents插件的入门,请查看我前面的博文: 自创强化学习环境之Unity3D插件ML-Agent的使用
本文内容基于ML-Agents的官方文档:Training ML-Agents以及Training Configuration File
ML-Agents命令
查看所有的命令:
mlagents-learn --help
训练的基本命令是:
mlagents-learn <trainer-config-file> --env=<env_name> --run-id=<run-identifier>
<trainer-config-file>
是训练器配置 YAML 的文件路径。里面包含所有超参数值。<env_name>
(可选)是包含要训练的代理的Unity 可执行文件的名称(包括路径) 。如果不写,则训练将在编辑器中进行。<run-identifier>
是一个唯一的名称,主要用于命名保存的训练模型、统计信息以及模型名称。训练过程产生的文件都保存在results/<run-identifier>
文件夹中。- –curriculum=
<file>*
:如果你的训练是Curriculum Learning*,这个命令可以指定你要训练的课程配置文件,官方也有一个示例(Wall Jump)专门展示了 Curriculum Learning这种训练类型,这里我们之后的文章再去深入研究。 - *–lesson=
<n>
*:指定在执行Curriculum Learning时要开始的课程,默认为0。 - *–sampler=
<file>
*:用于指定训练环境的可变参数的配置文件。具体内容可以看ML-Agents(四)3DBall补充の引入泛化。 - *–save-freq=
<n>
*:指定在训练过程中保存模型的频率,默认为50000。 - *–keep-checkpoints=
<n>
:指定了要保存模型的检查点的最大数量。该属性与上面的–save-freq=<n>
*有命令关,即在n步后,会记录一个检查点。此外,新的检查点形成,会使得老的检查点删除,默认存5个检查点。。 - *–num-envs=
<n>
*:指定在训练时,从几个Unity环境实例中收集数据,默认为1。当然如果是发布的程序,你就可以多开几个程序让训练数据更多。 - *–seed=
<n>
*:指定一个数字作为训练代码使用的随机数生成器的seed。 - –env-args=
<string>*
:为可执行程序传参,具体给Unity传参可以参考官方文档Unity Command Line Arguments。例如,命令mlagents-learn config/trainer_config.yaml –env-args –num-orcs 42会将–num-ors 42传递给可执行文件。 - –base-port:指定启动的端口。用于多个Unity程序连接会依次分配一个端口。默认是5005。当然我们之前都是直接使用IDE进行训练的,所以这一项直接可以忽略。
- –inference:指定是否仅在推理模式下运行。这种模式会忽略对对模型的训练。要加载现有的训练模型,需要结合*–reusme*以及run-id来使用。
- –resume:如果设置这一项,则训练代码会在训练前加载已经训练好的模型去初始化神经网络。训练代码会在**models/
<run-id>
**目录下查找训练模型。这个选项仅在模型存在且具有与场景中当前代理相同的行为名称(Behavior Name)时才有效。 - –force:当要使用之前已经使用过的run-id来训练模型会抛出错误。适用*–force*来强制覆盖原有id的数据模型和数据统计。
- *–initialize-form=
<run-identifier>
*:指定一个已存在的训练模型来初始化新的训练模型。但是注意,当前的训练环境行为参数要与之前保存的训练模型参数相同才可以。 - –no-graphics:指定Unity以*-batchmode*运行,并且不初始化图形驱动程序。当然注意只适用于训练中不涉及视觉观察(Observations,读取像素训练)。关于Unity不利用GPU运行请查看这里Unity官方文档。
- –debug:此选项可以输出代码某些部分的调试代码日志。
- –cpu:强制只使用CPU训练。
- Unity设置:
- –width:Unity运行时窗口的宽度,单位像素,默认84(IDE训练可忽略)。
- –height:有width,就有height,与上相同,指高度,默认84,同样IDE训练可忽略。
- –quality-level:设置Unity的QualitySettings.SetQualityLevel属性,即画面质量,默认为5。
- –time-scale:设置Unity的Time.timeScale属性,即游戏时间缩放比例,默认为20,最大为100。下次试试把这个值调大一些,是否可以加快训练速度。
- –target-frame-rate:设置Unity的Application.targetFrameRate,即设置游戏帧率,默认为-1,即不设置,一般为60帧每秒。
ML-Agents配置
参数配置
在配置文件YAML文件中,你可以添加以下参数:
环境设置:
env_settings:
env_path: FoodCollector
env_args: null
base_port: 5005
num_envs: 1
seed: -1
max_lifetime_restarts: 10
restarts_rate_limit_n: 1
restarts_rate_limit_period_s: 60
引擎设置:
engine_settings:
width: 84
height: 84
quality_level: 5
time_scale: 20
target_frame_rate: -1
capture_frame_rate: 60
no_graphics: false
检查点设置:
checkpoint_settings:
run_id: foodtorch
initialize_from: null
load_model: false
resume: false
force: true
train_model: false
inference: false
Torch设置:
torch_settings:
device: cpu
所有功能展示(基于PPO)
如果我们使用了所有的训练功能的PPO算法(包含记忆,行为克隆,好奇心,GAIL和self-play),配置文件应该这样写(自己灵活选择功能):
behaviors:
BehaviorPPO:
trainer_type: ppo
hyperparameters:
# Hyperparameters common to PPO and SAC
# 一次抽取多少条数据进行训练
batch_size: 1024
# 经验池大小
buffer_size: 10240
# 学习率
learning_rate: 3.0e-4
# 学习率是Linear则线性递减,达到训练的最大步数衰减为,如果设为Constant则恒定
learning_rate_schedule: linear
# PPO-specific hyperparameters
# Replaces the "PPO-specific hyperparameters" section above
# β值,PPO参数,决定了新旧策略的差距大小
beta: 5.0e-3
beta_schedule: constant
# 决定了策略的随机性,一般在前期应基于较大的随机有利于探索,后期随机减小
epsilon: 0.2
epsilon_schedule: linear
# agents更新估计值时依赖于当前值的多少,趋近于1时则靠近更新值,趋近于0靠近当前的估计值
lambd: 0.95
# 梯度下降过程中采样经验池的次数
num_epoch: 3
# Configuration of the neural network (common to PPO/SAC)
network_settings:
# 可视化观察的编码类型,simple对应两层卷积神经网络,nature_cnn是三个卷积层,resnet是叠的复杂卷积层
vis_encode_type: simple
# 是否自动标准化观测值
normalize: false
# 隐藏层神经网络单元个数
hidden_units: 128
# 隐藏层层数
num_layers: 3
# 循环神经网络,注意:LSTM不适用于连续动作,离散动作可以获得更好的结果
memory:
# 需要记住的经验序列长度,越大记忆越久
sequence_length: 64
# 智能体保存的记忆大小,必须是2的倍数,且应与期望agent完成任务所需记住的信息量成正比
memory_size: 256
# Trainer configurations common to all trainers
# 最大训练步数,达到后自动退出
max_steps: 5.0e5
# 在添加到经验池之前智能体要经过的步数,如果有频繁的奖励,可以设的小一些
time_horizon: 64
# 每经过多少步数在面板上显示统计数据
summary_freq: 10000
# 训练中保留模型的数量
keep_checkpoints: 5
# 每收集多少经验数据保存一个模型数据,所有保留的模型都会以.onnx文件的形式保存
checkpoint_interval: 50000
# 允许环境在更新模型时运行,当使用SAC时设为True有利于加速训练,但用Self Play时应设为False
threaded: false
# 之前保存的模型路径
init_path: null
# behavior cloning
behavioral_cloning:
demo_path: Project/Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo
strength: 0.5
steps: 150000
batch_size: 512
num_epoch: 3
samples_per_update: 0
reward_signals:
# environment reward (default)
extrinsic:
strength: 1.0
gamma: 0.99
# curiosity module
curiosity:
strength: 0.02
gamma: 0.99
encoding_size: 256
learning_rate: 3.0e-4
# GAIL
gail:
strength: 0.01
gamma: 0.99
encoding_size: 128
demo_path: Project/Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo
learning_rate: 3.0e-4
use_actions: false
use_vail: false
# self-play
self_play:
window: 10
play_against_latest_model_ratio: 0.5
save_steps: 50000
swap_steps: 2000
team_change: 100000
SAC部分展示
如果使用的是SAC而不是PPO算法,只需要做简单的修改:
behaviors:
BehaviorSAC:
trainer_type: sac
hyperparameters:
# SAC-specific hyperparameters
# Replaces the "PPO-specific hyperparameters" section above
buffer_init_steps: 0
tau: 0.005
steps_per_update: 10.0
save_replay_buffer: false
init_entcoef: 0.5
reward_signal_steps_per_update: 10.0
# 下面内容相同
配置说明
batch_size:一次性抽取多少条数据样本一起训练。连续动作空间推荐:512-5120,离散动作空间推荐:32-512
buffer_size:经验池容量。推荐:2048-409600
epsilon:影响策略在训练过程中的成型速度。对应新旧策略之间可接受的差异阈值,较小有较稳定的稳定,但会减慢训练过程。推荐:0.1-0.3
init_entcoef:在训练开始时,agent应该探索多深。
learning_rate:学习率,数据更新强度,训练不稳定应降低该值。推荐:1e-5-1e-3
learning_rate_Schedule:对应于学习率如何随时间变化,逐渐降低学习速率可以更稳定收敛。linear指线性衰减,maxSteps达到0,constant不衰减。
max_steps:每一个episode执行的最大步数。推荐:5e5-1e7
normalize:是否自动标准化观测值。这对于复杂连续控制问题很有用,但对于简单离散控制可能反而有害。
behavioral_cloning:使用演示引导神经网络的策略。strength:模仿学习的学习率,推荐:0.1-0.5。demo_path:是.demo文件的路径。Steps:对应于激活BC的步骤,,BC的学习率随步骤逐步提高,设置为0会在整个训练过程中持续模仿。
save_replay_buffer:退出训练时保存到回放缓冲区,并在恢复时加载。
summary_freq:设置多久一次保存统计数据。主要决定了在tensorboard中显示数据点的数值。
time_horizon:在将每个agent添加到经验缓冲池之前,需要经过多少步训练。推荐:32-2048
train_interval:更新智能体的频率。
use_recurrent:是否使用循环神经网络。以下参数在use_recurrent为true时使用。sequence_length:训练中通过网络传递的经验序列的长度,较大的值可以记住较长时间的信息。推荐:4-128。memory_size:对应了存储策略的循环神经网络隐藏状态的浮点数数组大小,必须是2的倍数,并且与期望agent成功完成任务所需记住的信息量成比例。推荐:32-256
Reward Signals:在强化训练中,目标就是要学习一种是奖励最大化的策略。在基础层面上将来是由环境给出的。然而我们很可能遇到鼓励探索的agent。我们可以让agent探索新的状态而获得奖励,而不是仅仅给予明确的奖励;我们还可以使用混合奖励信号来帮助学习过程。使用reward_signals可以定义奖励信号。ML-Agents默认提供三种奖励信号:外部奖励信号(环境给予)、好奇心奖励信号(鼓励探索)、GAIL奖励信号(对抗模仿学习)。
lambd:agents更新估计值时依赖于当前值的多少,趋近于1时则靠近更新值,趋近于0靠近当前的估计值。推荐:0.9-0.95
num_epoch:梯度下降过程中通过经验池的次数。batch_size越大它可以设置得越大。减小该值可以确保更新稳定,但降低学习速率。推荐:3-10
num_layer:观察值输入后或CNN之后存在的隐藏层的数量,复杂的问题需要更多的层,推荐:1-3
hidden_units:对应神经网络每个全连接层有多少个单元。推荐:32-512
vis_encode_type:对应于可视化观测进行编码的编码器类型,选项包含:simple(默认):两个卷积层组成的简单编码器,nature_cnn:三个卷积层组成,详见https://www.nature.com/articles/nature14236。resnet:由三个堆叠的层构成,是比其他两个更大的网络,详见https://arxiv.org/abs/1802.01561。
init_path:指定在开始训练之前训练的模型,注意以前的模型的训练配置需要与当前运行的相同,并且使用相同版本的ML-Agents保存,同时要提供全路径存储。
reward_signal_num_update:对应于每次更新过程中采样并用于更新奖励信号的小批量数。默认在每次主policy更新时都会更新一次奖励信号,但为了模仿某些论文中的训练过程,我们需要更新N次策略,然后将奖励信号(GAIL)更新M次。此时我们可以将SAC的train_interval和num_update设置为N,将reward_signals下的reward_signal_num_update设置为M。默认其值为num_update。
buffer_init_steps训练之前预填充经验池的数据量。未经训练的策略是随机的,用随机动作预填充对于探索十分有用。
num_update:每个训练时间期间采样并用于训练的最小批量数。通常情况下,该值为1。
tau:SAC模型更新期间目标Q网络更新的快慢,因为存在Q和Target Q两个网络,每隔一段时间需要对Target Q进行更新,推荐:0.005-0.01
strength:原始奖励的倍乘系数,范围根据奖励信号变化。推荐:1.0
gamma:对应未来奖励的折扣因子。推荐:0.8-0.995
好奇心奖励信号:包括正向模型:采用当前已编码的观测值和动作,预测下一个已编码的观测值,逆向模型:采用agent的当前和下一个观测值,对它们进行编码,并使用编码来预测观测值之间采取的动作。正向模型的损失(预测值和实际值之间的差异)被用作内在奖励。
encoding_size:好奇心模块使用的编码大小,该值足够小可以鼓励ICM压缩原始的观察值,但太小也会导致ICM学习区分输出的行为和实际的行为。推荐:64-256
GAIL:即生成对抗模仿学习。和GANs类似。对于strength的设置取决于人的水平,人的演示很好这个值设高一点,推荐:0.01-1。
use_actions:鉴别器是根据观察和操作进行区分,还是仅仅根据观察值进行区分,如果希望agent模仿操作,则应该设为true,如果希望agent使用不同的操作达到相同的状态,则设为false。设为false更加稳定,特别是演示不完美的情况下,但学习速度较慢。
use_vail:是鉴别器学习一种更笼统的表示,降低了其在鉴别方面的过拟合,使学习更加稳定,但也会增加训练时间,如果模仿学习不成功,可以启用这个功能。
Self Play
Self Play是计算机的“左右互搏术”,通过自己随机的一个个智能体相互战斗,共同进步,从而共同实现策略的优化。
参考文章:左右互搏,self-play,《Emergent Complexity via Multi-Agent Competition》
Self Play为强化学习面临的常见问题增加了额外的混杂因素。一般在技能水平、最终策略通用性、学习的稳定性之间进行权衡。和低多样性对手进行训练比和高多样性对手进行训练会使学习过程更稳定。在此背景下,本指南讨论了可以调整的self play超参数。
如果环境包含多个分成多个团队的智能体,您可以通过为每个行为提供以下配置来使用Self Play:
环境 | 描述 |
---|---|
save_steps |
(默认 = 20000 )存储智能体策略的训练步数。例如,如果save_steps=10000 当前策略的模型每个10000 step保存一次,保存的叫做快照(snapshots)。请注意,训练步数是按每个智能体单独计算的。有关更多信息,请参阅v0.13 之后的迁移文档。 较大的save_steps 会使智能体接受更多的训练,因此将产生一组涵盖更广泛比赛风格的对手。智能体针对更广泛的对手进行训练。学习一个策略来击败更多样化的对手是一个更难的问题,因此可能需要更多的整体训练步骤,实现更通用和更强大的策略。该值还取决于环境对智能体的困难程度。 典型范围:10000 -100000 |
team_change |
(默认 = 5 * save_steps )切换学习团队的训练步数。每个团体学习到一定步数后,将切换给另一个团体进行学习。在不对称的比赛中,对方团体可能需要较少的训练步骤来获得类似的性能提升。与更简单的智能体团队相比,较高的team_change使用户能够训练更复杂的智能体团队。 较大的值team-change 将允许智能体针对其对手进行更长时间的训练。智能体针对同一组对手训练的时间越长,击败他们的能力就越大。然而,针对同样的训练时间过长可能会导致对特定对手策略的过度拟合,智能体可能会在对抗下一批对手时失败。 team-change 还决定保存多少智能体的训练快照用作其他团队的对手。因此,我们建议将此值设置为save_steps 的倍数。 典型范围:4x-10x,其中 x=save_steps |
swap_steps |
(默认 = 10000 )切换对手快照之间的步数。此时对手遵循固定策略而不学习。在非对称游戏中,我们可能有智能体数量不同的团队。例如两个智能体的团队每个step收集的智能体数据是一个智能体的团队的两倍。因此,这两个值应该不同,以确保相同数量的训练步数。swap_steps的公式为:(num_agents / num_opponent_agents)*(team_change / x),x是交换次数。详细解释在下方。 |
play_against_latest_model_ratio |
(默认 = 0.5 )智能体与对手的最新策略对抗的概率。也就是说有 1 - play_against_latest_model_ratio 概率智能体将与过去迭代中对手的快照进行对抗。 较大的值play_against_latest_model_ratio 表示智能体将更频繁地与当前对手对战。由于智能体正在更新其策略,如果每次迭代的对手都会有所不同,可能会导致学习环境的不稳定,但会给智能体带来更具挑战性的情况的自动课程,这可能最终使其更强大。 典型范围:0.0 -1.0 |
window |
(默认 = 10 )储存快照的容量大小,智能体的对手从中采样。例如,window 大小为 5 将保存最近拍摄的 5 个快照。每次拍摄新快照时,最老的快照将被丢弃。较大的值window 意味着智能体的对手池将包含更多的行为多样性,因为它将包含训练早期的策略。就像在save_steps 超参数中一样,智能体针对更广泛的对手进行训练。学习一个策略来击败更多样化的对手是一个更难的问题,因此需要更多的整体训练步骤,但也会在使得自身策略训练得更加强大。 典型范围:5 -30 |
ELO机制
ELO等级分制度是衡量选手水平的评分方法,在训练智能体的过程中,各个智能体团队通过相互博弈共同进步,会使得ELO分数持续升高。一般来说,初始分为1200,赢了奖励一定分数,输了会扣除一定分数。详细规则请查看链接:
交换步骤的注意事项
例如,在 2v1 场景中,如果我们希望在 team-change=200000 步期间交换发生 x=4 次,则一个智能体的团队的 swap_steps 为:
swap_steps = (1 / 2) * (200000 / 4) = 25000
两个智能体的团队的 swap_steps 为:
swap_steps = (2 / 1) * (200000 / 4) = 100000 注意,在团队规模相同的情况下,第一项等于 1,swap_steps 可以通过将总步数除以所需的交换次数来计算。
较大的 swap_steps 值意味着智能体将在更长的训练迭代次数中与相同的固定对手对战。使训练环境更稳定,但让智能体面临针对该特定对手过度拟合其行为的风险。
双人足球中的具体配置:
self_play:
save_steps: 50000
team_change: 200000
swap_steps: 2000
window: 10
play_against_latest_model_ratio: 0.5
initial_elo: 1200.0
环境参数
为了控制环境参数,可以在下方再加上一段配置:
behaviors:
BehaviorY:
# < Same as above >
# Add this section
environment_parameters:
my_environment_parameter: 3.0
然后再Unity仿真中,可以通过以下方式访问参数:
Academy.Instance.EnvironmentParameters.GetWithDefault("my_environment_parameter", 0.0f);
为了使参数随机,我们可以不直接提供数值,而是让它自己采样,下面是包含三个环境参数的示例:
behaviors:
BehaviorY:
# < Same as above >
# Add this section
environment_parameters:
mass:
sampler_type: uniform
sampler_parameters:
min_value: 0.5
max_value: 10
length:
sampler_type: multirangeuniform
sampler_parameters:
intervals: [[7, 10], [15, 20]]
scale:
sampler_type: gaussian
sampler_parameters:
mean: 2
st_dev: .3
其中uniform是统一采样器,从给定最大值和最小值的范围中采样,gaussian是高斯采样器,给定均值和标准差从正态分布中采样。multirange_uniform是多范围均匀采样,根据区间的相对长度从一组区间中采用一个区间。从这个区间中统一采样一个单浮点值。
在3DBall的第二个配置文件中有这个用法。
定义采样器配置后,输入响应命令可以启用参数随机化的训练器配置(如下):
mlagents-learn config/ppo/3DBall_randomize.yaml --run-id=3D-Ball-randomize
Curriculum Learning
如果想启用课程学习,需要添加一段配置:
ehaviors:
BehaviorY:
# < Same as above >
# Add this section
environment_parameters:
my_environment_parameter:
curriculum:
- name: MyFirstLesson # The '-' is important as this is a list
completion_criteria:
measure: progress
behavior: my_behavior
signal_smoothing: true
min_lesson_length: 100
threshold: 0.2
value: 0.0
- name: MySecondLesson # This is the start of the second lesson
completion_criteria:
measure: progress
behavior: my_behavior
signal_smoothing: true
min_lesson_length: 100
threshold: 0.6
require_reset: true
value:
sampler_type: uniform
sampler_parameters:
min_value: 4.0
max_value: 7.0
- name: MyLastLesson
value: 8.0
name是用户定义的课程名称,completion_criteria决定了需要模拟的世间,当满足条件是课程转到下一个lessons,value就是环境参数在课程中需要采用的值。
- measure:衡量课程进度的方法。其中的值为reward指的是用奖励衡量,progress指的是用steps/max_steps比例来衡量。
- threshold:配合measure使用,到达这个值时会自动转向课程的下一个阶段。
- min_lesson_length:在转换阶段之前,需要完成的episode的最低数量。
- signal_smoothing:决定是否按以前的值对当前进度度量进行加权。
require_reset决定更改课程是否需要重置环境(默认:false)。
一旦我们指定了我们的元课程和课程,我们就可以启动 mlagents-learn
指向包含我们课程的配置文件,PPO 将使用课程学习进行训练。例如,要通过课程学习在 Wall Jump 环境中训练智能体,我们可以运行:
mlagents-learn config/ppo/WallJump_curriculum.yaml --run-id=wall-jump-curriculum
Behavioral Cloning
Behavior Cloning(行为克隆),简称BC。它的思想较为简单,就是把智能体的策略网络训练得和人类的演示数据的行为模式越接近越好,也就是说,输入相同的状态s,应当有相近的输出a。这单纯就是一个Supervised Learning,每一个状态相当于输入的特征,专家输出的动作相当于Label(标签),我们只需要让模型的输出接近我们的Label即可。
在这里BC通常用作预训练。
现在我们看看配置文件中的参数是怎么设定的。
behavioral_cloning:
demo_path: Project/Assets/ML-Agents/Examples/PushBlock/Demos/ExpertPushBlock.demo
steps: 50000
strength: 1.0
samples_per_update: 0
在使用BC之前,应当确保自己已经录制了演示文件(后面会讲怎么录制演示),其中的参数含义如下:
demo_path:演示文件的路径。
strength:默认为1。表示模仿学习相对于PPO算法的学习率,表示了BC改变策略的强度。.
steps:通常BC应当在模仿学习进行到智能体能够获取奖励时停止,从而正式进入强化学习。当运行的步数大于steps的时候,模仿学习的学习率将为0,也就是不再起作用。如果设为0,那么将会在整个过程中持续进行BC。
batch_size:默认为强化学习使用的batch_size。表示一次性使用多少条数据进行梯度递减。推荐:512-5120
num_epoch:默认为PPO设定。梯度下降期间需要从经验池中抽取多少次。推荐:512-5120
samples_per_update:默认为0。每次更新期间使用的最大样本数,0表示每次拿所有演示数据进行训练。如果演示数据非常大,应当降低此值防止过拟合。
后记
对于上面的命令不理解的不用着急,ML-Agents提供了一系列实例来演示大部分的功能,后面会一一开文章进行讲解。