Создайте агента для пользовательского алгоритма обучения с подкреплением

В этом примере показано, как создать пользовательский агент для собственного пользовательского алгоритма обучения с подкреплением. Это позволяет использовать следующую встроенную функциональность от Пакета Reinforcement Learning Toolbox™.

  • Доступ ко всем функциям агента, включая train и sim

  • Визуализируйте процесс обучения с помощью диспетчера эпизодов

  • Обучите агентов в среде Simulink ®

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

См. также

Похожие темы