# train!
智能体训练
函数库: TyReinforcementLearning
# 语法
result = train!(agent, env, trainOptions)
# 说明
result = train!(env, agent, trainOptions) 在指定的环境中训练强化学习智能体,使用 trainOptions 控制训练选项。在每个训练回合结束后,train 会更新在 agents 的策略(通常为表格或神经网络)参数,以最大化它们从环境中预期获得的长期奖励。当训练终止时,返回训练结果 result,agents 保持为智能体在最后一个训练回合结束时的状态。对于不同的强化学习智能体,其训练过程也不同,函数根据 agent 的种类自动选择相应的算法。
一般而言,train!在每一轮(episode)执行以下迭代步骤:
重置环境。
从环境中获取初始状态值 s。
计算初始动作 a = μ(s)。
将当前动作设置为初始动作,并将当前状态值设置为初始状态值。
当回合未完成或终止时:
(1). 使用动作 a 步进环境,获取下一个观察值 s' 和奖励 r。
(2). 从经验集(s,a,r,s' )中学习。
(3). 计算下一个动作 a' = μ(s')。
(4). 使用下一个动作更新当前动作(a ← a'),并使用下一个状态值更新当前状态值(s ← s' )。
(5). 如果满足环境中定义的回合终止条件,则终止当前回合。
# 示例
QL 智能体训练
在悬崖行走(CliffWalking)的环境示例中配置 QL 智能体,并以相应的环境进行训练。
CliffWalking 是一个经典的强化学习环境,通常用于教学和研究强化学习算法的性能。这个环境的特点是一个方格世界,智能体需要在其中移动,并在不掉入悬崖的情况下尽可能快地到达目标位置。
CliffWalking 环境是一个矩形方格世界,由网格组成,其中包括起始点、目标点和悬崖区域。 悬崖区域是位于起始点和目标点之间的一行方格,代表了危险区域,如果智能体掉入悬崖,将会受到较大的惩罚。 代理程序可以在四个基本方向(上、下、左、右)中选择一个动作,以在方格世界中移动。 目标是让智能体尽可能快地从起始点到达目标点,但要避免掉入悬崖区域。
代理程序会受到奖励或惩罚,具体规则如下: 如果代理程序成功到达目标点,会获得正奖励,表示任务成功完成。 如果代理程序掉入悬崖,会受到较大的负奖励,以惩罚不安全的行动。 对于其他非终止状态,代理程序执行动作后会获得小的负奖励,以鼓励它尽快到达目标而不浪费时间。
状态空间:状态空间通常由方格世界中的每个方格组成,表示代理程序的位置。状态可以用坐标 1~48 来表示。
动作空间:动作空间由代理程序可选择的四个基本动作(上、下、左、右)组成,用于在方格世界中移动,表示为 1,2,3,4。
导入需要的包以及创建 CliffWalking 训练环境。
using TyReinforcementLearning
env = BuildEnv("CliffWalking-v0");
创建智能体所需的 Q 表格,表格的形式为(48,4),各行代表了环境的状态,各列代表了智能体的动作,值为需要学习的 Q(s,a),智能体在处于 s 状态下,选取 Q 最大的 a 进行下一步行动,以期获得更高的长期奖励。
models = rlQLModels(
Qtable=zeros(StateDims(env), ActionDims(env))
)
创建智能体选项,将环境的状态与动作空间信息传入。
option = rlQLAgentOptions(
stateNum=StateDims(env),
actionNum=ActionDims(env)
);
创建 QL 智能体。
agent = rlQLAgent(models,option);
创建 train_options 来指定一些训练参数。对于这个示例,智能体最多训练 1000 个回合,每进行 1 步学习一次。
train_options = rlTrainOptions(
max_episodes=1000,
learning_interval=1,
path=joinpath(pwd(),"result")
);
此时,就可以将智能体传入train!函数中,在 Cart Pole 的环境下进行训练并得到训练结果。
result = train!(agent, env, train_options)
训练结束后,可以在工作目录的 result 文件夹下得到智能体文件 agent0,该智能体是训练过程中 score 得分最高的一个。
调用plot_result函数可以绘制训练结果图像,将 steps_per_episode,rewards_per_episode ,test_scores_per_episode 三个变量随训练回合增加的变化曲线绘制出来。
plot_result(result, ["steps", "rewards", "test_scores"])
对于这个已经训练好的智能体,使用 get_action 来获取其对环境状态的动作反应。
state = Reset(env)[1]
action = get_action(agent, state)
1
将智能体给出的动作输入环境,即可实现智能体与环境的互动。
state, reward, done, _, _ = Step(env, action)
(25, -1, false, false, Dict{Any, Any}("prob" => 1.0))
强化学习每次训练具有随机性,输出结果不会完全一致。
PG 智能体训练
在平衡杆小车(Cart Pole)的环境示例中配置 PG 智能体,并以相应的环境进行训练。
Cart Pole 即车杆游戏,游戏里面有一个小车,上有竖着一根杆子,每次重置后的初始状态会有所不同。小车需要左右移动来保持杆子竖直,为了保证游戏继续进行需要满足以下两个条件:
- 杆子倾斜的角度 不能大于 15°
- 小车移动的位置需保持在一定范围(中间到两边各 2.4 个单位长度)
环境中的状态值是一个包含小车的位置和速度,以及杆的角度位置和角速度的向量。动作是一个标量,有两个可能的元素(对小车施加-10 或 10 牛顿的力)。
导入需要的包以及创建 Cart Pole 训练环境。
using TyReinforcementLearning
env = BuildEnv("CartPole-v1");
创建 PG 智能体所需的神经网络模型,指定中间层神经元个数为 128。由于 Cart Pole 状态空间与动作空间均为离散,因此输入层神经元个数为环境状态的个数,输出层神经元为环境动作的个数。由于 PG 智能体采用概率的方法来确定动作,因此要在最后一层进行 soft_max 处理来获取概率值。
actor_net = BuildDefaultNet(128, StateSize(env)[1], ActionDims(env); soft=true)
models = rlPGModels(
actorNet=actor_net
);
创建智能体选项,对于离散动作空间的问题,采用 epsilonGreedy 探索策略,并将环境的状态与动作空间信息传入。
option = rlPGAgentOptions(
stateSize=StateSize(env),
actionNum=ActionDims(env)
);
创建 PG 智能体。
agent = rlPGAgent(models,option);
创建 train_options 来指定一些训练参数。对于这个示例,智能体最多训练 1500 个回合,每进行 200 步学习一次。
train_options = rlTrainOptions(
max_episodes=1500,
learning_interval=200,
path=joinpath(pwd(),"result")
)
此时,就可以将智能体传入train!函数中,在 Cart Pole 的环境下进行训练并得到训练结果。
result = train!(agent, env, train_options)
训练结束后,可以在工作目录的 result 文件夹下得到智能体文件 agent0,该智能体是训练过程中 score 得分最高的一个。
调用plot_result函数可以绘制训练结果图像,将 steps_per_episode,rewards_per_episode ,test_scores_per_episode 三个变量随训练回合增加的变化曲线绘制出来。
plot_result(result, ["steps", "rewards", "test_scores"])
对于这个已经训练好的智能体,使用 get_action 来获取其对 Cart Pole 环境状态的动作反应。
state = Reset(env)[1]
action = get_action(agent, state)
1
将智能体给出的动作输入环境,即可实现智能体与环境的互动。
state, reward, done, _, _ = Step(env, action)
(Float32[-0.045320075, -0.17840403, 0.044338264, 0.34655356], 1.0, false, false, Dict{Any, Any}())
强化学习每次训练具有随机性,输出结果不会完全一致。
# 输入参数
agent-智能体
结构体
需要训练的智能体,指定为强化学习智能体对象,例如rlQAgent或rlDQNAgent。
env-环境
环境对象
智能体训练的环境,指定为强化学习环境对象,通过BuildEnv函数创建或由用户自定义得到,也可以使用GridWorld和rlMDPEnv对象作为环境。
trainOptions-训练选项
结构体
训练选项,指定为rlTrainOptions对象。
# 输出参数
result-训练结果
字典
训练结果,包含有以下内容:
| 名称 | 说明 |
|---|---|
| TrainOptions | 训练选项。 |
| BestScore | 最高分。 |
| rewards_per_episode | 每个回合的奖励,以向量形式返回。每个条目包含对应回合的奖励。 |
| steps_per_episode | 每个回合的步数,以向量形式返回。每个条目包含对应回合的步数。 |
| test_scores_per_episode | 每个回合的分数,以向量形式返回。每个条目包含对应回合的分数。(如果在 trainOptions 中指定 test=false,则该项等于 rewards_per_episode )。 |
| average_rewards_per_episode | 窗口期内的平均奖励,以向量形式返回。 |
| average_steps_per_episode | 窗口期内的平均步数,以向量形式返回。 |
| average_test_scores_per_episode | 窗口期内的平均分数,以向量形式返回。 |
| total_agent_steps | 训练中智能体的总步数,以向量形式返回。每个条目包含到达该回合之前的 steps_per_episode 条目的累积和。 |
# 另请参阅
rlQLAgent | rlSARSAAgent | rlDQNAgent | rldoubleDQNAgent | rlPGAgent | rlACAgent | rlDDPGAgent