Сгенерируйте премиальную функцию от блока Model Verification для системы бака с водой

В этом примере показано, как автоматически сгенерировать премиальную функцию от требования к производительности, заданного в блоке верификации модели Simulink® Design Optimization™. Вы затем используете сгенерированную премиальную функцию, чтобы обучить агента обучения с подкреплением.

Введение

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

В этом примере вы преобразуете стоимость и ограничительные технические требования, заданные в блоке Check Step Response Characteristics для системы бака с водой в премиальную функцию. Вы затем используете премиальную функцию и используете ее, чтобы обучить агента управлять баком с водой.

Задайте параметры для этого примера.

% Watertank parameters
a = 2;
b = 5;
A = 20;

% Initial and final height
h0 = 1;
hf = 2;

% Simulation and sample times
Tf = 10;
Ts = 0.1;

Исходной моделью для этого примера является watertank Модель Simulink (Simulink Control Design).

Откройте модель.

open_system('rlWatertankStepInput')

Модель в этом примере была изменена для обучения с подкреплением. Цель состоит в том, чтобы управлять уровнем воды в баке с помощью агента обучения с подкреплением при удовлетворении характеристикам ответа, заданным в блоке Check Step Response Characteristics. Откройте блок, чтобы просмотреть желаемые технические требования переходного процесса.

blk = 'rlWatertankStepInput/WaterLevelStepResponse';
open_system(blk)

Figure Check Step Response Characteristics [1] - WaterLevelStepResponse contains an axes object and other objects of type uiflowcontainer, uimenu, uitoolbar. The axes object contains 9 objects of type patch, line.

Сгенерируйте премиальную функцию

Сгенерируйте премиальный код функции из технических требований в блоке WaterLevelStepResponse с помощью generateRewardFunction. Код отображен в редакторе MATLAB.

generateRewardFunction(blk)

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

  • Вес штрафа по умолчанию равняется 1. Установите вес на 10.

  • Внешний метод функции штрафа по умолчанию является шагом. Измените метод в quadratic.

После того, как вы внесете изменения, вес и технические требования штрафа должны быть следующие:

Weight = 10;
Penalty = sum(exteriorPenalty(x,Block1_xmin,Block1_xmax,'quadratic'));

В данном примере модифицированный код был сохранен в файле функции MATLAB rewardFunctionVfb.m. Отобразите сгенерированную премиальную функцию.

type rewardFunctionVfb.m
function reward = rewardFunctionVfb(x,t)
% REWARDFUNCTION generates rewards from Simulink block specifications.
%
% x : Input of watertank_stepinput_rl/WaterLevelStepResponse
% t : Simulation time (s)

% Reinforcement Learning Toolbox
% 26-Apr-2021 13:05:16

%#codegen

%% Specifications from watertank_stepinput_rl/WaterLevelStepResponse
Block1_InitialValue = 1;
Block1_FinalValue = 2;
Block1_StepTime = 0;
Block1_StepRange = Block1_FinalValue - Block1_InitialValue;
Block1_MinRise = Block1_InitialValue + Block1_StepRange * 80/100;
Block1_MaxSettling = Block1_InitialValue + Block1_StepRange * (1+2/100);
Block1_MinSettling = Block1_InitialValue + Block1_StepRange * (1-2/100);
Block1_MaxOvershoot = Block1_InitialValue + Block1_StepRange * (1+10/100);
Block1_MinUndershoot = Block1_InitialValue - Block1_StepRange * 5/100;

if t >= Block1_StepTime
    if Block1_InitialValue <= Block1_FinalValue
        Block1_UpperBoundTimes = [0,5; 5,max(5+1,t+1)];
        Block1_UpperBoundAmplitudes = [Block1_MaxOvershoot,Block1_MaxOvershoot; Block1_MaxSettling,Block1_MaxSettling];
        Block1_LowerBoundTimes = [0,2; 2,5; 5,max(5+1,t+1)];
        Block1_LowerBoundAmplitudes = [Block1_MinUndershoot,Block1_MinUndershoot; Block1_MinRise,Block1_MinRise; Block1_MinSettling,Block1_MinSettling];
    else
        Block1_UpperBoundTimes = [0,2; 2,5; 5,max(5+1,t+1)];
        Block1_UpperBoundAmplitudes = [Block1_MinUndershoot,Block1_MinUndershoot; Block1_MinRise,Block1_MinRise; Block1_MinSettling,Block1_MinSettling];
        Block1_LowerBoundTimes = [0,5; 5,max(5+1,t+1)];
        Block1_LowerBoundAmplitudes = [Block1_MaxOvershoot,Block1_MaxOvershoot; Block1_MaxSettling,Block1_MaxSettling];
    end

    Block1_xmax = zeros(1,size(Block1_UpperBoundTimes,1));
    for idx = 1:numel(Block1_xmax)
        tseg = Block1_UpperBoundTimes(idx,:);
        xseg = Block1_UpperBoundAmplitudes(idx,:);
        Block1_xmax(idx) = interp1(tseg,xseg,t,'linear',NaN);
    end
    if all(isnan(Block1_xmax))
        Block1_xmax = Inf;
    else
        Block1_xmax = max(Block1_xmax,[],'omitnan');
    end

    Block1_xmin = zeros(1,size(Block1_LowerBoundTimes,1));
    for idx = 1:numel(Block1_xmin)
        tseg = Block1_LowerBoundTimes(idx,:);
        xseg = Block1_LowerBoundAmplitudes(idx,:);
        Block1_xmin(idx) = interp1(tseg,xseg,t,'linear',NaN);
    end
    if all(isnan(Block1_xmin))
        Block1_xmin = -Inf;
    else
        Block1_xmin = max(Block1_xmin,[],'omitnan');
    end
else
    Block1_xmin = -Inf;
    Block1_xmax = Inf;
end

%% Penalty function weight (specify nonnegative)
Weight = 10;

%% Compute penalty
% Penalty is computed for violation of linear bound constraints.
%
% To compute exterior bound penalty, use the exteriorPenalty function and
% specify the penalty method as 'step' or 'quadratic'.
%
% Alternaltely, use the hyperbolicPenalty or barrierPenalty function for
% computing hyperbolic and barrier penalties.
%
% For more information, see help for these functions.
Penalty = sum(exteriorPenalty(x,Block1_xmin,Block1_xmax,'quadratic'));

%% Compute reward
reward = -Weight * Penalty;
end

Чтобы интегрировать эту премиальную функцию в модели бака с водой, откройте блок MATLAB function под Премиальной Подсистемой.

open_system('rlWatertankStepInput/Reward/Reward Function')

Добавьте функцию со следующей строкой кода и сохраните модель.

r = rewardFunctionVfb(x,t);

Блок MATLAB function теперь выполнит rewardFunctionVfb.m для вычисления вознаграждений.

В данном примере блок MATLAB function был уже изменен и сохранен.

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

Динамика окружения моделируется в Подсистеме Бака с водой. Для этой среды,

  • Наблюдения являются ссылочной высотой ref от последних 5 временных шагов и ошибки высоты err = ref H.

  • Действие является напряжением V примененный насос.

  • Шаг расчета Ts 0.1 s.

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

numObs = 6;
numAct = 1;
oinfo = rlNumericSpec([numObs 1]);
ainfo = rlNumericSpec([numAct 1]);

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

env = rlSimulinkEnv('rlWatertankStepInput','rlWatertankStepInput/RL Agent',oinfo,ainfo);

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

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

rng(100)

Агент в этом примере является Двойным Задержанным Глубоким Детерминированным Градиентом политики (TD3) агент.

Создайте два представления критика.

% Critic
cnet = [
    featureInputLayer(numObs,'Normalization','none','Name', 'State')
    fullyConnectedLayer(128, 'Name', 'fc1')
    concatenationLayer(1,2,'Name','concat')
    reluLayer('Name','relu1')
    fullyConnectedLayer(128, 'Name', 'fc3')
    reluLayer('Name','relu2')
    fullyConnectedLayer(1, 'Name', 'CriticOutput')];
actionPath = [
    featureInputLayer(numAct,'Normalization','none', 'Name', 'Action')
    fullyConnectedLayer(8, 'Name', 'fc2')];
criticNetwork = layerGraph(cnet);
criticNetwork = addLayers(criticNetwork, actionPath);
criticNetwork = connectLayers(criticNetwork,'fc2','concat/in2');
criticOptions = rlRepresentationOptions('LearnRate',1e-3,'GradientThreshold',1);
critic1 = rlQValueRepresentation(criticNetwork,oinfo,ainfo,...
    'Observation',{'State'},'Action',{'Action'},criticOptions);
critic2 = rlQValueRepresentation(criticNetwork,oinfo,ainfo,...
    'Observation',{'State'},'Action',{'Action'},criticOptions);

Создайте представление актера.

actorNetwork = [featureInputLayer(numObs,'Normalization','none','Name','State')
    fullyConnectedLayer(128, 'Name','actorFC1')
    reluLayer('Name','relu1')
    fullyConnectedLayer(128, 'Name','actorFC2')
    reluLayer('Name','relu2')
    fullyConnectedLayer(numAct,'Name','Action')
    ];
actorOptions = rlRepresentationOptions('LearnRate',1e-3,'GradientThreshold',1);
actor = rlDeterministicActorRepresentation(actorNetwork,oinfo,ainfo,...
    'Observation',{'State'},'Action',{'Action'},actorOptions);

Задайте опции агента с помощью rlTD3AgentOptions. Агент обучается от буфера опыта максимальной способности 1e6 путем случайного выбора мини-пакетов размера 256. Коэффициент дисконтирования 0.99 способствует долгосрочным вознаграждениям.

agentOpts = rlTD3AgentOptions("SampleTime",Ts, ...
    "DiscountFactor",0.99, ...
    "ExperienceBufferLength",1e6, ...
    "MiniBatchSize",256);

Модель исследования в этом агенте TD3 является Гауссовой. Шумовая модель добавляет универсальное случайное значение в действие во время обучения. Установите стандартное отклонение шума к 0.5. Стандартное отклонение затухает по курсу 1e-5 каждый шаг агента до минимального значения 0.

agentOpts.ExplorationModel.StandardDeviation = 0.5;
agentOpts.ExplorationModel.StandardDeviationDecayRate = 1e-5;
agentOpts.ExplorationModel.StandardDeviationMin = 0;

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

agent = rlTD3Agent(actor,[critic1,critic2],agentOpts);

Обучите агента

Чтобы обучить агента, сначала задайте опции обучения с помощью rlTrainingOptions. В данном примере используйте следующие опции:

  • Запустите каждое обучение самое большее 2 000 эпизодов с каждым эпизодом, длящимся в большей части ceil(Tf/Ts) временные шаги, где общее время симуляции Tf 10 s.

  • Остановите обучение, когда агент получит среднее совокупное вознаграждение, больше, чем -5 по 20 последовательные эпизоды. На данном этапе агент может отследить ссылочную высоту.

trainOpts = rlTrainingOptions(...
    'MaxEpisodes',100, ...
    'MaxStepsPerEpisode',ceil(Tf/Ts), ...
    'StopTrainingCriteria','AverageReward',...
    'StopTrainingValue',-5,...
    'ScoreAveragingWindowLength',20);

Обучите агента с помощью train функция. Обучение этот агент является в вычислительном отношении интенсивным процессом, который может занять несколько минут, чтобы завершиться. Чтобы сэкономить время при выполнении этого примера, загрузите предварительно обученного агента установкой doTraining к false. Чтобы обучить агента самостоятельно, установите doTraining к true.

doTraining = false;
if doTraining
    trainingStats = train(agent,env,trainOpts);
else
    load('rlWatertankTD3Agent.mat')
end

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

Подтвердите ответ замкнутого цикла

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

sim('rlWatertankStepInput');

Figure Check Step Response Characteristics [1] - WaterLevelStepResponse contains an axes object and other objects of type uiflowcontainer, uimenu, uitoolbar. The axes object contains 10 objects of type patch, line. This object represents WaterLevelStepResponse.

Закройте модель.

close_system('rlWatertankStepInput')