振子の振り上げと平衡化のための DQN エージェントの学習
この例では、Simulink® でモデル化された振子の振り上げと平衡化を行うように、深層 Q 学習ネットワーク (DQN) エージェントに学習させる方法を説明します。
DQN エージェントの詳細については、深層 Q ネットワーク (DQN) エージェントを参照してください。MATLAB® で DQN エージェントに学習させる例については、カートポール システムの平衡化のための DQN エージェントの学習を参照してください。
振子振り上げモデル
この例では、初期状態で下向きにぶら下がっている摩擦がない単純な振子を、強化学習の環境として使用します。学習の目標は、最小限の制御操作を使用して、振子が倒れず直立した状態を維持することです。
モデルを開きます。
mdl = "rlSimplePendulumModel";
open_system(mdl)
このモデルの場合、次のようにします。
振子が倒立平衡状態となっている位置を 0 ラジアンとし、鉛直下向きとなっている位置を
pi
ラジアンとする。エージェントから環境へのトルク アクション信号は、–2 ~ 2 N m とする。
環境からの観測値は、振子角度の正弦、振子角度の余弦、および振子角度の微分とする。
すべてのタイム ステップで与えられる報酬 は次のとおりとする。
ここで、以下となります。
は直立位置からの変位角。
は変位角の微分。
は前のタイム ステップからの制御量。
このモデルの詳細については、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) のいずれかを振子に適用できる、離散行動空間をもちます。
振子の初期状態を下向きにぶら下がっている状態として定義するには、無名関数ハンドルを使用して環境のリセット関数を指定します。このリセット関数は、モデル ワークスペース変数 theta0
を pi
に設定します。
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"
シミュレーション時間 Tf
とエージェントのサンプル時間 Ts
を秒単位で指定します。
Ts = 0.05; Tf = 20;
再現性をもたせるために、乱数発生器のシードを固定します。
rng(0)
DQN エージェントの作成
DQN エージェントは、パラメーター化された Q 値関数のクリティックを使用して、与えられた観測値とアクションに基づいて長期報酬を近似します。
DQN エージェントは離散行動空間をもちますが、(多出力の) ベクトル Q 値関数クリティックを作成することもできます。これは通常、同等の単出力クリティックよりも効率的です。ベクトル Q 値関数は、環境観測値からベクトルへのマッピングです。各要素は、エージェントが特定の観測値に対応する状態から開始して要素番号に対応するアクションを実行する (その後は与えられた方策に従う) ときの、割引累積長期報酬の期待値を表します。
クリティック内で Q 値関数をモデル化するには、深層ニューラル ネットワークを使用します。ネットワークには、1 つの入力層 (obsInfo
で指定された観測チャネルのコンテンツを受け取る) と 1 つの出力層 (すべての可能なアクションの値のベクトルを返す) がなければなりません。prod(obsInfo.Dimension)
は、観測空間の次元数 (行ベクトル、列ベクトル、行列のいずれによって構成されているかにかかわらず) を返し、一方 numel(actInfo.Elements)
は離散行動空間の要素数を返すことに注意してください。
ネットワークを layer オブジェクトの配列として定義します。
criticNet = [ featureInputLayer(prod(obsInfo.Dimension)) fullyConnectedLayer(256) reluLayer fullyConnectedLayer(256) reluLayer fullyConnectedLayer(numel(actInfo.Elements)) ];
dlnetwork
に変換し、重みの数を表示します。
criticNet = dlnetwork(criticNet); summary(criticNet)
Initialized: true Number of learnables: 67.5k Inputs: 1 'input' 3 features
クリティック ネットワークの構成を表示します。
plot(criticNet)
深層ニューラル ネットワーク モデルを使用する価値関数の作成の詳細については、Create Policies and Value Functionsを参照してください。
criticNet
、観測仕様、およびアクション仕様を使用してクリティックを作成します。詳細については、rlVectorQValueFunction
を参照してください。
critic = rlVectorQValueFunction(criticNet,obsInfo,actInfo);
rlOptimizerOptions
を使用して、クリティック オプティマイザーのオプションを指定します。
optimOpts = rlOptimizerOptions(LearnRate=5e-3,GradientThreshold=5);
DQN エージェントを作成するには、まずrlDQNAgentOptions
を使用して DQN エージェント オプションを指定します。
agentOptions = rlDQNAgentOptions(... SampleTime=Ts,... CriticOptimizerOptions=optimOpts,... ExperienceBufferLength=1e5,... TargetSmoothFactor=5e-3,... UseDoubleDQN=false,... MiniBatchSize=256); agentOptions.EpsilonGreedyExploration.EpsilonDecay = 5e-5; agentOptions.EpsilonGreedyExploration.EpsilonMin = 0.1;
次に、指定したクリティックとエージェントのオプションを使用して、DQN エージェントを作成します。詳細については、rlDQNAgent
を参照してください。
agent = rlDQNAgent(critic,agentOptions);
エージェントの学習
エージェントに学習させるには、まず、学習オプションを指定します。この例では、次のオプションを使用します。
最大 1000 個のエピソードについて、それぞれ学習を実行 (各エピソードは最大 500 タイム ステップ持続)。
[強化学習の学習モニター] ダイアログ ボックスに学習の進行状況を表示し (
Plots
オプションを設定)、コマンド ラインの表示を無効化 (Verbose
オプションをfalse
に設定)。決定論的方策を評価するときに、-1100 よりも大きい平均累積報酬をエージェントが受け取った時点で学習を停止。この時点で、エージェントは最小限の制御操作を使用して、振子を直立位置で素早く平衡化できるようになります。
累積報酬が -1100 よりも大きい各エピソードについてエージェントのコピーを保存。
詳細については、rlTrainingOptions
を参照してください。
trainingOptions = rlTrainingOptions(... MaxEpisodes=1000,... MaxStepsPerEpisode=500,... ScoreAveragingWindowLength=5,... Verbose=false,... Plots="training-progress",... StopTrainingCriteria="EvaluationStatistic",... StopTrainingValue=-1100,... SaveAgentCriteria="EvaluationStatistic",... SaveAgentValue=-1100);
関数 train
を使用して、エージェントに学習させます。このエージェントの学習は計算量が多いプロセスのため、完了するのに数分かかります。この例の実行時間を節約するために、doTraining
を false
に設定して事前学習済みのエージェントを読み込みます。エージェントに学習させるには、doTraining
を true
に設定します。
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,trainingOptions,Evaluator=evaluator); else % Load the pretrained agent for the example. load("SimulinkPendulumDQNMulti.mat","agent"); end
DQN エージェントのシミュレーション
学習済みエージェントの性能を検証するには、振子環境内でこれをシミュレートします。エージェントのシミュレーションの詳細については、rlSimulationOptions
および sim
を参照してください。
simOptions = rlSimulationOptions(MaxSteps=500); experience = sim(env,agent,simOptions);
参考
アプリ
関数
オブジェクト
rlDQNAgent
|rlDQNAgentOptions
|rlVectorQValueFunction
|rlTrainingOptions
|rlSimulationOptions
|rlOptimizerOptions
ブロック
関連する例
- 振子の振り上げと平衡化のための DDPG エージェントの学習
- Train DDPG Agent to Swing Up and Balance Pendulum with Bus Signal
- Create DQN Agent Using Deep Network Designer and Train Using Image Observations