配水系统调度使用强化学习
这个例子展示了如何学习的最佳泵配水系统的调度策略利用强化学习(RL)。
配水系统
下面的图显示了一个配水系统。
在这里:
是提供的水量从储水箱。
流出的水量的坦克来满足使用需求。
强化学习的目标代理调度运行的水泵数量最小化系统的能源使用和满足使用需求( )。坦克的动力系统由以下方程。
在这里, 和 。在24小时内的需求作为时间的函数
在哪里 预期的需求和吗 代表了需求的不确定性,这是取样均匀随机分布。
供应的数量是由泵运行, 根据下面的映射。
为了简化问题,电力消耗的定义是水泵运行的数量, 。
下面的函数是这个环境的奖励。避免溢出或排空水箱,添加一个附加的成本如果水高度接近最大值或最低水位, 或 ,分别。
生成需求概要
生成和基于的天数的水需求概要文件,使用generateWaterDemand
函数定义的这个例子。
num_days = 4;%的天数[WaterDemand, T_max] = generateWaterDemand (num_days);
查看需求概要文件。
情节(WaterDemand)
开放和配置模型
打开配电系统仿真软件模型。金宝app
mdl =“watertankscheduling”;open_system (mdl)
除了强化学习代理,一个简单的基线控制器控制律中定义的MATLAB函数块。这个控制器激活一定数量的泵根据水位。
指定初始水高度。
h0 = 3;% m
指定模型参数。
SampleTime = 0.2;H_max = 7;%马克斯槽高度(米)A_tank = 40;%的坦克(m ^ 2)
为RL创建环境接口代理
创建一个环境界面的仿真软件模型,首先定义操作和观察规格,金宝appactInfo
和obsInfo
,分别。代理行为是所选泵的数量。代理观察水的高度,这是作为一个连续时间信号测量。
actInfo = rlFiniteSetSpec ([0, 1, 2, 3]);obsInfo = rlNumericSpec ([1]);
创建环境的接口。
env = rl金宝appSimulinkEnv (mdl mdl +“/ RL代理”、obsInfo actInfo);
指定一个自定义的重置功能,这是定义在这个例子中,随机初始水高度和水的需求。这样做将允许代理被训练在不同初始水位和水需求函数为每个事件。
env。ResetFcn = @(在)localResetFcn(的);
演员和评论家网络随机初始化。确保修复种子再现性的随机发生器。
rng (0);
创建DQN代理
DQN代理使用参数化核反应能量函数近似者估计价值的政策。因为DQN代理有一个离散的行动空间,您可以选择创建一个向量(即多输出)评论家核反应能量函数,通常比对于类似的批评更有效。
一个向量核反应能量函数只需要观察作为输入并返回一个作为输出向量和尽可能多的元素的数量可能的行动。每个输出元素代表的价值预期的折扣累积长期奖励当代理人开始从国家对应于给定的观察和执行相应的动作元素的数量(和后来跟随给定的政策)
在评论家,模型参数化核反应能量函数使用一个临时神经网络。使用递归神经网络,集useLSTM
来真正的
。请注意,刺激(obsInfo.Dimension)
返回观察空间的维数(不管他们是否安排作为一个行向量,列向量,或矩阵,元素个数(actInfo.Elements)
返回的元素数量的离散动作空间。
useLSTM = false;如果useLSTM层= [sequenceInputLayer (prod (obsInfo.Dimension)) fullyConnectedLayer (32) reluLayer lstmLayer (32) fullyConnectedLayer (32) reluLayer fullyConnectedLayer(元素个数(actInfo.Elements)));其他的层= [featureInputLayer (obsInfo.Dimension (1) fullyConnectedLayer (32) reluLayer fullyConnectedLayer (32) reluLayer fullyConnectedLayer (32) reluLayer fullyConnectedLayer(元素个数(actInfo.Elements)));结束
转换为一个dlnetwork
对象和显示参数的数量。
款= dlnetwork(层);总结(款)
初始化:真很多可学的:2.3 k输入:1“输入”功能
创建一个评论家使用rlVectorQValueFunction
使用定义的深层神经网络和环境规范。
评论家= rlVectorQValueFunction(款、obsInfo actInfo);
创建DQN代理
指定培训选项的评论家和演员使用rlOptimizerOptions
。
criticOpts = rlOptimizerOptions (LearnRate = 0.001, GradientThreshold = 1);
使用指定DDPG代理选项rlDQNAgentOptions
。如果您正在使用一个LSTM网络,设置序列长度20.
。
选择= rlDQNAgentOptions (SampleTime = SampleTime);如果useLSTM opt.SequenceLength = 20;其他的opt.SequenceLength = 1;结束opt.DiscountFactor = 0.995;opt.ExperienceBufferLength = 1 e6;opt.EpsilonGreedyExploration。EpsilonDecay = 1 e-5;opt.EpsilonGreedyExploration。EpsilonMin = .02点;
包括培训选项评论家。
opt.CriticOptimizerOptions = criticOpts;
使用评论家和选项创建代理对象。
代理= rlDQNAgent(评论家,选择);
火车代理
培训代理商,首先指定培训选项。对于这个示例,使用以下选项。
运行培训1000集,每集持久
装天花板(T_max / Ts)
时间的步骤。在事件管理器对话框显示培训进展(设置
情节
选项)
培训使用一个指定的选项rlTrainingOptions
对象。
trainOpts = rlTrainingOptions (…MaxEpisodes = 1000,…MaxStepsPerEpisode =装天花板(T_max / SampleTime),…Verbose = false,…情节=“训练进步”,…StopTrainingCriteria =“EpisodeCount”,…StopTrainingValue = 1000,…ScoreAveragingWindowLength = 100);
虽然你不这样做对于这个示例,您可以保存代理在训练过程中。例如,以下选项保存每个代理奖励值大于或等于-42年
。
使用在必要时SaveAgentCriteria trainOpts省代理。SaveAgentCriteria = " EpisodeReward”;trainOpts。SaveAgentValue = -42;
火车代理使用火车
函数。培训这个代理是一个计算密集型过程,需要几个小时才能完成。节省时间在运行这个例子中,加载一个pretrained代理设置doTraining
来假
。训练自己代理,集doTraining
来真正的
。
doTraining = false;如果doTraining%连接RL代理阻止中断点%的手动开关部件set_param (mdl +“/手动开关”,“西南”,“0”);%培训代理。trainingStats =火车(代理,env, trainOpts);其他的%加载pretrained代理的例子。负载(“金宝appSimulinkWaterDistributionDQN.mat”,“代理”)结束
下面的图显示了培训的进展。
模拟DQN代理
验证培训代理的性能,模拟在水箱的环境。代理模拟更多的信息,请参阅rlSimulationOptions
和sim卡
。
模拟剂性能、连接块通过手动切换开关块RL代理。
set_param (mdl +“/手动开关”,“西南”,“0”);
设置步骤的最大数量为每个模拟和仿真的数量。对于本例,30模拟运行。环境重置函数集不同初始水高度和在每个模拟水需求是不同的。
NumSimulations = 30;simOptions = rlSimulationOptions (MaxSteps = T_max / SampleTime,…NumSimulations = NumSimulations);
与基线比较代理控制器在相同条件下,重置初始随机环境中使用的种子复位功能。
env.ResetFcn (“重置种子”);
模拟剂对环境。
experienceDQN = sim (env,代理,simOptions);
模拟基线控制器
与基线比较DQN代理控制器,您必须使用相同的仿真模拟基线控制器选项和初始随机种子复位功能。
使基线控制器。
set_param (mdl +“/手动开关”,“西南”,“1”);
与基线比较代理控制器在相同条件下,重置环境中使用的随机种子复位功能。
env.ResetFcn (“重置种子”);
模拟对环境基线控制器。
experienceBaseline = sim (env,代理,simOptions);
与基线比较DQN代理控制器
初始化累积奖励结果向量为代理和基线控制器。
resultVectorDQN = 0 (NumSimulations, 1);resultVectorBaseline = 0 (NumSimulations, 1);
计算累积奖励为代理和基线控制器。
为ct = 1: NumSimulations resultVectorDQN (ct) =总和(experienceDQN (ct) .Reward);resultVectorBaseline (ct) =总和(experienceBaseline (ct) .Reward);结束
情节的累积奖励。
情节([resultVectorDQN resultVectorBaseline),“o”甘氨胆酸)组(,“xtick”1:NumSimulations)包含(“模拟数字”)ylabel (“累积奖励”)传说(“DQN”,“基线”,“位置”,“NorthEastOutside”)
累计获得的奖励代理一直约-40。这个值远远大于获得的平均回报基线控制器。因此,DQN代理始终优于基线控制器而言,节省能源。
本地函数
水需求函数
函数[WaterDemand, T_max] = generateWaterDemand (num_days) t = 0: (num_days * 24) 1;%的人力资源T_max = t(结束);Demand_mean =[28日,28日,28岁,45岁,55岁,110年,…280,450,310,170,160,145,…130,150,165,155,170,265,…360、240、120、83、45、28];% m ^ 3 /人力资源需求= repmat (Demand_mean 1 num_days);需求=需求(:);%添加噪声要求一个= -25;% m ^ 3 /人力资源b = 25;% m ^ 3 /人力资源Demand_noise = a + (b)。*兰德(元素个数(需求),1);WaterDemand = timeseries(需求+ Demand_noise, t);WaterDemand。Name =“水需求”;WaterDemand.TimeInfo。单位=“小时”;结束
重置功能
函数= localResetFcn(中)%使用持久随机种子值来评估代理%和基线控制器在相同条件下。持续的randomSeed如果isempty (randomSeed) randomSeed = 0;结束如果比较字符串(在“重置种子”)randomSeed = 0;返回结束randomSeed = randomSeed + 1;rng (randomSeed)%随机水需求。num_days = 4;H_max = 7;[WaterDemand ~] = generateWaterDemand (num_days);assignin (“基地”,“WaterDemand”WaterDemand)%随机初始高度。h0 = 3 * randn;而h0 < = 0 | | h0 > = H_max h0 = 3 * randn;结束黑色=“watertankscheduling /水箱系统/初始水高度”;在= setBlockParameter(黑色,“价值”num2str (h0));结束