В этом примере показано, как создать полюсную корзиной среду путем предоставления пользовательских динамических функций в MATLAB®.
Используя rlFunctionEnv
функция, можно создать среду обучения с подкреплением MATLAB из спецификации наблюдения, спецификации действия и пользовательского step
и reset
функции. Можно затем обучить агента обучения с подкреплением в этой среде. Необходимый step
и reset
функции уже заданы для этого примера.
Для получения дополнительной информации о создании сред обучения с подкреплением видят, Создают Среды MATLAB для Обучения с подкреплением и Создают окружения Simulink для Обучения с подкреплением.
Полюсная корзиной среда является полюсом, присоединенным к неприводимому в движение соединению на корзине, которая проходит лишенная трения дорожка. Учебная цель состоит в том, чтобы заставить маятник стоять вертикально без падения.
Для этой среды:
Восходящим сбалансированным положением маятника является 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
.