В этом примере показано, как создать пользовательский агент для собственного пользовательского алгоритма обучения с подкреплением. Это позволяет использовать следующую встроенную функциональность от Пакета Reinforcement Learning Toolbox™.
В этом примере пользовательский цикл обучения REINFORCE преобразуется в пользовательский класс агента. Дополнительные сведения о пользовательском цикле train REINFORCE см. в разделе Train политики обучения с подкреплением с использованием пользовательского цикла обучения. Дополнительные сведения о записи пользовательских классов агента см. в разделе Создание пользовательских агентов обучения с подкреплением.
Исправьте начальное значение генератора для повторяемости.
rng(0)
Создайте то же окружение обучения, которая используется в примере «Train политике обучения с подкреплением» с использованием пользовательского цикла обучения. Окружение является средой балансировки тележки с шестом с дискретным пространством действий. Создайте окружение с помощью rlPredefinedEnv
функция.
env = rlPredefinedEnv('CartPole-Discrete');
Извлеките наблюдения и спецификации действия из окружения.
obsInfo = getObservationInfo(env); actInfo = getActionInfo(env);
Получите количество наблюдений (numObs
) и действия (numAct
).
numObs = obsInfo.Dimension(1); numAct = numel(actInfo.Elements);
Для получения дополнительной информации об этом окружении см. Раздел «Загрузка предопределенных Окружений системы управления».
Политика обучения с подкреплением в этом примере является стохастической политикой дискретного действия. Он представлен глубокой нейронной сетью, которая содержит fullyConnectedLayer
, reluLayer
, и softmaxLayer
слои. Эта сеть выводит вероятности для каждого дискретного действия, учитывая текущие наблюдения. The softmaxLayer
гарантирует, что представление выводит значения вероятностей в области значений [0 1] и что все вероятности равны 1.
Создайте глубокую нейронную сеть для актёра.
actorNetwork = [featureInputLayer(numObs,'Normalization','none','Name','state') fullyConnectedLayer(24,'Name','fc1') reluLayer('Name','relu1') fullyConnectedLayer(24,'Name','fc2') reluLayer('Name','relu2') fullyConnectedLayer(2,'Name','output') softmaxLayer('Name','actionProb')];
Создайте представление актера с помощью rlStochasticActorRepresentation
объект.
actorOpts = rlRepresentationOptions('LearnRate',1e-3,'GradientThreshold',1); actor = rlStochasticActorRepresentation(actorNetwork,... obsInfo,actInfo,'Observation','state',actorOpts);
Чтобы определить своего пользовательского агента, сначала создайте класс, который является подклассом rl.agent.CustomAgent
класс. Пользовательский класс агента для этого примера задан в CustomReinforceAgent.m
.
The CustomReinforceAgent
класс имеет следующее определение класса, которое указывает имя класса агента и связанный с ним абстрактный агент.
classdef CustomReinforceAgent < rl.agent.CustomAgent
Для определения агента необходимо указать следующее:
Свойства агента
Функция конструктора
Представление критика, которое оценивает дисконтированное долгосрочное вознаграждение (если требуется для обучения)
Представление актера, которое выбирает действие на основе текущего наблюдения (если требуется для обучения)
Необходимые методы агента
Необязательные методы агента
В properties
раздел файла класса, задайте любые параметры, необходимые для создания и обучения агента.
The rl.Agent.CustomAgent
класс уже включает свойства для шага расчета агента (SampleTime
) и спецификации действий и наблюдений (ActionInfo
и ObservationInfo
, соответственно).
Пользовательский агент REINFORCE задает следующие дополнительные свойства агента.
properties % Actor representation Actor % Agent options Options % Experience buffer ObservationBuffer ActionBuffer RewardBuffer end properties (Access = private) % Training utilities Counter NumObservation NumAction end
Чтобы создать пользовательский агент, вы должны задать функцию конструктора. Функция конструктора выполняет следующие действия.
Определяет спецификации действий и наблюдений. Для получения дополнительной информации о создании этих спецификаций см. rlNumericSpec
и rlFiniteSetSpec
.
Устанавливает свойства агента.
Вызывает конструктор базового абстрактного класса.
Определяет шаг расчета (необходимую для обучения в Окружения Simulink).
Для примера, CustomREINFORCEAgent
конструктор задает пространства действий и наблюдений на основе входа представления актера.
function obj = CustomReinforceAgent(Actor,Options) %CUSTOMREINFORCEAGENT Construct custom agent % AGENT = CUSTOMREINFORCEAGENT(ACTOR,OPTIONS) creates custom % REINFORCE AGENT from rlStochasticActorRepresentation ACTOR % and structure OPTIONS. OPTIONS has fields: % - DiscountFactor % - MaxStepsPerEpisode % (required) Call the abstract class constructor. obj = obj@rl.agent.CustomAgent(); obj.ObservationInfo = Actor.ObservationInfo; obj.ActionInfo = Actor.ActionInfo; % (required for Simulink environment) Register sample time. % For MATLAB environment, use -1. obj.SampleTime = -1; % (optional) Register actor and agent options. Actor = setLoss(Actor,@lossFunction); obj.Actor = Actor; obj.Options = Options; % (optional) Cache the number of observations and actions. obj.NumObservation = prod(obj.ObservationInfo.Dimension); obj.NumAction = prod(obj.ActionInfo.Dimension); % (optional) Initialize buffer and counter. reset(obj); end
Конструктор устанавливает функцию потерь представления актера с помощью указателя на функцию lossFunction
, которая реализована как локальная функция в CustomREINFORCEAgent.m
.
function loss = lossFunction(policy,lossData) % Create the action indication matrix. batchSize = lossData.batchSize; Z = repmat(lossData.actInfo.Elements',1,batchSize); actionIndicationMatrix = lossData.actionBatch(:,:) == Z; % Resize the discounted return to the size of policy. G = actionIndicationMatrix .* lossData.discountedReturn; G = reshape(G,size(policy)); % Round any policy values less than eps to eps. policy(policy < eps) = eps; % Compute the loss. loss = -sum(G .* log(policy),'all'); end
Чтобы создать пользовательского агента обучения с подкреплением, необходимо задать следующие функции реализации.
getActionImpl
- Оцените политику агента и выберите агента во время симуляции.
getActionWithExplorationImpl
- Оценка политики и выбор действия с исследованием во время обучения.
learnImpl
- Как агент учится на текущем опыте
Чтобы вызвать эти функции в собственном коде, используйте методы wrapper из абстрактного базового класса. Например, чтобы вызвать getActionImpl
, использовать getAction
. Методы-оболочки имеют те же входные и выходные аргументы, что и методы реализации.
getActionImpl
ФункцияThe getActionImpl
функция используется для оценки политики вашего агента и выбора действия при симуляции агента с помощью sim
функция. Эта функция должна иметь следующую сигнатуру, где obj
является объектом агента, Observation
- текущее наблюдение, и Action
- выбранное действие.
function Action = getActionImpl(obj,Observation)
Для пользовательского агента REINFORCE выберите действие путем вызова getAction
функция для представления актера. Дискретная rlStochasticActorRepresentation
генерирует дискретное распределение из наблюдения и отсчитывает действие из этого распределения.
function Action = getActionImpl(obj,Observation) % Compute an action using the policy given the current % observation. Action = getAction(obj.Actor,Observation); end
getActionWithExplorationImpl
ФункцияThe getActionWithExplorationImpl
функция выбирает действие с помощью модели исследования вашего агента при обучении агента с помощью train
функция. Используя эту функцию, можно реализовать методы исследования, такие как эпсилон-жадное исследование или сложение Гауссова шума. Эта функция должна иметь следующую сигнатуру, где obj
является объектом агента, Observation
- текущее наблюдение, и Action
- выбранное действие.
function Action = getActionWithExplorationImpl(obj,Observation)
Для пользовательского агента REINFORCE выполните getActionWithExplorationImpl
функция совпадает с функцией getActionImpl
. По умолчанию стохастические актёры всегда исследуют, то есть всегда выбирают действие на основе распределения вероятностей.
function Action = getActionWithExplorationImpl(obj,Observation) % Compute an action using the exploration policy given the % current observation. % REINFORCE: Stochastic actors always explore by default % (sample from a probability distribution) Action = getAction(obj.Actor,Observation); end
learnImpl
ФункцияThe learnImpl
функция определяет, как агент учится на текущем опыте. Эта функция реализует пользовательский алгоритм обучения вашего агента, обновив параметры политики и выбрав действие с исследованием для следующего состояния. Эта функция должна иметь следующую сигнатуру, где obj
является объектом агента, Experience
является текущим опытом работы с агентами и Action
- выбранное действие.
function Action = learnImpl(obj,Experience)
Опыт агента - это массив ячеек Experience = {state,action,reward,nextstate,isdone}
. Здесь:
state
- текущее наблюдение.
action
- текущее действие. Это отличается от выходного аргумента Action
, которое является действием для следующего состояния.
reward
- текущее вознаграждение.
nextState
является следующим наблюдением.
isDone
является логическим флагом, указывающим, что эпизод тренировки завершен.
Для пользовательского агента REINFORCE реплицируйте шаги 2-7 пользовательского цикла обучения в Настройте политику обучения с подкреплением с помощью пользовательского цикла обучения. Вы опускаете шаги 1, 8 и 9, так как будете использовать встроенную train
функция для обучения вашего агента.
function Action = learnImpl(obj,Experience) % Define how the agent learns from an Experience, which is a % cell array with the following format. % Experience = {observation,action,reward,nextObservation,isDone} % Reset buffer at the beginning of the episode. if obj.Counter < 2 resetBuffer(obj); end % Extract data from experience. Obs = Experience{1}; Action = Experience{2}; Reward = Experience{3}; NextObs = Experience{4}; IsDone = Experience{5}; % Save data to buffer. obj.ObservationBuffer(:,:,obj.Counter) = Obs{1}; obj.ActionBuffer(:,:,obj.Counter) = Action{1}; obj.RewardBuffer(:,obj.Counter) = Reward; if ~IsDone % Choose an action for the next state. Action = getActionWithExplorationImpl(obj, NextObs); obj.Counter = obj.Counter + 1; else % Learn from episodic data. % Collect data from the buffer. BatchSize = min(obj.Counter,obj.Options.MaxStepsPerEpisode); ObservationBatch = obj.ObservationBuffer(:,:,1:BatchSize); ActionBatch = obj.ActionBuffer(:,:,1:BatchSize); RewardBatch = obj.RewardBuffer(:,1:BatchSize); % Compute the discounted future reward. DiscountedReturn = zeros(1,BatchSize); for t = 1:BatchSize G = 0; for k = t:BatchSize G = G + obj.Options.DiscountFactor ^ (k-t) * RewardBatch(k); end DiscountedReturn(t) = G; end % Organize data to pass to the loss function. LossData.batchSize = BatchSize; LossData.actInfo = obj.ActionInfo; LossData.actionBatch = ActionBatch; LossData.discountedReturn = DiscountedReturn; % Compute the gradient of the loss with respect to the % actor parameters. ActorGradient = gradient(obj.Actor,'loss-parameters',... {ObservationBatch},LossData); % Update the actor parameters using the computed gradients. obj.Actor = optimize(obj.Actor,ActorGradient); % Reset the counter. obj.Counter = 1; end end
Вы можете задать, как ваш агент сбрасывается в начале обучения, задав resetImpl
функция со следующей сигнатурой функции, где obj
является объектом агента.
function resetImpl(obj)
Используя эту функцию, можно настроить агента в известное или случайное условие перед обучением.
function resetImpl(obj) % (Optional) Define how the agent is reset before training/ resetBuffer(obj); obj.Counter = 1; end
Кроме того, при необходимости можно задать любые другие вспомогательные функции в классе пользовательского агента. Для примера пользовательский агент REINFORCE задает resetBuffer
функция для повторной инициализации буфера опыта в начале каждого эпизода тренировки.
function resetBuffer(obj) % Reinitialize all experience buffers. obj.ObservationBuffer = zeros(obj.NumObservation,1,obj.Options.MaxStepsPerEpisode); obj.ActionBuffer = zeros(obj.NumAction,1,obj.Options.MaxStepsPerEpisode); obj.RewardBuffer = zeros(1,obj.Options.MaxStepsPerEpisode); end
После определения пользовательского класса агента создайте его образец в рабочем пространстве MATLAB. Чтобы создать пользовательский агент REINFORCE, сначала укажите опции агента.
options.MaxStepsPerEpisode = 250; options.DiscountFactor = 0.995;
Затем, используя опции и ранее заданное представление актера, вызовите функцию пользовательского конструктора агента.
agent = CustomReinforceAgent(actor,options);
Настройте обучение для использования следующих опций.
Настройте обучение на самое большее 5000 эпизодов с каждым эпизодом, длящимся самое большее 250 шагов.
Завершите обучение после достижения максимального количества эпизодов или когда среднее вознаграждение за 100 эпизодов достигает значения 240.
Для получения дополнительной информации смотрите rlTrainingOptions
.
numEpisodes = 5000; aveWindowSize = 100; trainingTerminationValue = 240; trainOpts = rlTrainingOptions(... 'MaxEpisodes',numEpisodes,... 'MaxStepsPerEpisode',options.MaxStepsPerEpisode,... 'ScoreAveragingWindowLength',aveWindowSize,... 'StopTrainingValue',trainingTerminationValue);
Обучите агента с помощью train
функция. Обучение этого агента является интенсивным в вычислительном отношении процессом, который занимает несколько минут. Чтобы сэкономить время при запуске этого примера, загрузите предварительно обученного агента путем установки doTraining
на false
. Чтобы обучить агента самостоятельно, установите doTraining
на true
.
doTraining = false; if doTraining % Train the agent. trainStats = train(agent,env,trainOpts); else % Load pretrained agent for the example. load('CustomReinforce.mat','agent'); end
Включите окружение визуализацию, которая обновляется каждый раз, когда окружение step
вызывается функция.
plot(env)
Чтобы подтвердить производительность обученного агента, симулируйте его в среде тележки с шестом. Для получения дополнительной информации о симуляции агента смотрите rlSimulationOptions
и sim
.
simOpts = rlSimulationOptions('MaxSteps',options.MaxStepsPerEpisode);
experience = sim(env,agent,simOpts);