メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

アダプティブ クルーズ コントロール用の DDPG エージェントの学習

この例では、アダプティブ クルーズ コントロール (ACC) 用の深層決定論的方策勾配 (DDPG) エージェントの学習を Simulink® で実行する方法を説明します。DDPG エージェントの詳細については、深層決定論的方策勾配 (DDPG) エージェントを参照してください。

再現性を高めるための乱数シード発生器の固定

サンプル コードには、さまざまな段階で乱数の計算が含まれる場合があります。サンプル コード内のさまざまなセクションの先頭にある乱数ストリームを固定すると、実行するたびにセクション内の乱数シーケンスが維持されるため、結果が再現される可能性が高くなります。詳細については、Results Reproducibilityを参照してください。

シード 0 で乱数ストリームを固定し、メルセンヌ・ツイスター乱数アルゴリズムを使用します。乱数生成に使用されるシード制御の詳細については、rngを参照してください。

previousRngState = rng(0,"twister");

出力 previousRngState は、ストリームの前の状態に関する情報が格納された構造体です。例の最後で、状態を復元します。

アダプティブ クルーズ コントロールの Simulink モデル

この例では、自車と先行車両に関する単純な縦方向のダイナミクスを強化学習の環境として使用します。学習の目標は、縦方向の加速と減速を制御して、先行車両との安全な距離を維持しつつ、自車を設定速度で走行させることです。この例では、Adaptive Cruise Control System Using Model Predictive Control (Model Predictive Control Toolbox)の例と同じ車両モデルを使用します。

2 台の車両の初期位置と初期速度を指定します。

x0_lead = 50;   % initial position for lead car (m)
v0_lead = 25;   % initial velocity for lead car (m/s)
x0_ego = 10;    % initial position for ego car (m)
v0_ego = 20;    % initial velocity for ego car (m/s)

停止時の既定の間隔 (m)、時間ギャップ (s)、および運転手が設定した速度 (m/s) を指定します。

D_default = 10;
t_gap = 1.4;
v_set = 30;

車両運動の物理的な制約をシミュレートするため、加速度を [–3,2] m/s^2 の範囲に制限します。

amin_ego = -3;
amax_ego = 2;

サンプル時間 Ts とシミュレーション期間 Tf を秒単位で定義します。

Ts = 0.1;
Tf = 60;

モデルを開きます。

mdl = "rlACCMdl";
open_system(mdl)
agentblk = mdl + "/RL Agent";

このモデルでは、次のようにします。

  • エージェントから環境への加速アクション信号は、-3 ~ 2 m/s^2 とする。

  • 自車の基準速度 Vref を次のように定義する。相対距離が安全距離未満の場合、自車は先行車両の速度と運転手が設定した速度の最小値に追従する。この方法により、自車は先行車両からある程度の距離を維持する。相対距離が安全距離より大きい場合、自車は運転手が設定した速度に追従する。この例では、安全距離は自車の縦方向の速度 V の線形関数、つまり、tgap*V+Ddefault として定義される。安全距離によって、自車の基準追従速度が決まる。

  • 環境からの観測値は、速度誤差 e=Vref-Vego、その積分 e、および自車の縦方向の速度 V とする。

  • シミュレーションは、自車の縦方向の速度が 0 未満となるか、先行車両と自車の相対距離が 0 未満となったときに終了する。

  • 各タイム ステップ t で与えられる報酬 rt は次のとおりとする。

rt=-(0.1et2+ut-12)+Mt

ここで、ut-1 は前のタイム ステップからの制御入力です。速度誤差が et2<=0.25 の場合は論理値を Mt=1 とし、そうでない場合は Mt=0 とします。

環境オブジェクトの作成

モデルの強化学習環境オブジェクトを作成します。

観測値の仕様を作成します。

obsInfo = rlNumericSpec([3 1], ...
    LowerLimit=-inf*ones(3,1), ...
    UpperLimit=inf*ones(3,1));
obsInfo.Name = "observations";
obsInfo.Description = "velocity error and ego velocity";

アクションの仕様を作成します。

actInfo = rlNumericSpec([1 1], ...
    LowerLimit=-3,UpperLimit=2);
actInfo.Name = "acceleration";

環境オブジェクトを作成します。

env = rlSimulinkEnv(mdl,agentblk,obsInfo,actInfo);

先行車両の位置の初期条件を定義するため、この例の最後で定義されているリセット関数 localResetFcn を指定します。

env.ResetFcn = @localResetFcn;

既定の DDPG エージェントの作成

この例では、DDPG エージェントを作成してその学習を行います。このエージェントは以下を使用します。

  • 方策の値を推定するための Q 値関数クリティック。このクリティックは、現在の観測値とアクションを入力として取り、単一のスカラーを出力として返します (状態からのアクションが与えられた割引累積長期報酬の推定値は、現在の観測値に対応し、その後の方策に従います)。

  • 連続決定論的アクターによって学習される、連続行動空間上の決定論的方策。このアクターは、現在の観測値を入力として取り、観測値の決定論的関数であるアクションを出力として返します。

アクター関数とクリティック関数は、ニューラル ネットワーク表現を使用して近似されます。エージェント初期化オブジェクトを作成し、隠れ層のサイズを 200 としてネットワークを初期化します。

initOpts = rlAgentInitializationOptions(NumHiddenUnit=200);

rlDDPGAgentOptionsを使用し、学習のハイパーパラメーターを構成します。

  • ミニバッチ サイズとして 50 を指定します。ミニバッチが小さいほど計算効率は高くなりますが、学習にばらつきが生じる可能性があります。対照的に、バッチ サイズが大きいほど学習は安定しますが、より多くのメモリが必要になります。

  • アクターとクリティックの学習率を 3e-4 と 1e-2 として指定します。学習率が大きいと、大幅な更新が発生し、動作の逸脱につながる可能性がありますが、値が低いと、最適な点に到達するまでに多くの更新が必要になる可能性があります。

  • サンプル時間を Ts として指定します。

アクターとクリティックのオプティマイザーのオプションを指定します。

actorOptions = rlOptimizerOptions( ...
    LearnRate                 = 3e-4, ...
    GradientThreshold         = 1, ...
    L2RegularizationFactor    = 1e-4);

criticOptions = rlOptimizerOptions( ...
    LearnRate                 = 1e-2, ...
    GradientThreshold         = 1, ...
    L2RegularizationFactor    = 1e-4);

エージェント オプション オブジェクトを作成します。詳細については、rlDDPGAgentOptionsを参照してください。

agentOptions = rlDDPGAgentOptions(...
    SampleTime                = Ts,...
    MiniBatchSize             = 50,...
    ActorOptimizerOptions     = actorOptions,...
    CriticOptimizerOptions    = criticOptions,...
    ExperienceBufferLength    = 1e6);

この例の DDPG エージェントは、探索にオルンシュタイン・ウーレンベック (OU) ノイズ モデルを使用します。ノイズ モデルについては、次のようにします。

  • 平均アトラクションの値を 0.7 に指定します。平均アトラクションの値が大きいほど、ノイズの値は平均に近くなります。

  • 学習中の探索を改善するために、標準偏差値 0.4 を指定します。

  • 標準偏差の減衰率を 1e-5 に指定します。減衰により、学習の進行に応じて、探索は徐々に減少します。

agentOptions.NoiseOptions.MeanAttractionConstant     = 0.7;
agentOptions.NoiseOptions.StandardDeviation          = 0.4;
agentOptions.NoiseOptions.StandardDeviationDecayRate = 1e-5;

観測値とアクションの入力仕様、初期化オプション、およびエージェントのオプションを使用し、DDPG エージェントを作成します。エージェントを作成すると、アクター ネットワークとクリティック ネットワークの初期パラメーターがランダムな値で初期化されます。エージェントが常に同じパラメーター値で初期化されるように、乱数ストリームを固定します。

rng(0,"twister");
agent = rlDDPGAgent(obsInfo,actInfo,initOpts,agentOptions);

詳細については、rlDDPGAgentを参照してください。

エージェントの学習

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

  • 500 個のエピソードについて、エピソードの学習を実行 (各エピソードは最大 maxsteps タイム ステップ持続)。

  • [強化学習の学習モニター] ウィンドウに学習の進行状況を表示。

学習オプションの詳細については、rlTrainingOptionsを参照してください。

maxepisodes = 500;
maxsteps = ceil(Tf/Ts);
trainingOpts = rlTrainingOptions(...
    MaxEpisodes          = maxepisodes,...
    MaxStepsPerEpisode   = maxsteps,...
    Plots                = "training-progress",...
    StopTrainingCriteria = "none");

再現性のために乱数ストリームを固定します。

rng(0,"twister");

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

doTraining = false;
if doTraining    
    % Train the agent.
    trainResult = train(agent,env,trainingOpts);
else
    % Load a pretrained agent for the example.
    load("SimulinkACCDDPG.mat","agent")
end

学習の例を以下に示します。学習プロセスにはランダム性があるため、実際の結果はこれとは異なる場合があります。

エージェントのシミュレーション

再現性のために乱数ストリームを固定します。

rng(0,"twister");

学習済みのエージェントの性能を決定論的に検証するには、先行車両の初期位置を 80 (m) に設定してモデルをシミュレートします。ランダムに選択された初期位置について性能を検証するには、useRandomInitialConditionstrue に設定します。

useRandomInitialConditions = false;
if useRandomInitialConditions
    x0_lead = 80;
    sim(mdl);
else
    simOptions = rlSimulationOptions(MaxSteps=maxsteps);
    experience = sim(env,agent,simOptions);
end

エージェントのシミュレーションの詳細については、rlSimulationOptions および sim を参照してください。

これらのプロットは、先行車両の初期位置が自車の 80 (m) 先であるときの決定論的シミュレーション結果を示しています。

  • 最初の 30 秒間は、相対距離が安全距離より大きいため (中央プロット)、自車は設定速度に追従します (下部プロット)。加速して設定速度に到達するために、最初の加速度は正の値です (上部プロット)。

  • 約 8 秒後、自車は設定速度に追従できるようになり、加速度はゼロに減少します。

  • 30 秒後、相対距離が安全距離より小さくなるため (中央プロット)、自車は先行車両の速度と設定速度のうち最小値に追従します。減速して先行車両の速度に追従するために、加速度が負になります (上部プロット)。

  • シミュレーション全体を通して、自車は、相対距離が安全な距離とみなせるかどうかに応じて、先行車両の速度と設定速度のうち小さいほうに追従し (または設定速度に追従し)、加速度を調整します。

previousRngState に保存されている情報を使用して、乱数ストリームを復元します。

rng(previousRngState);

リセット関数

function in = localResetFcn(in)
% Reset the initial position of the lead car.
in = setVariable(in,"x0_lead",40+randi(60,1,1));
end

参考

関数

オブジェクト

ブロック

トピック