주요 콘텐츠

DDPG 에이전트를 사용한 사족 보행 로봇 운동

이 예제에서는 DDPG(심층 결정적 정책 경사) 에이전트를 사용하여 4족 보행 로봇이 걷도록 훈련시키는 방법을 보여줍니다. 이 예제의 로봇은 Simscape™ Multibody™를 사용하여 모델링됩니다. DDPG 에이전트에 대한 자세한 내용은 DDPG(심층 결정적 정책 경사) 에이전트 항목을 참조하십시오.

재현이 가능하도록 난수 스트림 고정하기

예제 코드의 다양한 단계에서 난수 계산이 포함될 수 있습니다. 예제 코드에 있는 다양한 섹션의 시작 부분에서 난수 스트림을 고정하면 매 실행 시에 섹션의 난수열이 유지되며 결과를 재현할 가능성이 높아집니다. 자세한 내용은 결과 재현성 항목을 참조하십시오.

시드값 0과 난수 알고리즘인 메르센 트위스터를 사용하여 난수 스트림을 고정합니다. 난수 생성에 사용되는 시드값을 제어하는 방법에 대한 자세한 내용은 rng 항목을 참조하십시오.

previousRngState = rng(0,"twister");

출력값 previousRngState는 스트림의 이전 상태에 대한 정보를 포함하는 구조체입니다. 이 예제의 끝부분에서 그 상태를 복원할 것입니다.

이 예제에 제공된 스크립트 initializeRobotParameters를 사용하여, 필요한 파라미터를 MATLAB®의 기본 작업 공간으로 불러옵니다.

initializeRobotParameters;

4족 보행 로봇 모델

이 예제에 대한 환경은 4족 보행 로봇이며, 훈련 목표는 최소한의 제어 노력으로 이 로봇이 직선 보행하도록 만드는 것입니다.

모델을 엽니다.

mdl = "rlQuadrupedRobot";
open_system(mdl)

이 로봇은 Simscape™ Multibody™를 사용하여 모델링되었으며, 주요 구조적 컴포넌트는 네 개의 다리와 몸통으로 이루어져 있습니다. 다리는 몸통을 기준으로 다리를 회전할 수 있게 해주는 회전 조인트를 통해 몸통에 연결됩니다. 조인트는 RL Agent에서 제공되는 토크 신호로 작동됩니다.

관측값

이 로봇 환경은 각각 –1과 1 사이에서 정규화된 44개의 관측값을 에이전트에 제공합니다. 관측값은 다음과 같습니다.

  • 몸통 무게 중심의 Y(종방향) 및 Y(횡방향) 위치

  • 몸통의 방향을 나타내는 쿼터니언

  • 무게 중심에서 몸통의 X(진행방향), Y(종방향), Z(횡방향) 속도

  • 몸통의 롤, 피치, 요 각속도

  • 각 다리에 대한 힙 조인트 및 무릎 조인트의 각위치와 각속도

  • 각 다리의 지면 접촉으로 인한 수직항력과 마찰력

  • 이전 시간 스텝의 행동 값(각 조인트의 토크)

네 다리 전부에 대해, 힙 조인트 각도와 무릎 조인트 각도의 초기값은 각각 –0.8234라디안과 1.6468라디안으로 설정됩니다. 조인트의 중립 위치는 0라디안으로 설정됩니다. 다리가 최대로 펴지고 지면과 수직으로 정렬되면 중립 위치에 있는 것입니다.

행동

에이전트는 –1과 1 사이에서 정규화된 8가지 행동을 생성합니다. 스케일링 인자를 곱하면 이러한 행동은 회전 조인트에 대한 8가지 조인트 토크 신호가 됩니다. 전체 조인트 토크 범위는 각 조인트에 대해 +/– 10Nm입니다.

보상

훈련 중 각 시간 스텝에서 다음 보상이 에이전트에 제공됩니다. 이 보상 함수는 양의 진행방향 속도에 대해 양의 보상을 제공하여 에이전트가 앞으로 이동하도록 합니다. 또한 각 시간 스텝에서 일정한 보상(25Ts/Tf25 Ts/Tf)을 제공함으로써 에이전트가 조기 종료되지 않도록 합니다. 보상 함수의 나머지 항은 원하는 높이 및 방향에서의 큰 편차 또는 과도한 조인트 토크 사용과 같이 원치 않는 상태를 억제하는 벌점입니다.

rt=vx+25TsTf-50yˆ2-20θ2-0.02iut-1i2r(t) = vx(t) + 25 * Ts/Tf - - 50 * ĥ(t)^2 - 20 * θ(t)2 - 0.02 * Σ u(t-1)^2

여기서

  • vxvx(t)는 x 방향으로의 몸통 무게 중심의 속도입니다.

  • TsTsTfTf는 각각 환경의 샘플 시간 및 최종 시뮬레이션 시간입니다.

  • yˆ는 원하는 높이 0.75m에서의 몸통 무게 중심의 높이 오차인데 스케일링된 값입니다.

  • θ는 몸통의 피치 각도입니다.

  • ut-1iu(t-1)은 이전 시간 스텝에서 조인트 i에 대한 행동 값입니다.

에피소드 종료

훈련 또는 시뮬레이션 중에 다음 상황 중 하나라도 발생하면 에피소드가 종료됩니다.

  • 지면에서 몸통 무게 중심의 높이가 0.5m 미만입니다(넘어짐).

  • 몸통의 머리나 꼬리가 지면 아래에 있습니다.

  • 모든 무릎 조인트가 지면 아래에 있습니다.

  • 롤, 피치 또는 요 각도가 범위를 벗어납니다(각각 +/– 0.1745라디안, +/– 0.1745라디안, +/– 0.3491라디안).

환경 객체 만들기

관측값 세트에 대한 파라미터를 지정합니다.

numObs = 44;
obsInfo = rlNumericSpec([numObs 1]);
obsInfo.Name = "observations";

행동 세트에 대한 파라미터를 지정합니다.

numAct = 8;
actInfo = rlNumericSpec([numAct 1],LowerLimit=-1,UpperLimit=1);
actInfo.Name = "torque";

강화 학습 모델을 사용하여 환경을 만듭니다.

blk = mdl + "/RL Agent";
env = rlSimulinkEnv(mdl,blk,obsInfo,actInfo);

훈련 중에, 이 예제의 마지막에 나오는 함수 quadrupedResetFcn을 실행하면 초기 조인트 각도와 각속도에 무작위 편차가 발생합니다.

env.ResetFcn = @quadrupedResetFcn;

DDPG Agent 객체 만들기

DDPG 에이전트는 파라미터화된 Q-값 함수 근사기를 크리틱으로 사용하여 정책의 값을 추정합니다. 또한 연속 행동 공간에 대해 연속 결정적 액터가 학습한 파라미터화된 결정적 정책을 사용합니다.

심층 신경망 가치 함수를 만드는 방법에 대한 자세한 내용은 Create Policies and Value Functions 항목을 참조하십시오. DDPG 에이전트의 신경망을 생성하는 예제는 Compare DDPG Agent to LQR Controller 항목을 참조하십시오.

에이전트 훈련을 위해 먼저 다음 옵션을 지정하십시오. 자세한 내용은 rlDDPGAgentOptions 항목을 참조하십시오.

  • 다양한 경험을 저장하기 위해 경험 버퍼의 용량을 1e6으로 지정합니다.

  • 매 학습 반복 시 최대 200번의 기울기 스텝 업데이트를 수행하도록 MaxMiniBatchPerEpoch 값을 지정합니다.

  • 학습에 대한 미니 배치 크기를 256으로 지정합니다. 미니 배치 크기가 이보다 작으면 계산이 효율적이지만 훈련 시 변동성이 생길 수 있습니다. 반대로 미니 배치 크기가 이보다 크면 훈련이 안정되지만 메모리가 더 많이 필요할 수 있습니다.

  • 에이전트의 액터 및 크리틱 최적화 함수 알고리즘에 대한 학습률을 1e-3으로 지정합니다. 학습률이 높으면 대대적인 업데이트가 야기되어 발산이 발생할 수 있으며, 값이 낮으면 최적점에 도달하기까지 많은 업데이트가 필요할 수 있습니다.

  • 학습 알고리즘의 안정성을 강화하기 위해, 계산되는 기울기를 자르기 위한 기울기 임계값을 1.0으로 지정합니다.

  • 에이전트의 행동 공간 탐색을 향상시키기 위해 표준편차를 0.1로, 평균 유인 계수를 1.0으로 지정합니다.

  • 샘플 시간 Ts를 0.025s로 지정합니다.

% create the agent options object
agentOptions = rlDDPGAgentOptions();

% specify the options
agentOptions.SampleTime = Ts;
agentOptions.MiniBatchSize = 256;
agentOptions.ExperienceBufferLength = 1e6;
agentOptions.MaxMiniBatchPerEpoch = 200;

% optimizer options
agentOptions.ActorOptimizerOptions.LearnRate = 1e-3;
agentOptions.ActorOptimizerOptions.GradientThreshold = 1;
agentOptions.CriticOptimizerOptions.LearnRate = 1e-3;
agentOptions.CriticOptimizerOptions.GradientThreshold = 1;

% exploration options
agentOptions.NoiseOptions.StandardDeviation = 0.1;
agentOptions.NoiseOptions.MeanAttractionConstant = 1.0; 

에이전트를 생성하면 액터 신경망과 크리틱 신경망의 초기 파라미터가 난수 값으로 초기화됩니다. 에이전트가 항상 동일한 파라미터 값으로 초기화되도록 난수 스트림을 고정합니다.

rng(0,"twister");

계층당 256개의 은닉 유닛이 있는 에이전트에 대한 rlDDPGAgent 객체를 만듭니다.

initOpts = rlAgentInitializationOptions(NumHiddenUnit=256);
agent = rlDDPGAgent(obsInfo,actInfo,initOpts,agentOptions);

훈련 옵션 지정하기

에이전트를 훈련시키려면 먼저 다음 훈련 옵션을 지정하십시오.

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

  • 강화 학습 훈련 모니터 대화 상자에 훈련 진행 상황을 표시합니다(Plots 옵션 설정).

  • 그리디 정책 평가가 300을 초과하면 훈련을 중지합니다.

trainOpts = rlTrainingOptions(...
    MaxEpisodes=10000,...
    MaxStepsPerEpisode=floor(Tf/Ts),...
    ScoreAveragingWindowLength=250,...
    Plots="training-progress",...
    StopTrainingCriteria="EvaluationStatistic",...
    StopTrainingValue=300);

에이전트를 병렬로 훈련시키려면 다음 훈련 옵션을 지정하십시오. 병렬로 훈련시키려면 Parallel Computing Toolbox™가 필요합니다. Parallel Computing Toolbox™가 설치되어 있지 않으면 UseParallelfalse로 설정하십시오.

  • UseParallel 옵션을 true로 설정합니다.

  • 비동기 병렬 워커를 사용하여 에이전트를 훈련시킵니다.

trainOpts.UseParallel = true;
trainOpts.ParallelizationOptions.Mode = "async";

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

병렬 훈련에서 워커는 에이전트의 정책을 환경에서 시뮬레이션하고 재생 메모리에 경험을 저장합니다. 워커가 비동기식으로 동작하는 경우 저장되는 경험의 순서가 결정적(deterministic)이지 않을 수 있으며 결국 훈련 결과가 다를 수 있습니다. 재현 가능성을 최대화하려면 다음을 수행하십시오.

  • 매 코드 실행 시 동일한 개수의 병렬 워커를 사용하여 병렬 풀을 초기화하십시오. 풀 크기 지정에 대한 자세한 내용은 클러스터 검색 및 클러스터 프로파일 사용하기 (Parallel Computing Toolbox) 항목을 참조하십시오.

  • trainOpts.ParallelizationOptions.Mode"sync"로 설정하여 동기식 병렬 훈련을 사용하십시오.

  • trainOpts.ParallelizationOptions.WorkerRandomSeeds를 사용하여 난수 시드값을 각 병렬 워커에 할당하십시오. 디폴트 값 -1을 사용하면 각 병렬 워커에 고유한 난수 시드값이 할당됩니다.

에이전트 훈련시키기

재현이 가능하도록 난수 스트림을 고정합니다.

rng(0,"twister");

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

doTraining = false;
if doTraining    
    % Evaluate the greedy policy performance by taking the cumulative
    % reward mean over 5 simulations every 25 training episodes.
    evaluator = rlEvaluator(NumEpisodes=5, EvaluationFrequency=25);
    % Train the agent.
    result = train(agent, env, trainOpts, Evaluator=evaluator);
else
    % Load pretrained agent parameters for the example.
    load("rlQuadrupedAgentParams.mat","params")
    setLearnableParameters(agent, params);
end

훈련된 에이전트 시뮬레이션하기

재현이 가능하도록 난수 스트림을 고정합니다.

rng(0,"twister");

훈련된 에이전트의 성능을 검증하려면 로봇 환경 내에서 에이전트를 시뮬레이션하십시오. 에이전트 시뮬레이션에 대한 자세한 내용은 rlSimulationOptions 항목과 sim 항목을 참조하십시오.

simOptions = rlSimulationOptions(MaxSteps=floor(Tf/Ts));
experience = sim(env,agent,simOptions);

previousRngState에 저장된 정보를 사용하여 난수 스트림을 복원합니다.

rng(previousRngState);

재설정 함수

function in = quadrupedResetFcn(in)
% Randomize initial conditions.

l1 = evalin('base','l1');
l2 = evalin('base','l2');

max_foot_disp_x = 0.1;
min_body_height = 0.7;
max_body_height = 0.8;
max_speed_x = 0.05;
max_speed_y = 0.025;

if rand < 0.5
    % Start from random initial conditions

    % Randomize height
    b = min_body_height + (max_body_height - min_body_height) * rand;

    % Randomize x-displacement of foot from hip joint
    a = -max_foot_disp_x + 2 * max_foot_disp_x * rand(1,4);

    % Calculate joint angles
    d2r = pi/180;
    th_FL = d2r * quadrupedInverseKinematics(a(1),-b,l1,l2);
    th_FR = d2r * quadrupedInverseKinematics(a(2),-b,l1,l2);
    th_RL = d2r * quadrupedInverseKinematics(a(3),-b,l1,l2);
    th_RR = d2r * quadrupedInverseKinematics(a(4),-b,l1,l2);

    % Adjust for foot height
    foot_height = ...
        0.05*l2*(1-sin(2*pi-(3*pi/2+sum([th_FL;th_FR;th_RL;th_RR],2))));
    y_body = max(b) + max(foot_height);

    % Randomize body velocities
    vx = 2 * max_speed_x * (rand-0.5);
    vy = 2 * max_speed_y * (rand-0.5);

else
    % Start from fixed initial conditions

    y_body = 0.7588;
    th_FL = [-0.8234 1.6468];
    th_FR = th_FL;
    th_RL = th_FL;
    th_RR = th_FL;
    vx = 0;
    vy = 0;
end

in = setVariable(in,'y_init',y_body);
in = setVariable(in,'init_ang_FL',th_FL);
in = setVariable(in,'init_ang_FR',th_FR);
in = setVariable(in,'init_ang_RL',th_RL);
in = setVariable(in,'init_ang_RR',th_RR);
in = setVariable(in,'vx_init',vx);
in = setVariable(in,'vy_init',vy);
end

참고 문헌

[1] Heess, Nicolas, Dhruva TB, Srinivasan Sriram, Jay Lemmon, Josh Merel, Greg Wayne, Yuval Tassa, et al. ‘Emergence of Locomotion Behaviours in Rich Environments’. ArXiv:1707.02286 [Cs], 10 July 2017. https://arxiv.org/abs/1707.02286.

참고 항목

함수

객체

블록

도움말 항목