此示例显示了如何使用并行训练在Simulink®中训练深度Q学习网络(DQN)智能体以保持车道辅助(LKA)。 有关显示如何在不使用并行训练的情况下训练智能体的示例,请参阅 Train DQN Agent for Lane Keeping Assist。
matlab版本2020b。
DQN并行训练概述
在DQN智能体中,每个工作人员都从其智能体副本和环境中产生新的经验。 每隔N个步骤,工作人员就会将经验发送给主机智能体。 主机智能体如下更新其参数。
-
对于异步训练,主机智能体可以从接收到的经验中学习,而无需等待所有工作人员发送经验,然后将更新的参数发送回提供经验的工作人员。 然后,工作人员继续使用更新的参数从其环境中产生经验。
-
对于同步训练,主机智能体等待接收所有工人的经验并从这些经验中学习。 然后,主机同时将更新的参数发送给所有工作程序。 然后,所有工作人员将继续使用更新的参数来产生经验。
Ego Car 的 Simulink 模型
此示例的强化学习环境是用于车辆动力学的简单自行车模型。 训练的目标是通过调整前转向角来保持自行车沿着车道的中心线行驶。 本示例使用与Train DQN Agent for Lane Keeping Assist相同的车辆模型。
m = 1575; % total vehicle mass (kg)
Iz = 2875; % yaw moment of inertia (mNs^2)
lf = 1.2; % longitudinal distance from center of gravity to front tires (m)
lr = 1.6; % longitudinal distance from center of gravity to rear tires (m)
Cf = 19000; % cornering stiffness of front tires (N/rad)
Cr = 33000; % cornering stiffness of rear tires (N/rad)
Vx = 15; % longitudinal velocity (m/s)
以秒为单位定义采样时间Ts和仿真持续时间T。
Ts = 0.1;
T = 15;
LKA系统的输出是自行车的前转向角。 要模拟自行车的物理转向限制,请将转向角限制在[–0.5,0.5] rad范围内。
u_min = -0.5;
u_max = 0.5;
道路的曲率定义为常数 0.001 ( m − 1 ) 0.001 (m^{-1}) 0.001(m−1)。横向偏差初始值为0.2 m,相对偏航角初始值为0.1 rad。
rho = 0.001;
e1_initial = 0.2;
e2_initial = -0.1;
打开模型
mdl = 'rlLKAMdl';
open_system(mdl)
agentblk = [mdl '/RL Agent'];
点击进入。
对于这个模型:
- 从agent到环境的舵角动作信号为15度到15度。
- 从环境中观察到的是横向偏差 e 1 e_1 e1,相对偏航角 e 2 e_2 e2,它们的导数 e 1 ˙ \dot{e_1} e1˙和 e 2 ˙ \dot{e_2} e2˙,以及它们的积分 ∫ e 1 \int{e_1} ∫e1和 ∫ e 2 \int{e_2} ∫e2。
- 当侧向偏移 ∣ e 1 ∣ |e_1| ∣e1∣ >1时,仿真终止。
- 每一步t提供的奖励
r
t
r_t
rt为
其中 u u u是来自上一时间步 t − 1 t-1 t−1的控制输入。
创建环境接口
创建 ego vehicle 的强化学习环境界面。
定义观察信息。
observationInfo = rlNumericSpec([6 1],'LowerLimit',-inf*ones(6,1),'UpperLimit',inf*ones(6,1));
observationInfo.Name = 'observations';
observationInfo.Description = 'information on lateral deviation and relative yaw angle';
定义动作信息。
actionInfo = rlFiniteSetSpec((-15:15)*pi/180);
actionInfo.Name = 'steering';
创建环境接口。
env = rlSimulinkEnv(mdl,agentblk,observationInfo,actionInfo);
该界面具有离散的动作空间,智能体可以在其中应用从–15度到15度的31个可能的转向角之一。 观测值是包含横向偏差,相对偏航角及其相对于时间的导数和积分的六维向量。
要定义横向偏差和相对偏航角的初始条件,请使用匿名函数句柄指定环境重置函数。 在此示例末尾定义的localResetFcn使初始横向偏斜和相对偏航角随机化。
env.ResetFcn = @(in)localResetFcn(in);
固定随机发生器种子的重现性。
rng(0)
创建DQN智能体
DQN智能体可以使用通常更有效的多输出Q值评论者近似器。 一个多输出近似器将观测值作为输入,并将状态作用值作为输出。 每个输出元素代表从观察输入所指示的状态采取相应离散操作的预期累积长期奖励。
要创建评论者,首先要创建一个具有一个输入(六维观察状态)和一个具有31个元素(从-15度到15度均匀隔开的转向角)的输出向量的深层神经网络。 有关创建深度神经网络值函数表示的更多信息,请参见创建策略和值函数表示。
nI = observationInfo.Dimension(1); % number of inputs (6)
nL = 120; % number of neurons
nO = numel(actionInfo.Elements); % number of outputs (31)
dnn = [
featureInputLayer(nI,'Normalization','none','Name','state')
fullyConnectedLayer(nL,'Name','fc1')
reluLayer('Name','relu1')
fullyConnectedLayer(nL,'Name','fc2')
reluLayer('Name','relu2')
fullyConnectedLayer(nO,'Name','fc3')];
查看网络配置。
figure
plot(layerGraph(dnn))
使用rlRepresentationOptions指定评论者表示的选项。
criticOptions = rlRepresentationOptions('LearnRate',1e-4,'GradientThreshold',1,'L2RegularizationFactor',1e-4);
使用指定的深度神经网络和选项创建评论者表示。 您还必须指定评论者的操作和观察信息,这些信息是从环境界面获得的。 有关更多信息,请参见rlQValueRepresentation。
critic = rlQValueRepresentation(dnn,observationInfo,actionInfo,'Observation',{'state'},criticOptions);
要创建DQN智能体,请首先使用rlDQNAgentOptions指定DQN智能体选项。
agentOpts = rlDQNAgentOptions(...
'SampleTime',Ts,...
'UseDoubleDQN',true,...
'TargetSmoothFactor',1e-3,...
'DiscountFactor',0.99,...
'ExperienceBufferLength',1e6,...
'MiniBatchSize',256);
agentOpts.EpsilonGreedyExploration.EpsilonDecay = 1e-4;
然后使用指定的评论者表示形式和智能体选项创建DQN智能体。 有关更多信息,请参见rlDQNAgent。
agent = rlDQNAgent(critic,agentOpts);
训练选项
要训练智能体,请首先指定训练选项。 对于此示例,使用以下选项。
-
每次训练最多进行10000episode,每个episode持续最多ceil(T / Ts)个时间步长。
-
仅在“情节管理器”对话框中显示训练进度(相应地设置“Plots ”和“Verbose ”选项)。
-
当情节奖励达到-1时,停止训练。
-
为累积奖励大于100的每个情节保存智能体的副本。
maxepisodes = 10000;
maxsteps = ceil(T/Ts);
trainOpts = rlTrainingOptions(...
'MaxEpisodes',maxepisodes, ...
'MaxStepsPerEpisode',maxsteps, ...
'Verbose',false,...
'Plots','training-progress',...
'StopTrainingCriteria','EpisodeReward',...
'StopTrainingValue', -1,...
'SaveAgentCriteria','EpisodeReward',...
'SaveAgentValue',100);
并行计算选项
要并行训练智能体,请指定以下训练选项。
-
将UseParallel选项设置为true。
-
通过将ParallelizationOptions.Mode选项设置为“ async”,异步并行地训练智能体。
-
每隔30步,每个工作人员就会将经验发送给主机。
-
DQN智能体要求工作人员将“经验”发送给主机。
trainOpts.UseParallel = true;
trainOpts.ParallelizationOptions.Mode = "async";
trainOpts.ParallelizationOptions.DataToSendFromWorkers = "experiences";
trainOpts.ParallelizationOptions.StepsUntilDataIsSent = 32;
训练智能体
使用训练功能训练智能体。 训练智能体是一个计算密集型过程,需要几分钟才能完成。 为了节省运行本示例的时间,请通过将doTraining设置为false来加载预训练的智能体。 要自己训练智能体,请将doTraining设置为true。 由于并行训练的随机性,您可以从以下图表中得出不同的训练结果。
doTraining = false;
if doTraining
% Train the agent.
trainingStats = train(agent,env,trainOpts);
else
% Load pretrained agent for the example.
load('SimulinkLKADQNParallel.mat','agent')
end
DQN智能体仿真
要验证受过训练的智能体的性能,请取消注释以下两行,并在环境中模拟智能体。 有关智能体模拟的更多信息,请参见rlSimulationOptions和sim。
% simOptions = rlSimulationOptions('MaxSteps',maxsteps);
% experience = sim(env,agent,simOptions);
如果出现上图所示的错误,在当前目录下创建函数localResetFcn.m,粘贴以下代码
function in = localResetFcn(in)
% reset
in = setVariable(in,'e1_initial', 0.5*(-1+2*rand)); % random value for lateral deviation
in = setVariable(in,'e2_initial', 0.1*(-1+2*rand)); % random value for relative yaw angle
end
重新执行仿真命令。
要使用确定性初始条件演示训练后的智能体,请在Simulink中模拟模型。
e1_initial = -0.4;
e2_initial = 0.2;
sim(mdl)
如下所示,横向误差(中间图)和相对偏航角(底部图)都被驱动为零。 车辆从偏离中心线(–0.4 m)和非零偏航角误差(0.2 rad)开始。 LKA使自行车在2.5秒后沿着中心线行驶。 转向角(上图)显示控制器在2秒后达到稳定状态。