为自定义强化学习算法创建代理
此示例演示如何为您自己的自定义强化学习算法创建自定义代理。这样做允许您利用强化学习工具箱™软件的以下内置功能。
在本例中,您将一个自定义的REINFORCE训练循环转换为一个自定义代理类。有关REINFORCE自定义火车循环的更多信息,请参见使用自定义训练循环训练强化学习策略.有关编写自定义代理类的更多信息,请参见创建自定义强化学习代理.
固定随机生成器种子的再现性。
rng (0)
创建环境
创建与。相同的训练环境使用自定义训练循环训练强化学习策略的例子。该环境是一个具有离散动作空间的车杆平衡环境。方法创建环境rlPredefinedEnv
函数。
env = rlPredefinedEnv(“CartPole-Discrete”);
从环境中提取观察和行动规范。
obsInfo = getObservationInfo(env);actInfo = getActionInfo(env);
获取观测次数(numObs
)和行动(numAct
).
numObs = obsInfo.Dimension(1);numAct = numel(actInfo.Elements);
有关此环境的更多信息,请参见负载预定义控制系统环境.
定义政策
本例中的强化学习策略是一个离散-动作随机策略。它由一个深度神经网络表示,它包含fullyConnectedLayer
,reluLayer
,softmaxLayer
层。这个网络输出给定当前观察的每个离散动作的概率。的softmaxLayer
确保策略输出范围为[0 1]的概率值,并且所有概率之和为1。
为演员创建深度神经网络。
actorNetwork = [featureInputLayer(numObs,“归一化”,“没有”,“名字”,“状态”) fullyConnectedLayer(24日“名字”,“fc1”) reluLayer (“名字”,“relu1”) fullyConnectedLayer(24日“名字”,“取得”) reluLayer (“名字”,“relu2”) fullyConnectedLayer (2“名字”,“输出”) softmaxLayer (“名字”,“actionProb”));actorNetwork = dlnetwork(actorNetwork)
actorNetwork = dlnetwork with properties: Layers: [7x1 nnet.cnn.layer.Layer] Connections: [6x2 table] Learnables: [6x3 table] State: [0x3 table] InputNames: {' State '} OutputNames: {'actionProb'} Initialized: 1
方法创建参与者rlDiscreteCategoricalActor
对象。
actor = rldiscrete tecategoricalactor (actorNetwork,obsInfo,actInfo);
加速行为人的梯度计算。
Actor =加速(Actor,true);
创建优化器选项和rlOptimizerOptions
函数。
actorOpts = rlotimizeroptions (“LearnRate”1 e - 3);
自定义代理人类别
类的子类来定义自定义代理,首先创建一个类rl.agent.CustomAgent
类。中定义了此示例的自定义代理类CustomReinforceAgent.m
.
的CustomReinforceAgent
Class具有以下类定义,它指示代理类名和关联的抽象代理。
classdefcustomreinforcement agent < rl.agent.CustomAgent
要定义您的代理,您必须指定以下内容:
代理的属性
构造函数
评估贴现长期奖励的批评家近似器(如果学习需要)
根据当前观察选择操作的参与者(如果需要学习)
所需的代理方法
可选的代理方法
代理的属性
在属性
部分,指定创建和训练代理所需的任何参数。
的rl.Agent.CustomAgent
类已包含代理示例时间的属性(SampleTime
)及行动及观察细则(ActionInfo
而且ObservationInfo
分别)。
自定义REINFORCE代理定义了以下附加代理属性。
属性%的演员演员ActorOptimizer%代理选项选项%经验缓冲ObservationBuffer ActionBuffer RewardBuffer结束属性(访问=私有)%培训工具Counter numobreservations NumAction结束
构造函数
要创建自定义代理,必须定义一个构造函数。构造函数执行以下操作。
定义动作和观察规范。有关创建这些规范的详细信息,请参见
rlNumericSpec
而且rlFiniteSetSpec
.设置代理属性。
调用基抽象类的构造函数。
定义样本时间(在Simulink环境中进行培训所需的时间)。金宝app
例如,CustomREINFORCEAgent
构造函数根据输入参与者定义操作和观察空间。
函数obj = customreinforcement agent (Actor,Options)构建定制代理% AGENT = customreinforcement AGENT(ACTOR,OPTIONS)创建定制加固代理从rlrandomactorrepresentation ACTOR%和结构选项。OPTIONS有以下字段:% - DiscountFactor% - MaxStepsPerEpisode调用抽象类构造函数。obj = obj@rl.agent.CustomAgent();obj。ObservationInfo = Actor.ObservationInfo;obj。ActionInfo = Actor.ActionInfo;% (Simulink环境要求)金宝app注册采样时间。对于MATLAB环境,使用-1。obj。采样时间= -1;(可选)注册参与者和代理选项。obj。演员=演员;obj。期权=期权;obj。ActorOptimizer = rlooptimizer (Options.OptimizerOptions);%(可选)缓存观察和操作的数量。obj。numobreservations = prod(obj.ObservationInfo.Dimension);obj。NumAction = prod(obj.ActionInfo.Dimension);%(可选)初始化缓冲区和计数器。resetImpl (obj);结束
所需的功能
要创建自定义强化学习代理,必须定义以下实现函数。
getActionImpl
—评估代理策略,在模拟过程中选择一个代理。getActionWithExplorationImpl
-评估政策并在培训中进行探索选择行动。learnImpl
-代理如何从当前经验中学习
要在自己的代码中调用这些函数,请使用抽象基类中的包装器方法。例如,调用getActionImpl
,使用getAction
.包装器方法具有与实现方法相同的输入和输出参数。
getActionImpl
函数
的getActionImpl
函数用于评估代理的策略,并在使用sim卡
函数。此函数必须具有以下签名,其中obj
是代理对象,观察
是目前的观察,和行动
所选操作。
函数Action = getActionImpl(obj,Observation)
方法来选择自定义REINFORCE代理的操作getAction
角色的功能。离散rlStochasticActorRepresentation
根据观察结果生成一个离散分布,并从该分布中对一个动作进行采样。
函数Action = getActionImpl(obj,Observation)使用给定的当前策略计算一个动作%的观察。Action = getAction(obj.Actor,Observation);结束
getActionWithExplorationImpl
函数
的getActionWithExplorationImpl
方法训练代理时,使用代理的探索模型选择一个操作火车
函数。使用这个函数,您可以实现探测技术,如epsilon-greedy探测或添加高斯噪声。此函数必须具有以下签名,其中obj
是代理对象,观察
是目前的观察,和行动
所选操作。
函数Action = getActionWithExplorationImpl(obj,Observation)
对于自定义加固代理,getActionWithExplorationImpl
函数和getActionImpl
.默认情况下,随机参与者总是在探索,也就是说,他们总是根据概率分布选择行动。
函数Action = getActionWithExplorationImpl(obj,Observation)使用给定的探索策略计算一个操作%当前观察。强化:随机参与者总是默认探索%(来自概率分布的样本)Action = getAction(obj.Actor,Observation);结束
learnImpl
函数
的learnImpl
函数定义代理如何从当前经验中学习。这个函数通过更新策略参数和选择一个动作来实现代理的自定义学习算法,并对下一个状态进行探索。此函数必须具有以下签名,其中obj
是代理对象,经验
是目前的代理经验,和行动
所选操作。
函数行动= learnImpl(obj,经验)
代理体验是单元格数组经验={状态,行动,奖励,下一步状态,已完成}
.在这里:
状态
是目前的观察结果。行动
是当前动作。这与输出参数不同行动
,这是针对下一个状态的操作。奖励
是当前的奖励。nextState
这是下一个观察结果。结束
是指示训练集已完成的逻辑标志。
对于自定义REINFORCE代理,复制自定义训练循环的步骤2到步骤7使用自定义训练循环训练强化学习策略.您省略了步骤1、8和9,因为您将使用内置的火车
函数来训练您的代理。
函数行动= learnImpl(obj,经验)定义代理如何从经验中学习,这是一个%单元格数组,使用以下格式。%经验={观察,行动,奖励,下一步观察,isDone}在情节开始时重置缓冲区。如果obj。resetBuffer(obj);结束从经验中提取数据。Obs =经验{1};行动=经验{2};奖励=经验{3};NextObs =体验{4};IsDone = Experience{5};将数据保存到缓冲区。obj.ObservationBuffer(:,:,obj.Counter) = Obs{1};obj.ActionBuffer(:,:,obj.Counter) =动作{1};obj.RewardBuffer(:,obj.Counter) =奖励;如果~结束为下一个状态选择一个动作。。Action = getActionWithExplorationImpl(obj, NextObs);obj。Counter = obj。Counter + 1;其他的从情景数据中学习。从缓冲区收集数据。BatchSize = min(obj.Counter,obj.Options.MaxStepsPerEpisode);ObservationBatch = obj.ObservationBuffer(:,:,1:BatchSize);ActionBatch = obj.ActionBuffer(:,:,1:BatchSize);RewardBatch = obj.RewardBuffer(:,1:BatchSize);计算贴现的未来奖励。。DiscountedReturn = 0 (1,BatchSize);为t = 1:BatchSize G = 0为G = G + obj.Options.DiscountFactor ^ (k-t) * RewardBatch(k);结束discountereturn (t) = G;结束组织传递给丢失函数的数据。LossData。batchSize =批量大小;LossData。actInfo = obj.ActionInfo;LossData。行动Batch = ActionBatch; LossData.discountedReturn = DiscountedReturn;计算损失相对于的梯度% actor参数。ActorGradient = gradient(obj。演员,@lossFunction,...{ObservationBatch}, LossData);使用计算的梯度更新参与者参数。obj。Actor =优化(obj.Actor,ActorGradient);重置计数器。obj。Counter = 1;结束结束
该actor计算相对于参数的损失梯度,其中损失函数被实现为局部函数lossFunction
在CustomREINFORCEAgent.m
.
函数loss = lossFunction(policy,lossData) policy = policy;创建动作指示矩阵。batchSize = lossData.batchSize;Z = repmat(lossData.actInfo.Elements',1,batchSize);actionIndicationMatrix = lossData.actionBatch(:,:) == Z;将折现收益调整为保单的大小。G = actionIndicationMatrix .* lossdata . discountereturn;G =重塑(G,大小(政策));将小于eps的任何策略值四舍五入到eps。策略(策略< eps) = eps;%计算损失。loss = -sum(G .* log(policy),“所有”);结束
可选功能
可以选择在训练开始时定义如何重置代理resetImpl
函数具有以下函数签名,其中obj
是代理对象。
函数resetImpl (obj)
使用该函数,可以在训练前将代理设置为已知或随机条件。
函数resetImpl (obj)%(可选)定义培训前座席如何重置/resetBuffer (obj);obj。Counter = 1;结束
此外,您还可以根据需要在自定义代理类中定义任何其他帮助函数。例如,自定义REINFORCE代理定义了一个resetBuffer
用于在每个训练集开始时重新初始化经验缓冲区的函数。
函数resetBuffer (obj)重新初始化所有经验缓冲区。obj。ObservationBuffer = 0 (obj. numobreservations,1,obj.Options.MaxStepsPerEpisode);obj。ActionBuffer = 0 (obj.NumAction,1,obj.Options.MaxStepsPerEpisode);obj。RewardBuffer = 0 (1,obj.Options.MaxStepsPerEpisode);结束
创建自定义代理
定义了自定义代理类之后,在MATLAB工作区中创建它的实例。要创建自定义REINFORCE代理,首先要指定代理选项。
选项。MaxStepsPerEpisode = 250;选项。折扣因子= 0.995;选项。OptimizerOptions = actorOpts;
然后,使用选项和前面定义的角色,调用自定义代理构造函数。
agent = customreinforcement agent (actor,options);
培训报关员
将培训配置为使用以下选项。
将训练设置为持续最多5000集,每集持续最多250步。
在达到最大集数后或当100集的平均奖励达到240时终止训练。
有关更多信息,请参见rlTrainingOptions
.
numEpisodes = 5000;aveWindowSize = 100;trainingTerminationValue = 220;trainOpts = rlTrainingOptions(...“MaxEpisodes”numEpisodes,...“MaxStepsPerEpisode”,选择。MaxStepsPerEpisode,...“ScoreAveragingWindowLength”aveWindowSize,...“StopTrainingValue”, trainingTerminationValue);
训练代理使用火车
函数。训练这个代理是一个计算密集的过程,需要几分钟才能完成。要在运行此示例时节省时间,请通过设置加载预先训练过的代理doTraining
来假
.亲自训练探员,设doTraining
来真正的
.
doTraining = false;如果doTraining培训代理。trainStats = train(agent,env,trainOpts);其他的为示例加载经过训练的代理。负载(“CustomReinforce.mat”,“代理”);结束
模拟自定义代理
启用环境可视化,它将在每次环境更新时更新一步
函数被调用。
情节(env)
为了验证训练过的代理的性能,在车杆环境中模拟它。有关代理模拟的更多信息,请参见rlSimulationOptions
而且sim卡
.
simOpts = rlSimulationOptions(“MaxSteps”, options.MaxStepsPerEpisode);experience = sim(env,agent,simOpts);