创建自定义强化学习算法的智能体

  • 创建环境
  • 定义策略
  • 自定义智能体类
  • 智能体属性
  • 构造函数
  • 相关函数
  • 可选功能
  • 创建自定义智能体
  • 训练自定义智能体
  • 自定义智能体仿真

本示例说明如何为您自己的自定义强化学习算法创建自定义智能体。 这样做使您可以利用Reinforcement Learning Toolbox™软件的以下内置功能。

  1. 访问所有智能体函数,包括train和sim

  2. 使用Episode Manager可视化训练进度

  3. 在Simulink®环境中训练智能体

在此示例中,您将自定义REINFORCE训练循环转换为自定义智能体类。 有关REINFORCE自定义训练回路的更多信息,请参阅 Train Reinforcement Learning Policy Using Custom Training Loop。 有关编写自定义智能体类的更多信息,请参见 Custom Agents。

固定随机生成器种子的再现性。

rng(0)

创建环境

创建使用“Train Reinforcement Learning Policy Using Custom Training Loop example”中使用的相同训练环境。 该环境是具有离散动作空间的平衡杆环境。 使用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,'Normalization','none','Name','state')fullyConnectedLayer(24,'Name','fc1')reluLayer('Name','relu1')fullyConnectedLayer(24,'Name','fc2')reluLayer('Name','relu2')fullyConnectedLayer(2,'Name','output')softmaxLayer('Name','actionProb')];

使用rlStochasticActorRepresentation对象创建行动者表示。

actorOpts = rlRepresentationOptions('LearnRate',1e-3,'GradientThreshold',1);
actor = rlStochasticActorRepresentation(actorNetwork,...obsInfo,actInfo,'Observation','state',actorOpts);

自定义智能体类

要定义您的自定义智能体,请首先创建一个类,该类是rl.agent.CustomAgent类的子类。 此示例的自定义智能体类在CustomReinforceAgent.m中定义。

CustomReinforceAgent类具有以下类定义,该定义指示智能体类名称和关联的抽象智能体。

classdef CustomReinforceAgent < rl.agent.CustomAgent

要定义您的智能体,您必须指定以下内容:

  1. 智能体属性

  2. 构造函数

  3. 评估长期奖励折扣的评论者表示形式(如果学习需要)

  4. 根据当前观察选择动作的行动者表示(如果学习需要)

  5. 所需的智能体方法

  6. 可选智能体方法

智能体属性

在类文件的属性部分中,指定创建和训练智能体所需的任何参数。

rl.Agent.CustomAgent类已经包含智能体采样时间(SampleTime)以及操作和观察规范(分别为ActionInfo和ObservationInfo)的属性。

定制REINFORCE智能体定义了以下其他智能体属性。

properties% Actor representationActor% Agent optionsOptions% Experience bufferObservationBufferActionBufferRewardBuffer
endproperties (Access = private)% Training utilitiesCounterNumObservationNumAction
end

构造函数

要创建自定义智能体,您必须定义一个构造函数。 构造函数执行以下操作。

  1. 定义动作和观察规范。 有关创建这些规范的更多信息,请参见rlNumericSpec和rlFiniteSetSpec。

  2. 设置智能体属性。

  3. 调用基本抽象类的构造函数。

  4. 定义采样时间(在Simulink环境中进行训练所需)。

例如,CustomREINFORCEAgent构造函数根据输入行动者表示形式定义动作和观察空间。

function obj = CustomReinforceAgent(Actor,Options)%CUSTOMREINFORCEAGENT Construct custom agent%   AGENT = CUSTOMREINFORCEAGENT(ACTOR,OPTIONS) creates custom%   REINFORCE AGENT from rlStochasticActorRepresentation ACTOR%   and structure OPTIONS. OPTIONS has fields:%       - DiscountFactor%       - MaxStepsPerEpisode% (required) Call the abstract class constructor.obj = obj@rl.agent.CustomAgent();obj.ObservationInfo = Actor.ObservationInfo;obj.ActionInfo = Actor.ActionInfo;% (required for Simulink environment) Register sample time. % For MATLAB environment, use -1.obj.SampleTime = -1;% (optional) Register actor and agent options.Actor = setLoss(Actor,@lossFunction);obj.Actor = Actor;obj.Options = Options;% (optional) Cache the number of observations and actions.obj.NumObservation = prod(obj.ObservationInfo.Dimension);obj.NumAction = prod(obj.ActionInfo.Dimension);% (optional) Initialize buffer and counter.reset(obj);
end

构造函数使用函数句柄将actor表示的损失函数设置为lossFunction,该函数在CustomREINFORCEAgent.m中作为局部函数实现。

function loss = lossFunction(policy,lossData)% Create the action indication matrix.batchSize = lossData.batchSize;Z = repmat(lossData.actInfo.Elements',1,batchSize);actionIndicationMatrix = lossData.actionBatch(:,:) == Z;% Resize the discounted return to the size of policy.G = actionIndicationMatrix .* lossData.discountedReturn;G = reshape(G,size(policy));% Round any policy values less than eps to eps.policy(policy < eps) = eps;% Compute the loss.loss = -sum(G .* log(policy),'all');end

相关函数

要创建自定义强化学习智能体,您必须定义以下实现功能。

  1. getActionImpl —评估智能体策略并在模拟过程中选择一个智能体。

  2. getActionWithExplorationImpl —评估策略并在训练期间选择具有探索性的操作。

  3. learningImpl —智能体如何从当前经验中学习

要在自己的代码中调用这些函数,请使用抽象基类中的wrapper方法。 例如,要调用getActionImpl,请使用getAction。 wrapper 方法与实现方法具有相同的输入和输出参数。

getActionImpl Function

getActionImpl函数用于评估智能体的策略,并在使用sim函数模拟智能体时选择操作。 此函数必须具有以下签名,其中obj是智能体对象,observation是当前观察值,而Action是选定的动作。

 function Action = getActionImpl(obj,Observation)

对于自定义REINFORCE智能体,您可以通过调用行动者表示形式的getAction函数来选择一个动作。 离散rlStochasticActorRepresentation根据观察值生成离散分布,并从该分布中采样一个动作。

function Action = getActionImpl(obj,Observation)% Compute an action using the policy given the current % observation.Action = getAction(obj.Actor,Observation);
end

getActionWithExplorationImpl Function

使用训练函数训练智能体时,getActionWithExplorationImpl函数使用智能体的探索模型选择动作。 使用此函数,您可以实现诸如epsilon-greedy探索或添加高斯噪声之类的探索技术。 此函数必须具有以下签名,其中obj是智能体对象,observation是当前观察值,而Action是选定的动作。

function Action = getActionWithExplorationImpl(obj,Observation)

对于自定义REINFORCE智能体,getActionWithExplorationImpl函数与getActionImpl相同。 默认情况下,随机行动者总是进行探索,也就是说,他们总是根据概率分布选择一个动作。

function Action = getActionWithExplorationImpl(obj,Observation)% Compute an action using the exploration policy given the  % current observation.% REINFORCE: Stochastic actors always explore by default% (sample from a probability distribution)Action = getAction(obj.Actor,Observation);
end

learnImpl Function

learningImpl函数定义智能体如何从当前经验中学习。 此函数通过更新策略参数并选择探索下一个状态的动作来实现智能体的自定义学习算法。 该函数必须具有以下签名,其中obj是智能体对象,Experience是当前的智能体经验,而Action是选定的操作。

function Action = learnImpl(obj,Experience)

智能体经验是单元格数组Experience = {state,action,reward,nextstate,isdone}。 这里:

  1. 状态是当前的观察。

  2. 动作是当前动作。 这不同于输出参数Action,后者是下一个状态的动作。

  3. 奖励是当前的奖励。

  4. nextState是下一个观察值。

  5. isDone是一个逻辑标志,指示训练episode 已完成。

对于自定义REINFORCE智能体,请在“使用自定义训练循环的强化训练策略”中重复自定义训练循环的步骤2至7。 您将省略步骤1、8和9,因为您将使用内置的训练函数来训练您的智能体。

function Action = learnImpl(obj,Experience)% Define how the agent learns from an Experience, which is a% cell array with the following format.%   Experience = {observation,action,reward,nextObservation,isDone}% Reset buffer at the beginning of the episode.if obj.Counter < 2resetBuffer(obj);end% Extract data from experience.Obs = Experience{1};Action = Experience{2};Reward = Experience{3};NextObs = Experience{4};IsDone = Experience{5};% Save data to buffer.obj.ObservationBuffer(:,:,obj.Counter) = Obs{1};obj.ActionBuffer(:,:,obj.Counter) = Action{1};obj.RewardBuffer(:,obj.Counter) = Reward;if ~IsDone% Choose an action for the next state.Action = getActionWithExplorationImpl(obj, NextObs);obj.Counter = obj.Counter + 1;else% Learn from episodic data.% Collect data from the buffer.BatchSize = min(obj.Counter,obj.Options.MaxStepsPerEpisode);ObservationBatch = obj.ObservationBuffer(:,:,1:BatchSize);ActionBatch = obj.ActionBuffer(:,:,1:BatchSize);RewardBatch = obj.RewardBuffer(:,1:BatchSize);% Compute the discounted future reward.DiscountedReturn = zeros(1,BatchSize);for t = 1:BatchSizeG = 0;for k = t:BatchSizeG = G + obj.Options.DiscountFactor ^ (k-t) * RewardBatch(k);endDiscountedReturn(t) = G;end% Organize data to pass to the loss function.LossData.batchSize = BatchSize;LossData.actInfo = obj.ActionInfo;LossData.actionBatch = ActionBatch;LossData.discountedReturn = DiscountedReturn;% Compute the gradient of the loss with respect to the% actor parameters.ActorGradient = gradient(obj.Actor,'loss-parameters',...{ObservationBatch},LossData);% Update the actor parameters using the computed gradients.obj.Actor = optimize(obj.Actor,ActorGradient);% Reset the counter.obj.Counter = 1;end
end

可选功能

(可选)您可以通过指定带有以下函数签名的resetImpl函数来定义训练开始时如何重置智能体,其中obj是智能体对象。

function resetImpl(obj)

使用此函数,您可以在训练前将智能体设置为已知或随机条件。

function resetImpl(obj)% (Optional) Define how the agent is reset before training/resetBuffer(obj);obj.Counter = 1;
end

另外,您可以根据需要在自定义智能体类中定义任何其他帮助函数。 例如,自定义REINFORCE智能体定义了resetBuffer函数,用于在每个训练episode开始时重新初始化体验缓冲区。

function resetBuffer(obj)% Reinitialize all experience buffers.obj.ObservationBuffer = zeros(obj.NumObservation,1,obj.Options.MaxStepsPerEpisode);obj.ActionBuffer = zeros(obj.NumAction,1,obj.Options.MaxStepsPerEpisode);obj.RewardBuffer = zeros(1,obj.Options.MaxStepsPerEpisode);
end

创建自定义智能体

定义自定义智能体类后,在MATLAB工作空间中创建它的实例。 要创建自定义REINFORCE智能体,请首先指定智能体选项。

options.MaxStepsPerEpisode = 250;
options.DiscountFactor = 0.995;

然后,使用选项和先前定义的行动者表示形式,调用自定义智能体构造函数。

agent = CustomReinforceAgent(actor,options);

训练自定义智能体

配置训练以使用以下选项。

  1. 将训练设置为最多持续5000个episode,每个episode最多持续250个步骤。

  2. 在达到最大episode次数后或在100个发作中的平均奖励达到240的值时终止训练。

numEpisodes = 5000;
aveWindowSize = 100;
trainingTerminationValue = 240;
trainOpts = rlTrainingOptions(...'MaxEpisodes',numEpisodes,...'MaxStepsPerEpisode',options.MaxStepsPerEpisode,...'ScoreAveragingWindowLength',aveWindowSize,...'StopTrainingValue',trainingTerminationValue);

使用训练函数训练智能体。 训练此智能体是一个计算密集型过程,需要几分钟才能完成。 为了节省运行本示例的时间,请通过将doTraining设置为false来加载预训练的智能体。 要自己训练智能体,请将doTraining设置为true

doTraining = false;
if doTraining% Train the agent.trainStats = train(agent,env,trainOpts);
else% Load pretrained agent for the example.load('CustomReinforce.mat','agent');
end

自定义智能体仿真

启用环境可视化,该环境可视化在每次调用环境步骤功能时更新。

plot(env)

要验证训练后的智能体的表现,请在倒立摆环境中对其进行仿真。 有关智能体模拟的更多信息,请参见rlSimulationOptions和sim。

simOpts = rlSimulationOptions('MaxSteps',options.MaxStepsPerEpisode);
experience = sim(env,agent,simOpts);

MATLAB强化学习实战(十二) 创建自定义强化学习算法的智能体相关推荐

  1. Caffe学习记录(十二) ICNet分割网络学习二

    在ICNet分割网络训练的过程中,发生了很郁闷的事情, 首先ICNet的训练数据准备,和segnet一样,需要准备原始数据,mask 已经对应的txt文件,格式为pathofdata 空格 patho ...

  2. OpenCV学习笔记(十二)——图像分割与提取

    在图像处理的过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来.例如,在视频监控中,观测到的是固定背景下的视频内容,而我们对背景本身并无兴趣,感兴趣的是背景中出现的车辆.行人或者其他对象. ...

  3. VSTO 学习笔记(十二)自定义公式与Ribbon

    原文:VSTO 学习笔记(十二)自定义公式与Ribbon 这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果.这次我们来做一个简单的测试,达到类似的目的. 即在Excel ...

  4. 强化学习经典算法笔记(十二):近端策略优化算法(PPO)实现,基于A2C(下)

    强化学习经典算法笔记(十二):近端策略优化算法(PPO)实现,基于A2C 本篇实现一个基于A2C框架的PPO算法,应用于连续动作空间任务. import torch import torch.nn a ...

  5. Python语言入门这一篇就够了-学习笔记(十二万字)

    Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...

  6. jQuery学习(十二)—jQuery中对象的查找方法总结

    jQuery学习(十二)-jQuery中对象的查找方法总结 一.find方法 作用:在元素1中查找元素2,类似于选择器中的后代选择器 格式:元素1.find(元素2),元素2为CSS选择器或者jQue ...

  7. HTML学习第十二章------布局和排版

    HTML学习第十二章------布局和排版 教材:Head First HTML与CSS 布局 浏览器用流(flow)来布置页面上的XHTML元素, 即跟着元素的流(顺序)来进行显示. 块元素是从头流 ...

  8. Mysql学习总结十二:系统变量、用户变量、定义条件和处理程序

    Mysql学习总结十二:系统变量.用户变量.定义条件和处理程序 1.变量 1.1 系统变量 1.1.1 系统变量的分类 1.1.2 查看系统变量 1.2 用户变量 1.2.1 用户变量的分类 1.2. ...

  9. C语言学习(十二)C语言中的字符(宽字符与窄字符)、从字符谈谈C语言的编码、转义字符

    C语言学习(十二)C语言中的字符(宽字符与窄字符).从字符谈谈C语言的编码.转义字符 目录 C语言学习(十二)C语言中的字符(宽字符与窄字符).从字符谈谈C语言的编码.转义字符 英文字符 字符的表示 ...

最新文章

  1. Android开发之Service与Activity数据交互(源代码分享)
  2. Android NDK JNI 的简单使用
  3. Leecode02-两数相加——Leecode热题100道系列
  4. 【转】glTexImage2D()和gluBuild2DMipmaps() [将载入的位图文件(*.bmp)转换成纹理贴图]+glTexParameteri()纹理过滤函数...
  5. 程序员不满薪资拒绝offer,HR怒称:估计你一辈子就是个程序员
  6. ascii码与键盘代码的区别
  7. 理解RESTful架构(转)
  8. vob文件怎么转换成mp4?
  9. dataframe分组并求平均
  10. IP地址、网络号、主机号、网络地址、子网掩码、网关、192.168.0.1/24是什么意思
  11. 面试官:SPA(单页应用)首屏加载速度慢怎么解决?
  12. NodeMCU连接SD读卡器
  13. smtp java 抓包_[Wireshark]_003_电子邮件抓包分析
  14. 通达信指标公式编写常用函数(六)——SUM、IF
  15. Eclipse下更新项目出现.settings/org.eclipse.wst.common.component冲突
  16. IE浏览器:注定消亡?
  17. windows python3 bz2怎么安装_正确地建造本地Python3,用bz2支持
  18. COOX培训材料 — PMT(1.Phase)
  19. PHP中的6种加密方式
  20. python 录音vad_2020-02-25 python使用ffmpeg、speech-vad-demo、百度语音识别生成字幕

热门文章

  1. 我们如何研发了世界上最酷的调车内燃机车自动驾驶系统
  2. java导出excel
  3. 初中数学抽象教学的案例_初中数学典型教学案例与反思.doc
  4. 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 总共多少步
  5. QVGA/HVGA/WVGA/FWVGA分辨率屏含义及大小
  6. 骨龄仪存储卡损坏处理方案
  7. 华为群面失败回顾。记录是为了更好地思考
  8. win10系统无法连接xp工作组计算机,win10系统看不到windows xp系统主机上工作组的具体教程...
  9. Alfresco使用手册
  10. 不想做CEO的程序员不是好码农?