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

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

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

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

Полюсная корзиной среда MATLAB

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

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

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

  • Маятник запускается вертикально с начального угла + радианы/-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
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 = [T0;Td0;X0;Xd0];
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;

% 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;

% 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 функция. Для воспроизводимости, набор случайный seed генератора перед валидацией.

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

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

    0.0315
         0
         0
         0

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

    0.0315
    0.1951
         0
   -0.2927

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

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

    0.0315
         0
         0
         0

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

    0.0315
    0.1951
         0
   -0.2927

В обоих случаях среда инициализирует и продвигается успешно, производя те же значения состояния в NextObs.

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

Похожие темы