强化学习实战-训练PPO智能体控制火箭着陆

环境

在此示例中,环境是一个3自由度火箭,以质量为圆盘表示。 火箭有两个推进器用于前进和旋转运动。 重力垂直向下作用,没有空气动力阻力。 训练的目标是使机器人在指定位置着陆。
对于这个环境:
1.火箭的运动的范围是X(水平轴)从-100到100米,Y(垂直轴)从0到120米。
2.目标位置为(0,0)米,目标方向为0弧度。
3.每个推进器施加的最大推力为8.5N。
4.采样时间为0.1秒。
5.来自环境的观测是火箭的位置(x,y),方向(θ),速度(x,y),角速度(θ),以及探测粗糙着陆(-1),软着陆(1)或机载(0)条件的传感器读数。观测值在-1到1之间标准化。
6.在每一个episode的开始,火箭从一个随机的x初始位置和方向开始。高度总是重置为100米。
7.在时间步骤t提供的奖励r_t如下。

其中:
1.x_t,y_t, x_t和y_t是火箭沿xy轴的位置和速度。
2.\hat{d_t}=\sqrt{x^2_t+y^2_t}/d_{max}为火箭到目标位置的归一化距离。
3.\hat{v_t}=\sqrt{\dot{x^2_t}+\dot{y^2_t}}/v_{max}是火箭的归一化速度。
4.d_{max}v_{max}是最大的距离和速度。
5.\theta_{t}是关于纵轴的方向。
6.L_tR_t是左右推进器的作用值。
7.c是水平和垂直速度小于0.5 m / s的软着陆的稀疏奖励。

创建MATLAB环境

使用RocketLander类为火箭着陆器创建MATLAB环境。

env = RocketLander;

使用MATLAB强化学习工具箱例程。

从环境中获取观测和动作规范。

actionInfo = getActionInfo(env);
observationInfo = getObservationInfo(env);
numObs = observationInfo.Dimension(1);
numAct = numel(actionInfo.Elements);

设置环境的采样时间

Ts = 0.1;

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

rng(0)

创建PPO智能体


这个例子中的PPO智能体在一个离散的动作空间上运行。在每个时间步骤中,智能体选择以下离散动作对中的一个。

L, L−do nothing
L, M−fire right (med)
L, H−fire right (high)
M, L−fire left (med)
M, M−fire left (med)+right (med)
M, H−fire left (med)+right (high)
H, L−fire left (high)
H, M−fire left (high)+right (med)
H, H−fire left (high)+right (high)

其中,L=0.0,M=0.5, H=1.0为每个推进器的归一化推力值。
为了估计策略和价值函数,agent为行动器和批判器维持函数近似器,这是使用深度神经网络建模的。训练对初始网络权值和偏差很敏感,结果会因不同的值集而不同。本例中,网络权值随机初始化为小值。
创建有六个输入和一个输出的批判器深度神经网络。批判器网络的输出是对输入观测的折扣长期回报。

criticLayerSizes = [400 300];
actorLayerSizes = [400 300];

criticNetwork = [
        featureInputLayer(numObs,'Normalization','none','Name','observation')
        fullyConnectedLayer(criticLayerSizes(1),'Name','CriticFC1', ...
            'Weights',sqrt(2/numObs)*(rand(criticLayerSizes(1),numObs)-0.5), ...
            'Bias',1e-3*ones(criticLayerSizes(1),1))
        reluLayer('Name','CriticRelu1')
        fullyConnectedLayer(criticLayerSizes(2),'Name','CriticFC2', ...
            'Weights',sqrt(2/criticLayerSizes(1))*(rand(criticLayerSizes(2),criticLayerSizes(1))-0.5), ...
            'Bias',1e-3*ones(criticLayerSizes(2),1))
        reluLayer('Name','CriticRelu2')
        fullyConnectedLayer(1,'Name','CriticOutput', ...
            'Weights',sqrt(2/criticLayerSizes(2))*(rand(1,criticLayerSizes(2))-0.5), ...
            'Bias',1e-3)];

创建评判器表示。

criticOpts = rlRepresentationOptions('LearnRate',1e-4);
critic = rlValueRepresentation(criticNetwork,observationInfo,'Observation',{'observation'},criticOpts);

使用带有六个输入和两个输出的深度神经网络创建行动器。行动器网络的输出是采取每个可能行动对的概率。每个操作对包含每个推进器的标准化操作值。环境阶跃函数对这些值进行缩放,以确定实际推力值。

actorNetwork = [featureInputLayer(numObs,'Normalization','none','Name','observation')
        fullyConnectedLayer(actorLayerSizes(1),'Name','ActorFC1', ...
            'Weights',sqrt(2/numObs)*(rand(actorLayerSizes(1),numObs)-0.5), ...
            'Bias',1e-3*ones(actorLayerSizes(1),1))
        reluLayer('Name','ActorRelu1')
        fullyConnectedLayer(actorLayerSizes(2),'Name','ActorFC2', ...
            'Weights',sqrt(2/actorLayerSizes(1))*(rand(actorLayerSizes(2),actorLayerSizes(1))-0.5), ...
            'Bias',1e-3*ones(actorLayerSizes(2),1))
        reluLayer('Name', 'ActorRelu2')
        fullyConnectedLayer(numAct,'Name','Action', ...
            'Weights',sqrt(2/actorLayerSizes(2))*(rand(numAct,actorLayerSizes(2))-0.5), ...
            'Bias',1e-3*ones(numAct,1))
        softmaxLayer('Name','actionProb')];

使用随机行动器表示创建行动器。

actorOpts = rlRepresentationOptions('LearnRate',1e-4);
actor = rlStochasticActorRepresentation(actorNetwork,observationInfo,actionInfo,...
    'Observation',{'observation'},actorOpts);

使用rlPPOAgentOptions对象指定agent超参数。

agentOpts = rlPPOAgentOptions(...
                'ExperienceHorizon',600,... 
                'ClipFactor',0.02,...
                'EntropyLossWeight',0.01,...
                'MiniBatchSize',128,...
                'NumEpoch',3,...
                'AdvantageEstimateMethod','gae',...
                'GAEFactor',0.95,...
                'SampleTime',Ts,...
                'DiscountFactor',0.997);

对于这些超参数:

1.智能体会收集经验,直到达到600个步骤或episode终止的经验范围,然后从128个经验的mini-batches中训练3个epochs。
2.为了提高训练稳定性,请使用目标函数限幅因子0.02。
3.折扣系数值为0.997会鼓励长期奖励。
4.通过使用GAE系数为0.95的广义优势估计方法,可以减少批判器输出中的差异。
5.0.01的EntropyLossWeight项可增强训练过程中的探索性。

创建PPO智能体。

agent = rlPPOAgent(actor,critic,agentOpts);

训练智能体

要训练PPO智能体,请指定以下训练选项。
1.最多运行20000 episodes,每个 episode 最多持续600个时间步。

2.当连续100个 episodes 中的平均奖励为430或更高时,停止训练。

3.对于episode中奖励为700或更高的每个episode,请保存智能体的副本。

trainOpts = rlTrainingOptions(...
    'MaxEpisodes',20000,...
    'MaxStepsPerEpisode',600,...
    'Plots','training-progress',...
    'StopTrainingCriteria','AverageReward',...
    'StopTrainingValue',430,...
    'ScoreAveragingWindowLength',100,...
    'SaveAgentCriteria',"EpisodeReward",...
    'SaveAgentValue',700);

使用Train函数对智能体进行训练。由于环境的复杂性,训练过程是计算密集型的,需要几个小时才能完成。为了在运行这个示例时节省时间,可以通过将doTraining设置为false来加载一个预先训练过的智能体。若想要重头训练,请将参数改为true。

doTraining = false;
if doTraining   
    trainingStats = train(agent,env,trainOpts);
else
    load('rocketLanderAgent.mat');
end

下面显示了一个训练的示例。由于训练过程的随机性,实际结果可能会有所不同。

仿真

绘制火箭着陆器环境以可视化仿真。

plot(env)

在环境中仿真训练后的智能体。

simOptions = rlSimulationOptions('MaxSteps',600);
simOptions.NumSimulations = 5;  % simulate the environment 5 times
experience = sim(env,agent,simOptions);