exponenta event banner

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

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

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

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

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

В этом примере настраиваемый учебный цикл ENCREGATE преобразуется в класс настраиваемого агента. Дополнительные сведения о пользовательском контуре поезда ENCREGATE см. в разделе Политика обучения для усиления поезда с использованием пользовательского контура обучения. Дополнительные сведения о написании классов настраиваемых агентов см. в разделе Создание обучающих агентов настраиваемого усиления.

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

rng(0)

Создать среду

Создайте ту же среду обучения, которая используется в примере «Политика обучения с усилением поезда с использованием пользовательского цикла обучения». Среда представляет собой среду балансировки тележек и полюсов с дискретным пространством действия. Создание среды с помощью rlPredefinedEnv функция.

env = rlPredefinedEnv('CartPole-Discrete');

Извлеките спецификации наблюдения и действий из среды.

obsInfo = getObservationInfo(env);
actInfo = getActionInfo(env);

Получить количество наблюдений (numObs) и действия (numAct).

numObs = obsInfo.Dimension(1);
numAct = numel(actInfo.Elements);

Дополнительные сведения об этой среде см. в разделе Загрузка предварительно определенных сред системы управления.

Определение политики

Политика обучения усилению в этом примере является стохастической политикой дискретного действия. Он представлен глубокой нейронной сетью, которая содержит fullyConnectedLayer, reluLayer, и softmaxLayer слои. Эта сеть выводит вероятности для каждого дискретного действия, учитывая текущие наблюдения. 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.

CustomReinforceAgent имеет следующее определение класса, которое указывает имя класса агента и связанного абстрактного агента.

classdef CustomReinforceAgent < rl.agent.CustomAgent

Для определения агента необходимо указать следующее:

  • Свойства агента

  • Функция конструктора

  • Критическое представление, которое оценивает дисконтированное долгосрочное вознаграждение (если требуется для обучения)

  • Представление актера, которое выбирает действие на основе текущего наблюдения (если требуется для обучения)

  • Требуемые методы агента

  • Необязательные методы агента

Свойства агента

В properties в разделе файла класса укажите любые параметры, необходимые для создания и обучения агента.

rl.Agent.CustomAgent класс уже включает свойства для времени выборки агента (SampleTime) и спецификации действий и наблюдений (ActionInfo и ObservationInfoсоответственно).

Пользовательский агент ENERGENCE определяет следующие дополнительные свойства агента.

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 - Как агент учится на текущем опыте

Чтобы вызвать эти функции в собственном коде, используйте методы-оболочки из абстрактного базового класса. Например, для вызова getActionImpl, использовать getAction. Методы обертки имеют те же входные и выходные аргументы, что и методы реализации.

getActionImpl Функция

getActionImpl используется для оценки политики агента и выбора действия при моделировании агента с помощью sim функция. Эта функция должна иметь следующую подпись, где obj является объектом агента, Observation является текущим наблюдением, и Action - выбранное действие.

function Action = getActionImpl(obj,Observation)

Для пользовательского агента ENCREMATE выберите действие, вызвав getAction функция для представления актера. Дискретное rlStochasticActorRepresentation генерирует дискретное распределение из наблюдения и производит выборку действия из этого распределения.

function Action = getActionImpl(obj,Observation)
    % Compute an action using the policy given the current 
    % observation.
    
    Action = getAction(obj.Actor,Observation);
end

getActionWithExplorationImpl Функция

getActionWithExplorationImpl функция выбирает действие с использованием модели исследования агента при обучении агента с помощью train функция. С помощью этой функции можно реализовать такие методы исследования, как эпсилон-жадные исследования или добавление гауссова шума. Эта функция должна иметь следующую подпись, где obj является объектом агента, Observation является текущим наблюдением, и Action - выбранное действие.

function Action = getActionWithExplorationImpl(obj,Observation)

Для пользовательского агента ENCREMATE, 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 Функция

learnImpl функция определяет, как агент извлекает уроки из текущего опыта. Эта функция реализует пользовательский алгоритм обучения агента, обновляя параметры политики и выбирая действие с исследованием для следующего состояния. Эта функция должна иметь следующую подпись, где obj является объектом агента, Experience является текущим опытом агента, и Action - выбранное действие.

function Action = learnImpl(obj,Experience)

Опыт агента - это массив ячеек Experience = {state,action,reward,nextstate,isdone}. Здесь:

  • state - текущее наблюдение.

  • action является текущим действием. Это отличается от выходного аргумента Action, которое является действием для следующего состояния.

  • reward - текущее вознаграждение.

  • nextState следующее наблюдение.

  • isDone является логическим флагом, указывающим, что тренировочный эпизод завершен.

Для настраиваемого агента ENCREGATE реплицируйте шаги 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

Кроме того, при необходимости можно определить любые другие вспомогательные функции в пользовательском классе агента. Например, пользовательский агент ENCREMATE определяет 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. Чтобы создать пользовательский агент ENCREMATE, сначала укажите параметры агента.

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

См. также

Связанные темы