Main Content

진자가 위쪽으로 똑바로 서서 균형을 유지하도록 DQN 에이전트 훈련시키기

이 예제에서는 Simulink®에서 모델링된 진자가 위쪽으로 똑바로 서서 균형을 유지하도록 DQN(심층 Q-러닝 신경망) 에이전트를 훈련시키는 방법을 보여줍니다.

DQN 에이전트에 대한 자세한 내용은 DQN(심층 Q-신경망) 에이전트 항목을 참조하십시오. MATLAB®에서 DQN 에이전트를 훈련시키는 예제는 카트-폴 시스템의 균형을 유지하도록 DQN 에이전트 훈련시키기 항목을 참조하십시오.

진자 스윙업 모델

이 예제의 강화 학습 환경은 처음에 아래쪽을 향해 매달려 있는 마찰 없는 단순 진자입니다. 훈련 목표는 최소한의 제어 노력으로 이 진자가 넘어지지 않고 똑바로 서 있게 만드는 것입니다.

모델을 엽니다.

mdl = "rlSimplePendulumModel";
open_system(mdl)

이 모델의 경우 다음이 적용됩니다.

  • 위쪽으로 똑바로 균형이 잡혀 있을 때의 진자 위치는 0라디안이고, 아래쪽으로 매달려 있을 때의 위치는 pi라디안입니다.

  • 에이전트에서 환경으로 전달되는 토크 행동 신호는 –2Nm에서 2Nm까지입니다.

  • 환경에서 관측하는 값은 진자 각의 사인, 진자 각의 코사인, 진자 각 도함수입니다.

  • 매 시간 스텝마다 제공되는 보상 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개의 가능한 토크 값(–2Nm, 0Nm 또는 2Nm) 중 하나를 진자에 적용할 수 있는 이산 행동 공간이 있습니다.

진자의 초기 조건을 아래쪽을 향해 매달려 있는 것으로 정의하려면 익명 함수 핸들을 사용하여 환경 재설정 함수를 지정하십시오. 이 재설정 함수는 모델 작업 공간 변수 theta0pi로 설정합니다.

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

환경에서 관측값 및 행동 사양 정보를 가져옵니다.

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

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

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

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

시뮬레이션 시간 Tf와 에이전트 샘플 시간 Ts를 초 단위로 지정합니다.

Ts = 0.05;
Tf = 20;

재현이 가능하도록 난수 생성기 시드값을 고정합니다.

rng(0)

DQN 에이전트 만들기

DQN 에이전트는 관측값과 행동이 주어지면 파라미터화된 Q-값 함수 크리틱을 사용하여 장기 보상을 근사합니다.

DQN 에이전트에는 이산 행동 공간이 있으므로 벡터(즉, 다중 출력) Q-값 함수 크리틱을 만들 수 있는데, 일반적으로 이 방식이 비교 가능한 단일 출력 크리틱보다 더 효율적입니다. 벡터 Q-값 함수는 환경 관측값을 벡터에 매핑한 것이며, 이 벡터의 각 요소는 에이전트가 주어진 관측값에 해당하는 상태에서 시작하여 요소 번호에 해당하는 행동을 실행하고 그 후에는 주어진 정책을 따를 때 기대되는 감가된 누적 장기 보상을 나타냅니다.

크리틱 내에서 Q-값 함수를 모델링하려면 심층 신경망을 사용하십시오. 신경망에는 (obsInfo로 지정된 대로 관측값 채널의 내용을 받는) 하나의 입력 계층과 (가능한 모든 행동에 대한 값으로 구성된 벡터를 반환하는) 하나의 출력 계층이 있어야 합니다. prod(obsInfo.Dimension)은 관측값 공간의 차원 수를 반환하는 반면(행 벡터, 열 벡터 또는 행렬로 정렬되는지에 관계없음), numel(actInfo.Elements)는 이산 행동 공간의 요소 개수를 반환합니다.

신경망을 layer 객체로 구성된 배열로 정의합니다.

criticNet = [
    featureInputLayer(prod(obsInfo.Dimension))
    fullyConnectedLayer(24)
    reluLayer
    fullyConnectedLayer(48)
    reluLayer
    fullyConnectedLayer(numel(actInfo.Elements))
    ];

dlnetwork로 변환하고 가중치 개수를 표시합니다.

criticNet = dlnetwork(criticNet);
summary(criticNet)
   Initialized: true

   Number of learnables: 1.4k

   Inputs:
      1   'input'   3 features

크리틱 신경망 구성을 확인합니다.

plot(criticNet)

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

심층 신경망 모델을 사용하는 가치 함수를 만드는 방법에 대한 자세한 내용은 Create Policies and Value Functions 항목을 참조하십시오.

criticNet과 함께 관측값 및 행동 사양을 사용하여 크리틱을 만듭니다. 자세한 내용은 rlVectorQValueFunction 항목을 참조하십시오.

critic = rlVectorQValueFunction(criticNet,obsInfo,actInfo);

rlOptimizerOptions를 사용하여 크리틱 최적화 함수에 대한 옵션을 지정합니다.

criticOpts = rlOptimizerOptions(LearnRate=0.001,GradientThreshold=1);

DQN 에이전트를 만들려면 먼저 rlDQNAgentOptions 객체를 사용하여 DQN 에이전트 옵션을 지정하십시오.

agentOptions = rlDQNAgentOptions(...
    SampleTime=Ts,...
    CriticOptimizerOptions=criticOpts,...
    ExperienceBufferLength=3000,... 
    UseDoubleDQN=false);

그런 다음, 지정된 크리틱 및 에이전트 옵션을 사용하여 DQN 에이전트를 만듭니다. 자세한 내용은 rlDQNAgent 항목을 참조하십시오.

agent = rlDQNAgent(critic,agentOptions);

에이전트 훈련시키기

에이전트를 훈련시키려면 먼저 훈련 옵션을 지정하십시오. 이 예제에서는 다음 옵션을 사용합니다.

  • 최대 1000개의 에피소드에 대해 각 훈련을 실행하며, 각 에피소드마다 최대 500개의 시간 스텝이 지속됩니다.

  • 에피소드 관리자 대화 상자에 훈련 진행 상황을 표시하고(Plots 옵션 설정) 명령줄 표시를 비활성화합니다(Verbose 옵션을 false로 설정).

  • 연속되는 5개의 에피소드에서 에이전트가 받은 평균 누적 보상이 –1100보다 클 때 훈련을 중지합니다. 이 시점에서 에이전트는 진자가 똑바로 서 있는 위치에서 최소한의 제어 노력을 사용하여 빠르게 진자의 균형을 유지할 수 있습니다.

  • 누적 보상이 –1100보다 큰 각 에피소드에 대한 에이전트의 복사본을 저장합니다.

자세한 내용은 rlTrainingOptions 항목을 참조하십시오.

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

train 함수를 사용하여 에이전트를 훈련시킵니다. 이 에이전트를 훈련시키는 것은 완료하는 데 수 분이 소요되는 계산 집약적인 절차입니다. 이 예제를 실행하는 동안 시간을 절약하려면 doTrainingfalse로 설정하여 사전 훈련된 에이전트를 불러오십시오. 에이전트를 직접 훈련시키려면 doTrainingtrue로 설정하십시오.

doTraining = false;

if doTraining
    % Train the agent.
    trainingStats = train(agent,env,trainingOptions);
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);

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

참고 항목

함수

객체

블록

관련 예제

세부 정보