Main Content

여러 개의 에이전트가 협업해서 작업을 수행하도록 훈련시키기

이 예제에서는 Simulink® 환경에서 다중 에이전트 분산식 또는 중앙 집중식 훈련을 설정하는 방법을 보여줍니다. 이 예제를 통해 2개의 에이전트가 협업해서 물체를 옮기는 작업을 훈련해 보겠습니다.

이 예제의 환경은 원으로 표현된 요소들이 들어있는 마찰 없는 2차원 표면입니다. 타깃 물체 C는 반지름이 2m인 파란색 원이고, 로봇 A(빨간색)와 로봇 B(녹색)는 각각 반지름이 1m인 더 작은 원입니다. 이들 로봇은 충돌을 통해 힘을 가하여 물체 C를 반지름이 8m인 원의 테두리 밖으로 옮기려고 합니다. 환경 내에 있는 모든 요소들은 질량을 가지며 뉴턴의 운동 법칙을 따릅니다. 또한, 요소와 환경 경계 사이의 접촉력은 스프링과 질량 댐퍼 시스템으로 모델링됩니다. 요소들은 외부적으로 가해진 힘의 적용을 통해 표면에서 X와 Y 방향으로 움직일 수 있습니다. 요소는 3차원에서 움직이지 않으며 시스템의 총 에너지가 보존됩니다.

난수 시드값을 설정하고 이 예제에 필요한 파라미터 세트를 만듭니다.

rng(0)
rlCollaborativeTaskParams

Simulink 모델을 엽니다.

mdl = "rlCollaborativeTask";
open_system(mdl)

이 환경의 경우 다음이 적용됩니다.

  • 2차원 공간은 X와 Y 방향에서 모두 –12m부터 12m까지 경계가 지정되어 있습니다.

  • 접촉 스프링 경직성과 감쇠 값은 각각 100N/m 및 0.1N/m/s입니다.

  • 에이전트들은 A, B, C의 위치와 속도에 대해 동일한 관측값을 공유하고 마지막 시간 스텝의 행동 값을 공유합니다.

  • 물체 C가 원의 테두리 밖으로 나가면 시뮬레이션이 종료됩니다.

  • 각 시간 스텝에서 에이전트는 다음 보상을 받습니다.

rA=rglobal+rlocal,ArB=rglobal+rlocal,Brglobal=0.001dcrlocal,A=-0.005dAC-0.008uA2rlocal,B=-0.005dBC-0.008uB2

여기서 각 요소는 다음과 같습니다.

  • rArB는 각각 에이전트 A와 B가 받는 보상입니다.

  • rglobal은 물체 C가 테두리 경계 쪽으로 더 가까이 움직였을 때 두 에이전트가 모두 받는 팀 보상입니다.

  • rlocal,Arlocal,B는 물체 C와의 거리 및 마지막 시간 스텝의 행동 크기에 기반하여 에이전트 A와 B가 받는 국소 벌점입니다.

  • dC는 원의 중심에서 물체 C까지의 거리입니다.

  • dACdBC는 각각 에이전트 A와 물체 C 사이, 그리고 에이전트 B와 물체 C 사이의 거리입니다.

  • 에이전트가 로봇에 외부 힘을 가하고 그 결과 로봇이 움직입니다. uAuB는 마지막 시간 스텝에서 두 에이전트 A와 B의 행동 값입니다. 행동 값의 범위는 -1과 1 사이입니다.

환경

다중 에이전트 환경을 만들려면 string형 배열을 사용하여 에이전트의 블록 경로를 지정하십시오. 또한, 셀형 배열을 사용하여 관측값과 행동 사양 객체를 지정하십시오. 셀형 배열에서 사양 객체의 순서는 블록 경로 배열에 지정된 순서와 일치해야 합니다. 환경을 생성하는 시점에 MATLAB® 작업 공간에 사용 가능한 에이전트가 있는 경우, 관측값 및 행동 사양 배열은 선택 사항입니다. 다중 에이전트 환경을 만드는 방법에 대한 자세한 내용은 rlSimulinkEnv 항목을 참조하십시오.

환경에 대한 I/O 사양을 만듭니다. 이 예제에서 에이전트는 동일한 유형이며 동일한 I/O 사양을 가집니다.

% Number of observations
numObs = 16;

% Number of actions
numAct = 2;

% Maximum value of externally applied force (N)
maxF = 1.0;

% I/O specifications for each agent
oinfo = rlNumericSpec([numObs,1]);
ainfo = rlNumericSpec([numAct,1], ...
    UpperLimit= maxF, ...
    LowerLimit= -maxF);
oinfo.Name = "observations";
ainfo.Name = "forces";

Simulink 환경 인터페이스를 만듭니다.

blks = ["rlCollaborativeTask/Agent A", "rlCollaborativeTask/Agent B"];
obsInfos = {oinfo,oinfo};
actInfos = {ainfo,ainfo};
env = rlSimulinkEnv(mdl,blks,obsInfos,actInfos);

환경에 대한 재설정 함수를 지정합니다. 함수 resetRobots는 각 에피소드가 시작할 때마다 로봇이 임의의 초기 위치에서 시작할 수 있게 해줍니다. 이 함수는 이 예제의 끝부분에 제공됩니다.

env.ResetFcn = @(in) resetRobots(in,RA,RB,RC,boundaryR);

에이전트

이 예제에서는 연속 행동 공간에서 2개의 PPO(근위 정책 최적화) 에이전트를 사용합니다. 에이전트가 로봇에 외부 힘을 가하고 그 결과 로봇이 움직입니다. PPO 에이전트에 대한 자세한 내용은 Proximal Policy Optimization (PPO) Agents 항목을 참조하십시오.

에이전트는 미니 배치 크기 300과 경험 지평 600을 사용하여 수집된 궤적에서 훈련됩니다. 훈련 안정성을 높이기 위해 목적 함수 자르기 인자 0.2를 사용하고, 장기 보상을 장려하기 위해 감가 인자 0.99를 사용합니다.

이 예제에 대한 에이전트 옵션을 지정합니다.

agentOptions = rlPPOAgentOptions(...
    ExperienceHorizon=600,...
    ClipFactor=0.2,...
    EntropyLossWeight=0.01,...
    MiniBatchSize=300,...
    NumEpoch=4,...
    SampleTime=Ts,...
    DiscountFactor=0.99);

액터와 크리틱에 대한 학습률을 1e-4로 설정합니다.

agentOptions.ActorOptimizerOptions.LearnRate  = 1e-4;
agentOptions.CriticOptimizerOptions.LearnRate = 1e-4;

디폴트 에이전트 생성 구문을 사용하여 에이전트를 만듭니다. 자세한 내용은 rlPPOAgent 항목을 참조하십시오.

dcAgentA = rlPPOAgent(oinfo, ainfo, ...
    rlAgentInitializationOptions(NumHiddenUnit= 200), agentOptions);
dcAgentB = rlPPOAgent(oinfo, ainfo, ...
    rlAgentInitializationOptions(NumHiddenUnit= 200), agentOptions);
cnAgentA = rlPPOAgent(oinfo, ainfo, ...
    rlAgentInitializationOptions(NumHiddenUnit= 200), agentOptions);
cnAgentB = rlPPOAgent(oinfo, ainfo, ...
    rlAgentInitializationOptions(NumHiddenUnit= 200), agentOptions);

훈련

여러 개의 에이전트를 훈련시키려면 에이전트로 구성된 배열을 train 함수에 전달할 수 있습니다. 배열에서 에이전트의 순서는 환경 생성 중에 지정된 에이전트 블록 경로의 순서와 일치해야 합니다. 이렇게 하면 agent 객체가 환경에서 적절한 I/O 인터페이스에 연결됩니다.

분산식 또는 중앙 집중식으로 여러 개의 에이전트를 훈련시킬 수 있습니다. 분산식 훈련에서 에이전트는 에피소드 중에 자신만의 경험 세트를 수집하고 이러한 경험으로부터 독립적으로 학습합니다. 중앙 집중식 훈련에서 에이전트는 수집한 경험을 공유하고 이러한 경험으로부터 함께 학습합니다. 궤적이 완성된 후에 에이전트 간에 액터와 크리틱 함수가 동기화됩니다.

다중 에이전트 훈련을 구성하려면 rlMultiAgentTrainingOptions 객체를 통해 에이전트 그룹을 만들고 각 그룹에 대한 학습 전략을 지정할 수 있습니다. 각 에이전트 그룹은 고유한 에이전트 인덱스를 포함할 수 있으며, 학습 전략은 "centralized" 또는 "decentralized"일 수 있습니다. 예를 들어, 다음 명령을 사용하여 서로 다른 학습 전략을 갖는 3개의 에이전트 그룹에 대한 훈련을 구성할 수 있습니다. 인덱스가 [1,2][3,4]인 에이전트는 중앙 집중식으로 학습하는 반면, 에이전트 4는 분산식으로 학습합니다.

opts = rlMultiAgentTrainingOptions(AgentGroups= {[1,2], 4, [3,5]}, LearningStrategy= ["centralized","decentralized","centralized"])

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

1. 분산식 훈련

이 예제에 대해 분산식 다중 에이전트 훈련을 구성하려면 다음을 수행하십시오.

  • AgentGroups=auto 옵션을 사용하여 에이전트 그룹을 자동으로 할당합니다. 이 경우 각 에이전트가 별개의 그룹에 할당됩니다.

  • "decentralized" 학습 전략을 지정합니다.

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

dcOpts = rlMultiAgentTrainingOptions(...
    AgentGroups="auto",...
    LearningStrategy="decentralized",...
    MaxEpisodes=500,...
    MaxStepsPerEpisode=600,...
    ScoreAveragingWindowLength=30,...
    StopTrainingCriteria="none");

train 함수를 사용하여 에이전트를 훈련시킵니다. 계산 성능에 따라 훈련을 완료하는 데 몇 시간이 걸릴 수 있습니다. 시간을 절약하기 위해 사전 훈련된 에이전트 세트가 포함된 MAT 파일 decentralizedAgents.mat를 불러옵니다. 에이전트를 직접 훈련시키려면 dcTrainingtrue로 설정하십시오.

dcTraining = false;
if dcTraining
    dcResults = train([dcAgentA,dcAgentB], env, dcOpts);
else
    load("decentralizedAgents.mat");
end

다음 그림은 분산식 훈련 진행의 스냅샷을 보여줍니다. 훈련 과정에서 임의성으로 인해 서로 다른 결과가 나올 수 있습니다.

2. 중앙 집중식 훈련

이 예제에 대해 중앙 집중식 다중 에이전트 훈련을 구성하려면 다음을 수행하십시오.

  • 두 에이전트(인덱스 12)를 모두 하나의 그룹에 할당합니다. 이렇게 하려면 "AgentGroups" 옵션에 에이전트 인덱스를 지정하십시오.

  • "centralized" 학습 전략을 지정합니다.

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

cnOpts = rlMultiAgentTrainingOptions(...
    AgentGroups={[1,2]},...
    LearningStrategy="centralized",...
    MaxEpisodes=500,...
    MaxStepsPerEpisode=600,...
    ScoreAveragingWindowLength=30,...
    StopTrainingCriteria="none");

train 함수를 사용하여 에이전트를 훈련시킵니다. 계산 성능에 따라 훈련을 완료하는 데 몇 시간이 걸릴 수 있습니다. 시간을 절약하기 위해 사전 훈련된 에이전트 세트가 포함된 MAT 파일 centralizedAgents.mat를 불러옵니다. 에이전트를 직접 훈련시키려면 cnTrainingtrue로 설정하십시오.

cnTraining = false;
if cnTraining
    cnResults = train([cnAgentA,cnAgentB], env, cnOpts);
else
    load("centralizedAgents.mat");
end

다음 그림은 중앙 집중식 훈련 진행의 스냅샷을 보여줍니다. 훈련 과정에서 임의성으로 인해 서로 다른 결과가 나올 수 있습니다.

시뮬레이션

재현이 가능하도록 난수 시드값을 초기화합니다.

rng(0);

시뮬레이션이 수행되는 환경 스텝의 최대 수를 600으로 지정하는 simulation options 객체를 만듭니다.

simOptions = rlSimulationOptions(MaxSteps=600);

분산식으로 훈련된 에이전트를 환경에서 시뮬레이션합니다.

dcExp = sim(env,[dcAgentA,dcAgentB],simOptions);

중앙 집중식으로 훈련된 에이전트를 환경에서 시뮬레이션합니다.

cnExp = sim(env,[cnAgentA,cnAgentB],simOptions);

Figure Multi Agent Collaborative Task contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 5 objects of type rectangle, text.

에이전트가 물체를 테두리 밖으로 밀어낼 수 있습니다.

에이전트 시뮬레이션에 대한 자세한 내용은 rlSimulationOptions 항목과 sim 항목을 참조하십시오.

로컬 함수

환경을 재설정하는 헬퍼 함수입니다.

function in = resetRobots(in,RA,RB,RC,boundaryR)
% Reset the environment.

% Random initial positions
valid = false;
while ~valid
    xA0 = -10 + 20*rand;
    yA0 = -10 + 20*rand;
    xB0 = -10 + 20*rand;
    yB0 = -10 + 20*rand;
    r = 0.5*boundaryR*rand;
    th = -pi + 2*pi*rand;
    xC0 = r*cos(th);
    yC0 = r*sin(th);
    dAB = norm([xA0-xB0;yA0-yB0]);
    dBC = norm([xB0-xC0;yB0-yC0]);
    dAC = norm([xA0-xC0;yA0-yC0]);
    dA = norm([xA0;yA0]);
    dB = norm([xB0;yB0]);
    valid = dA > boundaryR && dB > boundaryR && dAB > (RA+RB) && dBC > (RB+RC) && dAC > (RA+RC);
end

% Set the variables in the simulation input object
in = setVariable(in,'xA0',xA0);
in = setVariable(in,'xB0',xB0);
in = setVariable(in,'yA0',yA0);
in = setVariable(in,'yB0',yB0);

% Set a post sim function for visualization
in = setPostSimFcn(in,@(out) localPostSim(out,RA,RB,RC,boundaryR));
end

function out = localPostSim(out,RA,RB,RC,boundaryR)
tsqA = localGetState(out,'qA');
tsqB = localGetState(out,'qB');
tsqC = localGetState(out,'qC');
xA = tsqA.Data(:,1);
xB = tsqB.Data(:,1);
xC = tsqC.Data(:,1);
yA = tsqA.Data(:,2);
yB = tsqB.Data(:,2);
yC = tsqC.Data(:,2);
t = tsqA.Time;
for i = 1:numel(xA)
    plotEnvironment([xA(i);xB(i);xC(i)], [yA(i);yB(i);yC(i)], [RA;RB;RC], boundaryR, t(i));
    drawnow();
end
end

function ts = localGetState(out,name)
stateObj = out.logsout.get(name);
ts = stateObj.Values;
end

환경을 플로팅하는 헬퍼 함수입니다.

function plotEnvironment(x,y,R,boundaryR,t)
% Plot the environment.

persistent f;
if isempty(f) || ~isvalid(f)
    f = figure(...
        NumberTitle="off",...
        Name="Multi Agent Collaborative Task",...
        MenuBar="none",...
        Position=[500,500,300,300],...
        Visible="on");
    ha = gca(f);
    axis(ha,"equal");
    ha.XLim = [-12 12];
    ha.YLim = [-12 12];
    xlabel(ha,"X (m)");
    ylabel(ha,"Y (m)");
    
    D = [-1 -1 2 2]*boundaryR;
    rectangle(ha,Position=D,Curvature=[1 1]);
    
    hold(ha,'on');
end
% plot elements
ha = gca(f);
N = numel(R);
colors = ["r","g","b"];
for i = 1:N
    D = [(x(i)-R(i)) (y(i)-R(i)) 2*R(i) 2*R(i)];
    tagstr = sprintf("rect_%u",i);
    r = findobj(ha,Tag=tagstr);
    if isempty(r)
        r = rectangle(ha,Position=D,Curvature=[1 1],Tag=tagstr);
        r.FaceColor = colors(i);
    else
        r.Position = D;
    end
end
% Display time string
timestr = sprintf("Time: %0.1f s",t);
time = findobj(ha,Tag="time");
if isempty(time)
    text(ha,5,10,timestr,Tag="time");
else
    time.String = timestr;
end
end

참고 항목

함수

객체

블록

관련 예제

세부 정보