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

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

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

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

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

В этом примере вы преобразуете пользовательский цикл обучения REINFORCE в пользовательский класс агента. Для получения дополнительной информации о пользовательском REINFORCE обучают цикл, видят, Обучают политику Обучения с подкреплением Используя Пользовательский Учебный Цикл. Для получения дополнительной информации о записи пользовательских классов агента смотрите, Создают Пользовательских Агентов Обучения с подкреплением.

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

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, соответственно).

Пользовательский агент 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)

    policy = policy{1};
    % 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)

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

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 Функция

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,@lossFunction,...
            {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);

Обучите пользовательского агента

Сконфигурируйте обучение использовать следующие опции.

  • Настройте обучение продлиться самое большее 5 000 эпизодов с каждым эпизодом, длящимся самое большее 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);

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

Похожие темы