使用Deep Network Designer创建智能体并使用图像观察进行训练
本示例说明了如何创建深度Q学习网络(DQN)智能体,该智能体可以平衡在MATLAB®中建模的钟摆。 在此示例中,您将使用Deep Network Designer创建DQN智能体。 有关DQN智能体的更多信息,请参阅 Deep Q-Network Agents。
有图像观测的摆锤环境
此示例的强化学习环境是一个简单的无摩擦摆,其最初悬挂在向下的位置。 训练的目标是使摆锤直立,而无需花费最少的控制力。
对于这种环境:
- 平衡摆向上位置为0弧度,向下悬挂位置为pi弧度。
- 智能体到环境的扭矩动作信号为2 ~ 2 N·m。
- 从环境观测得到的是简化的摆灰度图像和摆角导数。
- 每一步提供的奖励
r
t
r _t
rt为
其中:
- θ t \theta_t θt从直立位置到位移的角度。
- θ ˙ t \dot\theta_t θ˙t是位移角的导数。
- u t − 1 u_{t-1} ut−1是前一个时间步骤的控制工作。
创建环境接口
为钟摆创建一个预定义的环境接口。
env = rlPredefinedEnv('SimplePendulumWithImage-Discrete');
该界面有两个观察结果。 第一个观察结果称为“ pendImage”,是一个50 x 50的灰度图像。
obsInfo = getObservationInfo(env);
obsInfo(1)
第二个观测值称为“ angularRate”,是摆的角速度。
obsInfo(2)
接口具有离散的动作空间,智能体可以在其中将五个可能的扭矩值之一施加到摆锤上:-2,-1、0、1或2 N·m。
actInfo = getActionInfo(env)
固定随机发生器种子的重现性。
rng(0)
使用深度网络设计器构建critic网络
DQN智能体使用评论者价值函数表示法,根据给定的观察和操作来估算长期奖励。 对于这种环境,评论者是一个具有三个输入(两个观察值和一个动作)和一个输出的深度神经网络。 有关创建深度神经网络值函数表示的更多信息,请参见创建策略和值函数表示。
您可以使用Deep Network Designer应用程序以交互方式构建critic网络。 为此,您首先为每个观察和操作创建单独的输入路径。 这些路径从各自的输入中学习较低级别的功能。 然后,创建一个公共输出路径,该路径将输入路径的输出组合在一起。
创建图像观测路径
要创建图像观察路径,请首先将ImageInputLayer从Layer Library窗格拖到画布。 将图层InputSize设置为50,50,1进行图像观察,并将Normalization设置为none。
其次,将Convolution2DLayer拖到画布上,并将该层的输入连接到ImageInputLayer的输出。 使用2个高度和宽度为10的过滤器(NumFilters属性)创建一个卷积层(FilterSize属性),并在水平和垂直方向上使用5步长(Stride属性)。
最后,使用两组ReLULayer和FullyConnectedLayer图层完成图像路径网络。 第一和第二FullyConnectedLayer层的输出大小分别为400和300。
创建全输入路径和输出路径
以类似的方式构造其他输入路径和输出路径。 对于此示例,使用以下选项。
Angular velocity路径(标量输入):
-
ImageInputLayer —将InputSize设置为1,1,将Normalization设置为none。
-
FullyConnectedLayer —将OutputSize设置为400。
-
ReLULayer
-
FullyConnectedLayer —将OutputSize设置为300。
Action 路径(标量输入):
-
ImageInputLayer — 将InputSize设置为1,1,将Normalization设置为none。
-
FullyConnectedLayer — 将OutputSize设置为300。
Output路径:
-
AdditionLayer —将所有输入路径的输出连接到该层的输入。
-
ReLULayer
-
FullyConnectedLayer —将标量值函数的OutputSize设置为1。
从Deep Network Designer导出网络
要将网络导出到MATLAB工作区,请在Deep Network Designer中单击“导出”。 Deep Network Designer将网络导出为包含网络层的新变量。 您可以使用此图层网络变量创建评论者表示。
或者,要为网络生成等效的MATLAB代码,请单击导出>生成代码。
生成的代码如下。
lgraph = layerGraph();
layers = [
imageInputLayer([1 1 1],"Name","torque","Normalization","none")
fullyConnectedLayer(300,"Name","torque_fc1")];
lgraph = addLayers(lgraph,layers);
layers = [
imageInputLayer([1 1 1],"Name","angularRate","Normalization","none")
fullyConnectedLayer(400,"Name","dtheta_fc1")
reluLayer("Name","dtheta_relu1")
fullyConnectedLayer(300,"Name","dtheta_fc2")];
lgraph = addLayers(lgraph,layers);
layers = [
imageInputLayer([50 50 1],"Name","pendImage","Normalization","none")
convolution2dLayer([10 10],2,"Name","img_conv1","Stride",[5 5])
reluLayer("Name","img_relu")
fullyConnectedLayer(400,"Name","theta_fc1")
reluLayer("Name","theta_relu1")
fullyConnectedLayer(300,"Name","theta_fc2")];
lgraph = addLayers(lgraph,layers);
layers = [
additionLayer(3,"Name","addition")
reluLayer("Name","relu")
fullyConnectedLayer(1,"Name","stateValue")];
lgraph = addLayers(lgraph,layers);
lgraph = connectLayers(lgraph,"torque_fc1","addition/in3");
lgraph = connectLayers(lgraph,"theta_fc2","addition/in1");
lgraph = connectLayers(lgraph,"dtheta_fc2","addition/in2");
查看评论者网络配置。
figure
plot(lgraph)
使用rlRepresentationOptions指定评论者表示的选项。
criticOpts = rlRepresentationOptions('LearnRate',1e-03,'GradientThreshold',1);
使用指定的深度神经网络图和选项创建评论者表示。 您还必须指定评论者的操作和观察信息,这些信息是从环境界面获得的。 有关更多信息,请参见rlQValueRepresentation。
critic = rlQValueRepresentation(lgraph,obsInfo,actInfo,...
'Observation',{'pendImage','angularRate'},'Action',{'torque'},criticOpts);
要创建DQN智能体,请首先使用rlDQNAgentOptions指定DQN智能体选项。
agentOpts = rlDQNAgentOptions(...
'UseDoubleDQN',false,...
'TargetUpdateMethod',"smoothing",...
'TargetSmoothFactor',1e-3,...
'ExperienceBufferLength',1e6,...
'DiscountFactor',0.99,...
'SampleTime',env.Ts,...
'MiniBatchSize',64);
agentOpts.EpsilonGreedyExploration.EpsilonDecay = 1e-5;
然后,使用指定的评论者表示形式和智能体选项创建DQN智能体。 有关更多信息,请参见rlDQNAgent。
agentOpts = rlDQNAgentOptions(...
'UseDoubleDQN',false,...
'TargetUpdateMethod',"smoothing",...
'TargetSmoothFactor',1e-3,...
'ExperienceBufferLength',1e6,...
'DiscountFactor',0.99,...
'SampleTime',env.Ts,...
'MiniBatchSize',64);
agentOpts.EpsilonGreedyExploration.EpsilonDecay = 1e-5;
然后,使用指定的评论者表示形式和智能体选项创建DQN智能体。 有关更多信息,请参见rlDQNAgent。
agent = rlDQNAgent(critic,agentOpts);
训练智能体
要训练智能体,请首先指定训练选项。 对于此示例,使用以下选项。
-
每次训练最多进行5000个episode,每个episode最多持续500个时间步。
-
在“情节管理器”对话框中显示训练进度(设置“Plots ”选项)并禁用命令行显示(将“Verbose ”选项设置为false)。
-
当智能体在五个连续episode的默认窗口长度内收到的平均累积奖励大于–1000时,停止训练。 在这一点上,智能体可以以最小的控制力快速地使摆在直立位置上平衡。
trainOpts = rlTrainingOptions(...
'MaxEpisodes',5000,...
'MaxStepsPerEpisode',500,...
'Verbose',false,...
'Plots','training-progress',...
'StopTrainingCriteria','AverageReward',...
'StopTrainingValue',-1000);
您可以使用绘图功能在训练或模拟过程中可视化摆系统。
plot(env)
使用训练功能训练智能体。 这是一个需要大量时间才能完成的计算密集型过程。 为了节省运行本示例的时间,请通过将doTraining设置为false来加载预训练的代理。 要自己训练智能体,请将doTraining设置为true。
doTraining = false;
if doTraining
% Train the agent.
trainingStats = train(agent,env,trainOpts);
else
% Load pretrained agent for the example.
load('MATLABPendImageDQN.mat','agent');
end
智能体仿真
要验证训练后的智能体的表现,请在钟摆环境中对其进行仿真。 有关智能体模拟的更多信息,请参见rlSimulationOptions和sim。
simOptions = rlSimulationOptions('MaxSteps',500);
experience = sim(env,agent,simOptions);
totalReward = sum(experience.Reward)