メインコンテンツ

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

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

この例では、Simulink® でモデル化された振子の振り上げと平衡化を行うように、深層 Q 学習ネットワーク (DQN) エージェントに学習させる方法を説明します。

DQN エージェントの詳細については、深層 Q ネットワーク (DQN) エージェントを参照してください。MATLAB® で DQN エージェントに学習させる例については、Train DQN Agent to Balance Discrete Cart-Pole Systemを参照してください。

再現性のための乱数ストリームの固定

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

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

previousRngState = rng(0,"twister");

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

振子振り上げモデル

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

モデルを開きます。

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-Discrete")
env = 
SimulinkEnvWithAgent with properties:

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

このオブジェクトは、エージェントが 3 つの可能なトルク値 (-2、0、または 2 N·m) のいずれかを振子に適用できる、離散行動空間をもちます。

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

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

環境から、観測仕様とアクション仕様の情報を取得します。

obsInfo = getObservationInfo(env)
obsInfo = 
  rlNumericSpec with properties:

     LowerLimit: -Inf
     UpperLimit: Inf
           Name: "observations"
    Description: [0×0 string]
      Dimension: [3 1]
       DataType: "double"

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

       Elements: [3×1 double]
           Name: "torque"
    Description: [0×0 string]
      Dimension: [1 1]
       DataType: "double"

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

Ts = 0.05;
Tf = 20;

DQN エージェントの作成

エージェントを作成すると、クリティック ネットワークの初期パラメーターがランダムな値で初期化されます。エージェントが常に同じパラメーター値で初期化されるように、乱数ストリームを固定します。

rng(0,"twister");

エージェント初期化オブジェクトを作成し、隠れ層のサイズを 256 としてクリティック ネットワークを初期化します。

initOpts = rlAgentInitializationOptions(NumHiddenUnit=256);

rlDQNAgentOptionsオブジェクトとrlOptimizerOptionsオブジェクトを使用して、学習用のエージェント オプションを指定します。この学習では、次のようにします。

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

  • 勾配をクリップするために、勾配しきい値 5 を使用します。勾配をクリップすると、学習の安定性が向上します。

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

  • 平滑化係数 5e-3 を使用して、4 回の学習反復ごとにターゲット クリティック ネットワークを更新します。

  • double-DQN アルゴリズムは使用しません。

optimOpts = rlOptimizerOptions(LearnRate=5e-3, GradientThreshold=5);
agentOptions = rlDQNAgentOptions( ...
    SampleTime=Ts,...
    CriticOptimizerOptions=optimOpts,...
    ExperienceBufferLength=1e5,... 
    TargetSmoothFactor=5e-3,...
    UseDoubleDQN=false,...
    MiniBatchSize=256);

学習が実行されている間、DQN エージェントは ε-greedy アルゴリズムを使用して行動空間を探索します。学習中にイプシロンの値が最小値の 0.1 に達するまで徐々に減少するように、減衰率を 5e-5 に指定します。これにより、エージェントが適切な方策をもたない場合は開始時に探索が促進され、エージェントが最適な方策を学習した場合は終了時に活用が促進されます。

agentOptions.EpsilonGreedyExploration.EpsilonDecay = 5e-5;
agentOptions.EpsilonGreedyExploration.EpsilonMin = 0.1;

観測とアクションの入力仕様、初期化オプション、およびエージェントのオプションを使用し、DQN エージェントを作成します。

agent = rlDQNAgent(obsInfo,actInfo,initOpts,agentOptions);

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

エージェントの学習

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

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

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

  • 10 回の学習エピソードごとに貪欲方策のパフォーマンスを評価。

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

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

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

% training options
trainingOptions = rlTrainingOptions(...
    MaxEpisodes=1000,...
    MaxStepsPerEpisode=500,...
    ScoreAveragingWindowLength=5,...
    Verbose=false,...
    Plots="training-progress",...
    StopTrainingCriteria="EvaluationStatistic",...
    StopTrainingValue=-1100,...
    SaveAgentCriteria="EvaluationStatistic",...
    SaveAgentValue=-1100);

% agent evaluator
evl = rlEvaluator(EvaluationFrequency=10, NumEpisodes=1);

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

rng(0,"twister");

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

doTraining = false;
if doTraining
    % Train the agent.
    trainingStats = train(agent,env,trainingOptions, ...
        Evaluator=evl);
else
    % Load the pretrained agent for the example.
    load("SimulinkPendulumDQNMulti.mat","agent");
end

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

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

rng(0,"twister");

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

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

Figure Simple Pendulum Visualizer contains an axes object. The axes object contains 2 objects of type line, rectangle.

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

rng(previousRngState);

参考

アプリ

関数

オブジェクト

ブロック

トピック