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

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

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

В этом примере политика стохастического актёра с дискретным пространством действий обучается с помощью алгоритма REINFORCE (без базовой линии). Дополнительные сведения об алгоритме REINFORCE см. в разделе Агенты градиента политики.

Исправьте начальное значение генератора для повторяемости.

rng(0)

Дополнительные сведения о функциях, которые можно использовать для пользовательского обучения, см. в разделе Функции для пользовательского обучения.

Окружение

В данном примере политика обучения с подкреплением обучается в дискретном окружении тележки с шестом. Цель в этом окружении состоит в том, чтобы сбалансировать полюс, прикладывая силы (действия) к тележке. Создайте окружение с помощью rlPredefinedEnv функция.

env = rlPredefinedEnv('CartPole-Discrete');

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

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

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

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

Для получения дополнительной информации об этом окружении см. Раздел «Загрузка предопределенных Окружений системы управления».

Политика

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

В данном примере функция потерь для политики реализована в actorLossFunction.

Установите функцию потерь с помощью setLoss функция.

actor = setLoss(actor,@actorLossFunction);

Setup обучения

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

  • Настройте обучение на самое большее 5000 эпизодов с каждым эпизодом, длящимся самое большее 250 шагов.

  • Чтобы вычислить дисконтированное вознаграждение, выберите коэффициент дисконтирования 0,995.

  • Завершите обучение после достижения максимального количества эпизодов или когда среднее вознаграждение за 100 эпизодов достигает значения 220.

numEpisodes = 5000;
maxStepsPerEpisode = 250;
discountFactor = 0.995;
aveWindowSize = 100;
trainingTerminationValue = 220;

Создайте вектор для хранения совокупного вознаграждения для каждого эпизода тренировки.

episodeCumulativeRewardVector = [];

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

[trainingPlot,lineReward,lineAveReward] = hBuildFigure;

Пользовательский цикл обучения

Алгоритм пользовательского цикла обучения следующий. Для каждого эпизода:

  1. Сбросьте окружение.

  2. Создайте буферы для хранения информации об опыте: наблюдения, действия и вознаграждения.

  3. Сгенерируйте опыт до тех пор, пока не произойдет терминальное условие. Для этого оцените политику, чтобы получить действия, применить эти действия к окружению и получить полученные наблюдения и вознаграждения. Сохраните действия, наблюдения и вознаграждения в буферах.

  4. Собирайте обучающие данные как пакет опыта.

  5. Вычислите эпизод возврата Монте-Карло, который является дисконтированным будущим вознаграждением.

  6. Вычислите градиент функции потерь относительно параметров представления политики.

  7. Обновите представление актера с помощью вычисленных градиентов.

  8. Обновите обучающую визуализацию.

  9. Прекращает обучение, если политика достаточно обучена.

% Enable the training visualization plot.
set(trainingPlot,'Visible','on');

% Train the policy for the maximum number of episodes or until the average
% reward indicates that the policy is sufficiently trained.
for episodeCt = 1:numEpisodes
    
    % 1. Reset the environment at the start of the episode
    obs = reset(env);
    
    episodeReward = zeros(maxStepsPerEpisode,1);
    
    % 2. Create buffers to store experiences. The dimensions for each buffer
    % must be as follows.
    %
    % For observation buffer: 
    %     numberOfObservations x numberOfObservationChannels x batchSize
    %
    % For action buffer: 
    %     numberOfActions x numberOfActionChannels x batchSize
    %
    % For reward buffer: 
    %     1 x batchSize
    %
    observationBuffer = zeros(numObs,1,maxStepsPerEpisode);
    actionBuffer = zeros(numAct,1,maxStepsPerEpisode);
    rewardBuffer = zeros(1,maxStepsPerEpisode);
    
    % 3. Generate experiences for the maximum number of steps per
    % episode or until a terminal condition is reached.
    for stepCt = 1:maxStepsPerEpisode
        
        % Compute an action using the policy based on the current 
        % observation.
        action = getAction(actor,{obs});
        
        % Apply the action to the environment and obtain the resulting
        % observation and reward.
        [nextObs,reward,isdone] = step(env,action{1});
        
        % Store the action, observation, and reward experiences in buffers.
        observationBuffer(:,:,stepCt) = obs;
        actionBuffer(:,:,stepCt) = action{1};
        rewardBuffer(:,stepCt) = reward;
        
        episodeReward(stepCt) = reward;
        obs = nextObs;
        
        % Stop if a terminal condition is reached.
        if isdone
            break;
        end
        
    end
    
    % 4. Create training data. Training is performed using batch data. The
    % batch size equal to the length of the episode.
    batchSize = min(stepCt,maxStepsPerEpisode);
    observationBatch = observationBuffer(:,:,1:batchSize);
    actionBatch = actionBuffer(:,:,1:batchSize);
    rewardBatch = rewardBuffer(:,1:batchSize);

    % Compute the discounted future reward.
    discountedReturn = zeros(1,batchSize);
    for t = 1:batchSize
        G = 0;
        for k = t:batchSize
            G = G + discountFactor ^ (k-t) * rewardBatch(k);
        end
        discountedReturn(t) = G;
    end

    % 5. Organize data to pass to the loss function.
    lossData.batchSize = batchSize;
    lossData.actInfo = actInfo;
    lossData.actionBatch = actionBatch;
    lossData.discountedReturn = discountedReturn;
    
    % 6. Compute the gradient of the loss with respect to the policy
    % parameters.
    actorGradient = gradient(actor,'loss-parameters',...
        {observationBatch},lossData);
    
    % 7. Update the actor network using the computed gradients.
    actor = optimize(actor,actorGradient);

    % 8. Update the training visualization.
    episodeCumulativeReward = sum(episodeReward);
    episodeCumulativeRewardVector = cat(2,...
        episodeCumulativeRewardVector,episodeCumulativeReward);
    movingAveReward = movmean(episodeCumulativeRewardVector,...
        aveWindowSize,2);
    addpoints(lineReward,episodeCt,episodeCumulativeReward);
    addpoints(lineAveReward,episodeCt,movingAveReward(end));
    drawnow;
    
    % 9. Terminate training if the network is sufficiently trained.
    if max(movingAveReward) > trainingTerminationValue
        break
    end
    
end

Figure Cart Pole Custom Training contains an axes. The axes with title Training Progress contains 2 objects of type animatedline. These objects represent Cumulative Reward, Average Reward.

Симуляция

После обучения моделируйте обученную политику.

Перед симуляцией сбросьте окружение.

obs = reset(env);

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

plot(env)

Для каждого шага симуляции выполните следующие действия.

  1. Получите действие путем выборки из политики с помощью getAction функция.

  2. Постройте окружение с помощью полученного значения действия.

  3. Завершает работу при достижении терминального условия.

for stepCt = 1:maxStepsPerEpisode
    
    % Select action according to trained policy
    action = getAction(actor,{obs});
        
    % Step the environment
    [nextObs,reward,isdone] = step(env,action{1});
    
    % Check for terminal condition
    if isdone
        break
    end
    
    obs = nextObs;
    
end

Figure Cart Pole Visualizer contains an axes. The axes contains 6 objects of type line, polygon.

Функции для пользовательского обучения

Чтобы получить действия и функции ценности для заданных наблюдений из политики Reinforcement Learning Toolbox и представлений функции ценности, можно использовать следующие функции.

  • getValue - Получите расчетное значение состояния или функцию ценности состояния активности.

  • getAction - Получите действие из представления актера на основе текущего наблюдения.

  • getMaxQValue - Получите предполагаемую функцию максимального значения состояния активности для дискретного представления Q-значения.

Если представление вашей политики или функции ценности является рекуррентной нейронной сетью, то есть нейронной сетью с по крайней мере одним слоем, который имеет скрытую информацию о состоянии, предыдущие функции могут вернуть текущее состояние сети. Можно использовать следующие синтаксисы функций, чтобы получить и задать состояние своего представления.

  • state = getState(rep) - Получите состояние представления rep.

  • newRep = setState(oldRep,state) - Установите состояние представления oldRep, и возвращает результат в oldRep.

  • newRep = resetState(oldRep) - Сбросьте все значения состояний oldRep для нуля и возврата результата в newRep.

Получить и задать настраиваемые параметры представления можно с помощью getLearnableParameters и setLearnableParameters функция, соответственно.

В дополнение к этим функциям можно использовать setLoss, gradient, optimize, и syncParameters функции для задания параметров и вычисления градиентов для представлений политики и функции ценности.

setLoss

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

newRep = setLoss(oldRep,lossFcn)

Здесь:

  • oldRep является объектом представления политики или функции ценности.

  • lossFcn - имя пользовательской функции потерь или указателя на пользовательскую функцию потерь.

  • newRep эквивалентно oldRep, за исключением того, что функция потерь была добавлена к представлению.

gradient

The gradient функция вычисляет градиенты функции потерь представления. Можно вычислить несколько различных градиентов. Для примера, чтобы вычислить градиент выходов представления относительны его входы, используйте следующий синтаксис.

grad = gradient(rep,"output-input",inputData)

Здесь:

  • rep является объектом представления политики или функции ценности.

  • inputData содержит значения для каналов входа в представление.

  • grad содержит вычисленные градиенты.

Для получения дополнительной информации в командной строке MATLAB введите help rl.representation.rlAbstractRepresentation.gradient.

optimize

The optimize функция обновляет настраиваемые параметры представления на основе вычисленных градиентов. Чтобы обновить параметры градиентов, используйте следующий синтаксис.

newRep = optimize(oldRep,grad)

Здесь, oldRep является объектом представления политики или функции ценности и grad содержит градиенты, вычисленные с помощью gradient функция. newRep имеет ту же структуру, что и oldRep, но его параметры обновляются.

syncParameters

The syncParameters функция обновляет настраиваемые параметры одной политики или представления функции ценности на основе параметров другого представления. Эта функция полезна для обновления представления целевого актёра или критика, как это делается для агентов DDPG. Чтобы синхронизировать значения параметров между двумя представлениями, используйте следующий синтаксис.

newTargetRep = syncParameters(oldTargetRep,sourceRep,smoothFactor)

Здесь:

  • oldTargetRep является объектом представления политики или функции ценности с параметрами θold.

  • sourceRep является объектом представления политики или функции ценности с той же структурой, что и oldTargetRep, но с параметрами θsource.

  • smoothFactor - коэффициент сглаживания (τ) для обновления.

  • newTargetRep имеет ту же структуру, что и oldRep, но его параметры θnew=τθsource+(1-τ)θold.

Функция потерь

Функция потерь в алгоритме REINFORCE является продуктом дисконтированного вознаграждения и журнала политики, суммированных по всем временным шагам. Дисконтированное вознаграждение, рассчитанное в пользовательском цикле обучения, должно быть изменено в размере, чтобы сделать его совместимым для умножения с политикой.

function loss = actorLossFunction(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

Функция помощника

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

function [trainingPlot, lineReward, lineAveReward] = hBuildFigure()
    plotRatio = 16/9;
    trainingPlot = figure(...
                'Visible','off',...
                'HandleVisibility','off', ...
                'NumberTitle','off',...
                'Name','Cart Pole Custom Training');
    trainingPlot.Position(3) = plotRatio * trainingPlot.Position(4);
    
    ax = gca(trainingPlot);
    
    lineReward = animatedline(ax);
    lineAveReward = animatedline(ax,'Color','r','LineWidth',3);
    xlabel(ax,'Episode');
    ylabel(ax,'Reward');
    legend(ax,'Cumulative Reward','Average Reward','Location','northwest')
    title(ax,'Training Progress');
end

См. также

Похожие темы