Создайте окружение 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 содержит состояния окружения тележки с шестом: положение и скорость тележки, угол маятника и производную угла маятника. The reset функция устанавливает угол тележки на случайное значение каждый раз, когда окружение сбрасывается.

В данном примере используйте пользовательскую функцию сброса, заданную в 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. Для простоты реализации эта функция переопределяет физические константы, такие как масса тележки, каждый раз 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);

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

Использование дополнительных входных параметров может создать более эффективную реализацию окружения. Для примера, 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.

См. также

Похожие темы