Создайте среду MATLAB Используя пользовательские функции

В этом примере показано, как создать среду тележки с шестом путем предоставления пользовательских динамических функций в MATLAB®.

Используя rlFunctionEnv функция, можно создать среду обучения с подкреплением MATLAB из спецификации наблюдений, спецификации действия и пользовательского step и reset функции. Можно затем обучить агента обучения с подкреплением в этой среде. Необходимый step и reset функции уже заданы для этого примера.

Создание среды с помощью пользовательских функций полезно для сред с менее комплексной динамикой, сред без специальных требований визуализации или сред с интерфейсами к сторонним библиотекам. Для более сложных сред можно создать объект среды использование шаблонного класса. Для получения дополнительной информации смотрите, Создают Пользовательскую Среду MATLAB из Шаблона.

Для получения дополнительной информации о создании сред обучения с подкреплением смотрите, Создают Среды MATLAB для Обучения с подкреплением и Создают окружения Simulink для Обучения с подкреплением.

Среда MATLAB тележки с шестом

Среда тележки с шестом является полюсом, присоединенным к неприводимому в движение соединению на тележке, которая проходит лишенная трения дорожка. Цель обучения должна заставить маятник стоять вертикально без падения.

Для этой среды:

  • Восходящим сбалансированным положением маятника является 0 радианами и нисходящим положением зависания является pi радианы.

  • Маятник запускается вертикально с начального угла, который является между –0.5 и 0.05.

  • Сигнал действия силы от агента до среды от –10 до 10 Н.

  • Наблюдения средой являются положением тележки, скоростью тележки, углом маятника и угловой производной маятника.

  • Эпизод завершает работу, если полюс является больше чем 12 градусами вертикали, или если тележка перемещает больше чем 2,4 м от исходного положения.

  • Вознаграждение +1 предоставлено для каждого временного шага, что полюс остается вертикальным. Штраф –10 применяется, когда маятник падает.

Для получения дополнительной информации об этой модели смотрите Загрузку Предопределенные Среды Системы управления.

Спецификации наблюдений и спецификации действия

Наблюдения средой являются положением тележки, скоростью тележки, углом маятника и угловой производной маятника.

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

Среда имеет дискретное пространство действий, где агент может применить одно из двух возможных значений силы к тележке: -10 или 10 N.

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

Для получения дополнительной информации об определении действий среды и наблюдений, смотрите rlNumericSpec и rlFiniteSetSpec.

Создайте среду Используя имена функций

Чтобы задать пользовательскую среду, сначала задайте пользовательский step и reset функции. Эти функции должны быть в вашей текущей рабочей папке или на пути MATLAB.

Пользовательский reset функционируйте устанавливает состояние по умолчанию среды. Эта функция должна иметь следующую подпись.

[InitialObservation,LoggedSignals] = myResetFunction()

Передать информацию от одного шага до следующего, такого как состояние среды, LoggedSignals использования. В данном примере LoggedSignals содержит состояния среды тележки с шестом, положения и скорости тележки, угла маятника и угловой производной маятника. reset функционируйте устанавливает угол тележки на случайное значение каждый раз, когда среда сбрасывается.

В данном примере используйте пользовательскую функцию, определяемую сброса в myResetFunction.m.

type myResetFunction.m
% 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. Для простоты реализации эта функция переопределяет физические константы, такие как масса тележки, каждый раз step выполняется.

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 + PoleMass*HalfPoleLength*ThetaDot*ThetaDot*SinTheta)/SystemMass;

% Apply motion equations.
ThetaDotDot = (Gravity*SinTheta - CosTheta*temp) / ...
    (HalfPoleLength*(4.0/3.0 - PoleMass*CosTheta*CosTheta/SystemMass));
XDotDot  = temp - PoleMass*HalfPoleLength*ThetaDotDot*CosTheta/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 обоим шаг и функция отдыха, используйте следующий код.

[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);

Для получения дополнительной информации см. Анонимные функции (MATLAB).

Используя дополнительные входные параметры может создать более эффективную реализацию среды. Например, myStepFunction2.m содержит пользовательский step функция, которая берет константы среды в качестве входного параметра (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.MassPole*EnvConstants.Length*ThetaDot*ThetaDot*SinTheta)/SystemMass;

% Apply motion equations.
ThetaDotDot = (EnvConstants.Gravity*SinTheta - CosTheta*temp)...
    / (EnvConstants.Length*(4.0/3.0 - EnvConstants.MassPole*CosTheta*CosTheta/SystemMass));
XDotDot  = temp - EnvConstants.MassPole*EnvConstants.Length*ThetaDotDot*CosTheta/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;

Создайте указатель анонимной функции на пользовательский step функция, передавая envConstants как дополнительный входной параметр. Поскольку envConstants доступно в то время, когда StepHandle создается, указатель на функцию включает те значения. Значения сохраняются в указателе на функцию, даже если вы очищаете переменные.

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

Используйте тот же reset функция, задавая его как указатель на функцию, а не при помощи его имени.

ResetHandle = @myResetFunction;

Создайте среду с помощью пользовательских указателей на функцию.

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

Подтвердите пользовательские функции

Прежде чем вы обучите агента в своей среде, лучшая практика состоит в том, чтобы подтвердить поведение ваших пользовательских функций. Для этого можно инициализировать среду с помощью reset функционируйте и запустите один шаг симуляции с помощью step функция. Для воспроизводимости установите начальное значение (зерно) генератора перед валидацией.

Подтвердите среду, созданную с помощью имен функций.

rng(0);
InitialObs = reset(env)
InitialObs = 4×1

         0
         0
    0.0315
         0

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

         0
    0.1947
    0.0315
   -0.2826

Подтвердите среду, созданную с помощью указателей на функцию.

rng(0);
InitialObs2 = reset(env2)
InitialObs2 = 4×1

         0
         0
    0.0315
         0

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

         0
    0.1947
    0.0315
   -0.2826

Обе среды инициализируют и симулируют успешно, производя те же значения состояния в NextObs.

Смотрите также

Похожие темы