Main Content

振子の振り上げと平衡化のための DDPG エージェントの学習

この例では、Simulink® でモデル化された振子の振り上げと平衡化を行うように、深層決定論的方策勾配 (DDPG) エージェントに学習させる方法を説明します。

DDPG エージェントの詳細については、深層決定論的方策勾配 (DDPG) エージェントを参照してください。MATLAB® で DDPG エージェントに学習させる例については、Compare DDPG Agent to LQR Controllerを参照してください。

振子振り上げモデル

この例では、初期状態で下向きにぶら下がっている摩擦がない単純な振子を、強化学習の環境として使用します。学習の目標は、最小限の制御操作を使用して、振子が倒れず直立した状態を維持することです。

モデルを開きます。

mdl = "rlSimplePendulumModel";
open_system(mdl)

このモデルの場合、次のようにします。

  • 振子が倒立平衡状態となっている位置を 0 ラジアンとし、鉛直下向きとなっている位置を pi ラジアンとする。

  • エージェントから環境へのトルク アクション信号は、–2 ~ 2 N m とする。

  • 環境からの観測値は、振子角度の正弦、振子角度の余弦、および振子角度の微分とする。

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

rt=-(θt2+0.1θt˙2+0.001ut-12)

ここで、以下となります。

  • θt は直立位置からの変位角。

  • θt˙ は変位角の微分。

  • ut-1 は前のタイム ステップからの制御量。

このモデルの詳細については、Load Predefined Control System Environmentsを参照してください。

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

振子用の事前定義された環境インターフェイスを作成します。

env = rlPredefinedEnv("SimplePendulumModel-Continuous")
env = 
SimulinkEnvWithAgent with properties:

           Model : rlSimplePendulumModel
      AgentBlock : rlSimplePendulumModel/RL Agent
        ResetFcn : []
  UseFastRestart : on

obsInfo = getObservationInfo(env);

このインターフェイスは、エージェントが -2 ~ 2 N·m のトルク値を振子に適用できる、連続行動空間をもちます。

actInfo = getActionInfo(env)
actInfo = 
  rlNumericSpec with properties:

     LowerLimit: -2
     UpperLimit: 2
           Name: "torque"
    Description: [0x0 string]
      Dimension: [1 1]
       DataType: "double"

環境の観測値を振子角度の正弦、振子角度の余弦、および振子角度の微分に設定します。

set_param( ...
    "rlSimplePendulumModel/create observations", ...
    "ThetaObservationHandling","sincos");

振子の初期状態を下向きにぶら下がっている状態として定義するには、無名関数ハンドルを使用して環境のリセット関数を指定します。このリセット関数は、モデル ワークスペース変数 theta0pi に設定します。

env.ResetFcn = @(in)setVariable(in,"theta0",pi,"Workspace",mdl);

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

Ts = 0.05;
Tf = 20;

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

rng(0)

DDPG エージェントの作成

DDPG エージェントは、パラメーター化された Q 値関数近似器を使用して方策の価値を推定します。Q 値関数クリティックは、現在の観測値とアクションを入力として取り、単一のスカラーを出力として返します (状態からのアクションの受け取りに関する割引累積長期報酬の推定値は、現在の観測値に対応し、その後の方策に従います)。

パラメーター化された Q 値関数をクリティック内でモデル化するには、2 つの入力層 (そのうち 1 つは obsInfo で指定された観測チャネル用で、もう 1 つは actInfo で指定されたアクション チャネル用) と 1 つの出力層 (これはスカラー値を返します) をもつニューラル ネットワークを使用します。

各ネットワーク パスを layer オブジェクトの配列として定義し、各パスの入力層と出力層に名前を割り当てます。これらの名前を使用すると、パスを接続してから、ネットワークの入力層と出力層に適切な環境チャネルを明示的に関連付けることができます。

深層ニューラル ネットワークの値関数表現の作成の詳細については、Create Policies and Value Functionsを参照してください。

% Define state path.
statePath = [
    featureInputLayer( ...
        obsInfo.Dimension(1), ...
        Name="obsPathInputLayer")
    fullyConnectedLayer(400)
    reluLayer
    fullyConnectedLayer(300,Name="spOutLayer")
    ];

% Define action path.
actionPath = [
    featureInputLayer( ...
        actInfo.Dimension(1), ...
        Name="actPathInputLayer")
    fullyConnectedLayer(300, ...
        Name="apOutLayer", ...
        BiasLearnRateFactor=0)
    ];

% Define common path.
commonPath = [
    additionLayer(2,Name="add")
    reluLayer
    fullyConnectedLayer(1)
    ];

dlnetwork オブジェクトを作成し、層を追加して接続します。

criticNetwork = dlnetwork();
criticNetwork = addLayers(criticNetwork,statePath);
criticNetwork = addLayers(criticNetwork,actionPath);
criticNetwork = addLayers(criticNetwork,commonPath);
criticNetwork = connectLayers(criticNetwork,"spOutLayer","add/in1");
criticNetwork = connectLayers(criticNetwork,"apOutLayer","add/in2");

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

plot(criticNetwork)

ネットワークを初期化し、重みの数を表示します。

criticNetwork = initialize(criticNetwork);
summary(criticNetwork)
   Initialized: true

   Number of learnables: 122.8k

   Inputs:
      1   'obsPathInputLayer'   3 features
      2   'actPathInputLayer'   1 features

criticNet、環境の観測仕様とアクション仕様、および環境の観測チャネルとアクション チャネルに接続するネットワーク入力層の名前を使用して、クリティック近似器オブジェクトを作成します。詳細については、rlQValueFunctionを参照してください。

critic = rlQValueFunction(criticNetwork, ...
    obsInfo,actInfo, ...
    ObservationInputNames="obsPathInputLayer", ...
    ActionInputNames="actPathInputLayer");

DDPG エージェントは、連続行動空間において、パラメーター化された決定論的方策を使用します。この方策は、連続決定論的アクターによって学習されます。

連続決定論的アクターは、連続行動空間に関するパラメーター化された決定論的方策を実装します。このアクターは、現在の観測値を入力として取り、観測値の決定論的関数であるアクションを出力として返します。

パラメーター化された方策をアクター内でモデル化するには、1 つの入力層 (これは、obsInfo で指定された、環境観測チャネルのコンテンツを受け取ります) と 1 つの出力層 (これは、actInfo で指定された、環境アクション チャネルへのアクションを返します) をもつニューラル ネットワークを使用します。

ネットワークを layer オブジェクトの配列として定義します。双曲線正接層の出力は常に -1 ~ 1 の間であるため、スケーリング層を使用して、actInfo.UpperLimit で指定されているアクションの実際の範囲に合わせてスケールします。

actorNetwork = [
    featureInputLayer(obsInfo.Dimension(1))
    fullyConnectedLayer(400)
    reluLayer
    fullyConnectedLayer(300)
    reluLayer
    fullyConnectedLayer(1)
    tanhLayer
    scalingLayer(Scale=max(actInfo.UpperLimit))
    ];

dlnetwork に変換し、ネットワークを初期化して、重みの数を表示します。

actorNetwork = dlnetwork(actorNetwork);
actorNetwork = initialize(actorNetwork);
summary(actorNetwork)
   Initialized: true

   Number of learnables: 122.2k

   Inputs:
      1   'input'   3 features

actorNet、および観測仕様とアクション仕様を使用して、アクターを作成します。連続決定論的アクターの詳細については、rlContinuousDeterministicActorを参照してください。

actor = rlContinuousDeterministicActor(actorNetwork,obsInfo,actInfo);

rlOptimizerOptionsを使用して、クリティックとアクターのオプションを指定します。

criticOpts = rlOptimizerOptions(LearnRate=1e-03,GradientThreshold=1);
actorOpts = rlOptimizerOptions(LearnRate=1e-03,GradientThreshold=1);

rlDDPGAgentOptionsを使用して、DDPG エージェントのオプション (アクターとクリティックの学習オプションなど) を指定します。

agentOpts = rlDDPGAgentOptions(...
    SampleTime=Ts,...
    CriticOptimizerOptions=criticOpts,...
    ActorOptimizerOptions=actorOpts,...
    ExperienceBufferLength=1e5,...
    DiscountFactor=0.99,...
    MiniBatchSize=128);

ドット表記を使用してエージェントのオプションを変更することもできます。

agentOpts.NoiseOptions.StandardDeviation = 0.6;

または、最初にエージェントを作成してから、ドット表記を使用してそのオプション オブジェクトにアクセスしてオプションを変更することもできます。

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

agent = rlDDPGAgent(actor,critic,agentOpts);

エージェントの学習

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

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

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

  • 決定論的方策を評価するときに、-740 よりも大きい平均累積報酬をエージェントが受け取った時点で学習を停止。この時点で、エージェントは最小限の制御操作を使用して、振子を直立位置で素早く平衡化できるようになります。

  • 累積報酬が -740 よりも大きい各エピソードについてエージェントのコピーを保存。

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

maxepisodes = 5000;
maxsteps = ceil(Tf/Ts);
trainOpts = rlTrainingOptions(...
    MaxEpisodes=maxepisodes,...
    MaxStepsPerEpisode=maxsteps,...
    ScoreAveragingWindowLength=5,...
    Verbose=false,...
    Plots="training-progress",...
    StopTrainingCriteria="EvaluationStatistic",...
    StopTrainingValue=-740,...
    SaveAgentCriteria="EvaluationStatistic",...
    SaveAgentValue=-740);

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

doTraining = false;
if doTraining
    % Use the rlEvaluator object to measure policy performance every 10
    % episodes
    evaluator = rlEvaluator(...
        NumEpisodes=1,...
        EvaluationFrequency=10);
    % Train the agent.
    trainingStats = train(agent,env,trainOpts,Evaluator=evaluator);
else
    % Load the pretrained agent for the example.
    load("SimulinkPendulumDDPG.mat","agent")
end

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

学習済みエージェントの性能を検証するには、振子環境内でこれをシミュレートします。エージェントのシミュレーションの詳細については、rlSimulationOptions および sim を参照してください。

simOptions = rlSimulationOptions(MaxSteps=500);
experience = sim(env,agent,simOptions);

参考

アプリ

関数

オブジェクト

ブロック

ブロック

関連する例

詳細