MATLAB强化学习工具箱(五)使用自定义函数创建MATLAB环境

该示例说明了如何通过在MATLAB®中提供自定义动态函数来创建一个环境。

使用rlFunctionEnv功能,您可以从观察规范,动作规范,用户自定义创建MATLAB强化学习环境step和reset功能。然后,您可以在此环境中训练强化学习智能体。必要的step和reset功能已经在这个例子中所定义。

使用自定义功能创建环境对于动态性不太复杂的环境,无特殊可视化要求的环境或具有第三方库接口的环境非常有用。对于更复杂的环境,可以使用模板类创建环境对象。

Cart-Pole MATLAB 环境

车杆环境是一个附在小车上的无驱动接头上的杆,它沿着无摩擦轨道移动。训练的目标是使钟摆直立而不倒下。
在这里插入图片描述
对于这个环境:

  1. 平衡摆向上位置为 θ \theta θ弧度,向下悬挂位置为 π \pi π弧度。
  2. 钟摆开始直立,最初的角度是在-0.5和0.05之间。
  3. agent对环境的力作用信号为10 到 10 N。
  4. 从环境中观察小车位置、小车速度、摆角和摆角导数。
  5. 如果杆从垂直方向超过12度,或者球车从原来的位置移动超过2.4米,则结束。
  6. 柱子每直立一步,奖励+1。当钟摆倒下时,罚10分。

观察和行动规范

从环境中观察小车位置、小车速度、摆角和摆角导数。

ObservationInfo = rlNumericSpec([4 1]);
ObservationInfo.Name = 'CartPole States';
ObservationInfo.Description = 'x, dx, theta, dtheta';

环境有一个离散的动作空间,在这个空间中,智能体可以将两个可能的力值中的一个应用到车:-10或10N。

ActionInfo = rlFiniteSetSpec([-10 10]);
ActionInfo.Name = 'CartPole Action';

使用函数名创建环境

要定义自定义环境,首先指定自定义步骤和重置函数。这些函数必须在当前工作文件夹中或在MATLAB路径中。

自定义reset函数设置环境的默认状态。此函数必须具有以下签名。

 [InitialObservation,LoggedSignals] = myResetFunction()

此时出现
在这里插入图片描述
点击箭头,进入示例文件夹,或自行创建.m文件
在这里插入图片描述
要将信息从一个步骤传递到下一个步骤,例如环境状态,请使用LoggedSignals。对于本例,LoggedSignals包含车-杆环境的状态:小车的位置和速度、摆角和摆角导数。reset函数在每次重置环境时将cart角度设置为一个随机值。

对于本例,使用在myResetFunction.m中定义的自定义重置函数。

type myResetFunction.m

出现以下内容

function [InitialObservation, LoggedSignal] = myResetFunction()
% Reset function to place custom cart-pole environment into a random
% initial state.
% Theta (randomize)
T0 = 2 * 0.05 * rand() - 0.05;
% Thetadot
Td0 = 0;
% X
X0 = 0;
% Xdot
Xd0 = 0;
% Return initial environment state variables as logged signals.
LoggedSignal.State = [X0;Xd0;T0;Td0];
InitialObservation = LoggedSignal.State;
end

自定义step函数指定环境如何根据给定的操作推进到下一个状态。此函数必须具有以下签名。

[Observation,Reward,IsDone,LoggedSignals] = myStepFunction(Action,LoggedSignals)

为了获得新的状态,环境将动态方程应用到存储在LoggedSignals中的当前状态,这类似于给微分方程一个初始条件。新的状态存储在LoggedSignals中,并作为输出返回。

对于本例,使用在myStepFunction.m中定义的自定义步骤函数。为了简化实现,此函数重新定义了物理常量,例如cart质量,每个时间步都执行。

type myStepFunction.m

出现以下内容

function [NextObs,Reward,IsDone,LoggedSignals] = myStepFunction(Action,LoggedSignals)
% Custom step function to construct cart-pole environment for the function
% name case.
%
% This function applies the given action to the environment and evaluates
% the system dynamics for one simulation step.
% Define the environment constants.
% Acceleration due to gravity in m/s^2
Gravity = 9.8;
% Mass of the cart
CartMass = 1.0;
% Mass of the pole
PoleMass = 0.1;
% Half the length of the pole
HalfPoleLength = 0.5;
% Max force the input can apply
MaxForce = 10;
% Sample time
Ts = 0.02;
% Pole angle at which to fail the episode
AngleThreshold = 12 * pi/180;
% Cart distance at which to fail the episode
DisplacementThreshold = 2.4;
% Reward each time step the cart-pole is balanced
RewardForNotFalling = 1;
% Penalty when the cart-pole fails to balance
PenaltyForFalling = -10;
% Check if the given action is valid.
if ~ismember(Action,[-MaxForce MaxForce])
error(‘Action must be %g for going left and %g for going right.’,…
-MaxForce,MaxForce);
end
Force = Action;
% Unpack the state vector from the logged signals.
State = LoggedSignals.State;
XDot = State(2);
Theta = State(3);
ThetaDot = State(4);
% Cache to avoid recomputation.
CosTheta = cos(Theta);
SinTheta = sin(Theta);
SystemMass = CartMass + PoleMass;
temp = (Force + PoleMassHalfPoleLengthThetaDotThetaDotSinTheta)/SystemMass;
% Apply motion equations.
ThetaDotDot = (GravitySinTheta - CosThetatemp) / …
(HalfPoleLength*(4.0/3.0 - PoleMassCosThetaCosTheta/SystemMass));
XDotDot = temp - PoleMassHalfPoleLengthThetaDotDotCosTheta/SystemMass;
% Perform Euler integration.
LoggedSignals.State = State + Ts.
[XDot;XDotDot;ThetaDot;ThetaDotDot];
% Transform state to observation.
NextObs = LoggedSignals.State;
% Check terminal condition.
X = NextObs(1);
Theta = NextObs(3);
IsDone = abs(X) > DisplacementThreshold || abs(Theta) > AngleThreshold;
% Get reward.
if ~IsDone
Reward = RewardForNotFalling;
else
Reward = PenaltyForFalling;
end
end

使用定义的观察规范,操作规范和函数名称构造定制环境。

env = rlFunctionEnv(ObservationInfo,ActionInfo,'myStepFunction','myResetFunction');

要验证环境的操作,rlFunctionEnv会在创建环境后自动调用validateEnvironment。

使用功能句柄创建环境

您还可以定义具有额外输入参数的自定义函数,这些参数超过了最小要求集。例如,要将额外参数arg1和arg2传递给step和rest函数,请使用以下代码。

[InitialObservation,LoggedSignals] = myResetFunction(arg1,arg2)
[Observation,Reward,IsDone,LoggedSignals] = myStepFunction(Action,LoggedSignals,arg1,arg2)

要在rlFunctionEnv中使用这些函数,必须使用匿名函数句柄。

ResetHandle = @()myResetFunction(arg1,arg2);
StepHandle = @(Action,LoggedSignals) myStepFunction(Action,LoggedSignals,arg1,arg2);

使用其他输入参数可以创建更有效的环境实现。 例如,myStepFunction2.m包含一个自定义步骤函数,该函数将环境常量作为输入参数(envConstants)。 这样,此功能避免了在每个步骤中重新定义环境常数。

type myStepFunction2.m

显示函数内容

function [NextObs,Reward,IsDone,LoggedSignals] = myStepFunction2(Action,LoggedSignals,EnvConstants)
% Custom step function to construct cart-pole environment for the function
% handle case.
%
% This function applies the given action to the environment and evaluates
% the system dynamics for one simulation step.
% Check if the given action is valid.
if ~ismember(Action,[-EnvConstants.MaxForce EnvConstants.MaxForce])
error(‘Action must be %g for going left and %g for going right.’,…
-EnvConstants.MaxForce,EnvConstants.MaxForce);
end
Force = Action;
% Unpack the state vector from the logged signals.
State = LoggedSignals.State;
XDot = State(2);
Theta = State(3);
ThetaDot = State(4);
% Cache to avoid recomputation.
CosTheta = cos(Theta);
SinTheta = sin(Theta);
SystemMass = EnvConstants.MassCart + EnvConstants.MassPole;
temp = (Force + EnvConstants.MassPoleEnvConstants.LengthThetaDotThetaDotSinTheta)/SystemMass;
% Apply motion equations.
ThetaDotDot = (EnvConstants.GravitySinTheta - CosThetatemp)…
/ (EnvConstants.Length*(4.0/3.0 - EnvConstants.MassPoleCosThetaCosTheta/SystemMass));
XDotDot = temp - EnvConstants.MassPoleEnvConstants.LengthThetaDotDotCosTheta/SystemMass;
% Perform Euler integration.
LoggedSignals.State = State + EnvConstants.Ts.
[XDot;XDotDot;ThetaDot;ThetaDotDot];
% Transform state to observation.
NextObs = LoggedSignals.State;
% Check terminal condition.
X = NextObs(1);
Theta = NextObs(3);
IsDone = abs(X) > EnvConstants.XThreshold || abs(Theta) > EnvConstants.ThetaThresholdRadians;
% Get reward.
if ~IsDone
Reward = EnvConstants.RewardForNotFalling;
else
Reward = EnvConstants.PenaltyForFalling;
end
end

创建包含环境常量的结构。

% Acceleration due to gravity in m/s^2
envConstants.Gravity = 9.8;
% Mass of the cart
envConstants.MassCart = 1.0;
% Mass of the pole
envConstants.MassPole = 0.1;
% Half the length of the pole
envConstants.Length = 0.5;
% Max force the input can apply
envConstants.MaxForce = 10;
% Sample time
envConstants.Ts = 0.02;
% Angle at which to fail the episode
envConstants.ThetaThresholdRadians = 12 * pi/180;
% Distance at which to fail the episode
envConstants.XThreshold = 2.4;
% Reward each time step the cart-pole is balanced
envConstants.RewardForNotFalling = 1;
% Penalty when the cart-pole fails to balance
envConstants.PenaltyForFalling = -5;

为自定义步骤函数创建一个匿名函数句柄,将envConstants作为额外的输入参数传递。因为在创建StepHandle时envConstants是可用的,所以函数句柄包含了这些值。即使您清除了变量,这些值也会保存在函数句柄内。

StepHandle = @(Action,LoggedSignals) myStepFunction2(Action,LoggedSignals,envConstants);

使用相同的重置函数,将其指定为函数句柄,而不是使用其名称。

ResetHandle = @myResetFunction;

使用自定义函数句柄创建环境。

env2 = rlFunctionEnv(ObservationInfo,ActionInfo,StepHandle,ResetHandle);

验证自定义函数

在您的环境中训练智能体之前,最佳实践是验证自定义函数的行为。为此,可以使用reset函数初始化环境,并使用step函数运行一个模拟步骤。为了重现性,在验证前设置随机生成器种子。

验证使用函数名创建的环境。

rng(0);
InitialObs = reset(env)

在这里插入图片描述

[NextObs,Reward,IsDone,LoggedSignals] = step(env,10);
NextObs

在这里插入图片描述
验证使用函数句柄创建的环境。

rng(0);
InitialObs2 = reset(env2)

在这里插入图片描述

[NextObs2,Reward2,IsDone2,LoggedSignals2] = step(env2,10);
NextObs

在这里插入图片描述
这两个环境都成功地初始化和模拟,在NextObs中产生相同的状态值。

猜你喜欢

转载自blog.csdn.net/wangyifan123456zz/article/details/109472901