Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

Simulink 環境の作成とエージェントの学習

この例では、watertank Simulink® モデル内の PI コントローラーを、強化学習用の深層決定方策勾配 (DDPG) エージェントに変換する方法を説明します。MATLAB® で DDPG エージェントに学習させる例については、Train DDPG Agent to Control Double Integrator System (Reinforcement Learning Toolbox)を参照してください。

貯水槽モデル

この例の元のモデルは貯水槽モデルです。目的はタンク内の水位を制御することです。貯水槽モデルの詳細については、watertank Simulink モデル (Simulink Control Design)を参照してください。

元のモデルに対して次の変更を加えます。

  1. PID コントローラーを削除します。

  2. RL Agent ブロックを挿入します。

  3. 観測値ベクトル [e dteh]T を接続します。ここで、h はタンクの高さ、e=r-h、および r は基準の高さです。

  4. 報酬 reward=10(|e|<0.1)-1(|e|0.1)-100(h0||h20) を設定します。

  5. 終端信号を設定して、h0 または h20 の時点でシミュレーションが停止するようにします。

結果のモデルは rlwatertank.slx です。このモデルおよび変更内容の詳細については、Create Simulink Reinforcement Learning Environments (Reinforcement Learning Toolbox)を参照してください。

open_system('rlwatertank')

環境インターフェイスの作成

次の定義を含む環境モデルを作成します。

  • エージェントが環境を操作するのに使用するアクションと観測値の信号。詳細は、rlNumericSpec (Reinforcement Learning Toolbox)rlFiniteSetSpec (Reinforcement Learning Toolbox)を参照してください。

  • エージェントがその成功度を測定するのに使用する報酬信号。詳細については、Define Reward Signals (Reinforcement Learning Toolbox)を参照してください。

観測値の仕様 obsInfo とアクションの仕様 actInfo を定義します。

obsInfo = rlNumericSpec([3 1],...
    'LowerLimit',[-inf -inf 0  ]',...
    'UpperLimit',[ inf  inf inf]');
obsInfo.Name = 'observations';
obsInfo.Description = 'integrated error, error, and measured height';
numObservations = obsInfo.Dimension(1);

actInfo = rlNumericSpec([1 1]);
actInfo.Name = 'flow';
numActions = actInfo.Dimension(1);

環境インターフェイス オブジェクトを作成します。

env = rlSimulinkEnv('rlwatertank','rlwatertank/RL Agent',...
    obsInfo,actInfo);

モデルの基準値をランダム化するカスタム リセット関数を設定します。

env.ResetFcn = @(in)localResetFcn(in);

シミュレーション時間 Tf とエージェントのサンプル時間 Ts を秒単位で指定します。

Ts = 1.0;
Tf = 200;

再現性をもたせるために、乱数発生器のシードを固定します。

rng(0)

DDPG エージェントの作成

DDPG エージェントは、観測値とアクションが与えられると、クリティックの値関数表現を使用して長期的な報酬を概算します。クリティックを作成するには、まず、2 つの入力 (観測値およびアクション) と 1 つの出力をもつ深層ニューラル ネットワークを作成します。深層ニューラル ネットワークの値関数表現の作成の詳細については、Create Policies and Value Functions (Reinforcement Learning Toolbox)を参照してください。

statePath = [
    featureInputLayer(numObservations,'Normalization','none','Name','State')
    fullyConnectedLayer(50,'Name','CriticStateFC1')
    reluLayer('Name','CriticRelu1')
    fullyConnectedLayer(25,'Name','CriticStateFC2')];
actionPath = [
    featureInputLayer(numActions,'Normalization','none','Name','Action')
    fullyConnectedLayer(25,'Name','CriticActionFC1')];
commonPath = [
    additionLayer(2,'Name','add')
    reluLayer('Name','CriticCommonRelu')
    fullyConnectedLayer(1,'Name','CriticOutput')];

criticNetwork = layerGraph();
criticNetwork = addLayers(criticNetwork,statePath);
criticNetwork = addLayers(criticNetwork,actionPath);
criticNetwork = addLayers(criticNetwork,commonPath);
criticNetwork = connectLayers(criticNetwork,'CriticStateFC2','add/in1');
criticNetwork = connectLayers(criticNetwork,'CriticActionFC1','add/in2');

クリティック ネットワークの構成を表示します。

figure
plot(criticNetwork)

Figure contains an axes object. The axes object contains an object of type graphplot.

rlRepresentationOptions (Reinforcement Learning Toolbox) を使用して、クリティック表現のオプションを指定します。

criticOpts = rlRepresentationOptions('LearnRate',1e-03,'GradientThreshold',1);

指定した深層ニューラル ネットワークとオプションを使用して、クリティック表現を作成します。また、クリティックのアクションと観測値の仕様も指定しなければなりません。これらは環境インターフェイスから取得します。詳細については、rlQValueRepresentation (Reinforcement Learning Toolbox)を参照してください。

critic = rlQValueRepresentation(criticNetwork,obsInfo,actInfo,'Observation',{'State'},'Action',{'Action'},criticOpts);

DDPG エージェントは、観測値が与えられると、どのアクションを実行するかをアクター表現を使用して決定します。アクターを作成するには、まず、1 つの入力 (観測値) と 1 つの出力 (アクション) をもつ深層ニューラル ネットワークを作成します。

クリティックと同様の方法でアクターを作成します。詳細については、rlDeterministicActorRepresentation (Reinforcement Learning Toolbox)を参照してください。

actorNetwork = [
    featureInputLayer(numObservations,'Normalization','none','Name','State')
    fullyConnectedLayer(3, 'Name','actorFC')
    tanhLayer('Name','actorTanh')
    fullyConnectedLayer(numActions,'Name','Action')
    ];

actorOptions = rlRepresentationOptions('LearnRate',1e-04,'GradientThreshold',1);

actor = rlDeterministicActorRepresentation(actorNetwork,obsInfo,actInfo,'Observation',{'State'},'Action',{'Action'},actorOptions);

DDPG エージェントを作成するには、まず、rlDDPGAgentOptions (Reinforcement Learning Toolbox) を使用して DDPG エージェントのオプションを指定します。

agentOpts = rlDDPGAgentOptions(...
    'SampleTime',Ts,...
    'TargetSmoothFactor',1e-3,...
    'DiscountFactor',1.0, ...
    'MiniBatchSize',64, ...
    'ExperienceBufferLength',1e6); 
agentOpts.NoiseOptions.Variance = 0.3;
agentOpts.NoiseOptions.VarianceDecayRate = 1e-5;

次に、指定したアクター表現、クリティック表現、およびエージェントのオプションを使用して DDPG エージェントを作成します。詳細については、rlDDPGAgent (Reinforcement Learning Toolbox)を参照してください。

agent = rlDDPGAgent(actor,critic,agentOpts);

エージェントの学習

エージェントに学習させるには、まず、学習オプションを指定します。この例では、次のオプションを使用します。

  • 各学習を最大 5000 個のエピソードに対して実行。各エピソードを最大 ceil(Tf/Ts) (つまり 200) タイム ステップ持続するよう指定。

  • Episode Manager のダイアログ ボックスに学習の進行状況を表示 (Plots オプションを設定) し、コマンド ラインの表示を無効化 (Verbose オプションを false に設定)。

  • 連続する 20 個のエピソードについて、800 を超える平均累積報酬をエージェントが受け取ったときに学習を停止。この時点で、エージェントはタンクの水位を制御できます。

詳細については、rlTrainingOptions (Reinforcement Learning Toolbox)を参照してください。

maxepisodes = 5000;
maxsteps = ceil(Tf/Ts);
trainOpts = rlTrainingOptions(...
    'MaxEpisodes',maxepisodes, ...
    'MaxStepsPerEpisode',maxsteps, ...
    'ScoreAveragingWindowLength',20, ...
    'Verbose',false, ...
    'Plots','training-progress',...
    'StopTrainingCriteria','AverageReward',...
    'StopTrainingValue',800);

関数 train (Reinforcement Learning Toolbox) を使用して、エージェントに学習させます。学習は計算量が多いプロセスのため、完了するのに数分かかります。この例の実行時間を節約するために、doTrainingfalse に設定して事前学習済みのエージェントを読み込みます。エージェントに学習させるには、doTrainingtrue に設定します。

doTraining = false;

if doTraining
    % Train the agent.
    trainingStats = train(agent,env,trainOpts);
else
    % Load the pretrained agent for the example.
    load('WaterTankDDPG.mat','agent')
end

学習済みエージェントの検証

シミュレーションを実行し、学習済みエージェントをモデルに対して検証します。

simOpts = rlSimulationOptions('MaxSteps',maxsteps,'StopOnError','on');
experiences = sim(env,agent,simOpts);

ローカル関数

function in = localResetFcn(in)

% randomize reference signal
blk = sprintf('rlwatertank/Desired \nWater Level');
h = 3*randn + 10;
while h <= 0 || h >= 20
    h = 3*randn + 10;
end
in = setBlockParameter(in,blk,'Value',num2str(h));

% randomize initial height
h = 3*randn + 10;
while h <= 0 || h >= 20
    h = 3*randn + 10;
end
blk = 'rlwatertank/Water-Tank System/H';
in = setBlockParameter(in,blk,'InitialCondition',num2str(h));

end

参考

(Reinforcement Learning Toolbox)

関連するトピック