인공지능/강화학습

Matlab 강화학습 - simulink 환경 만들기 및 에이전트 훈련시키기

이게될까 2024. 5. 10. 03:15
728x90
728x90

https://kr.mathworks.com/help/reinforcement-learning/ug/create-simulink-environment-and-train-agent.html

 

Simulink 환경 만들기 및 에이전트 훈련시키기 - MATLAB & Simulink - MathWorks 한국

다음 MATLAB 명령에 해당하는 링크를 클릭했습니다. 명령을 실행하려면 MATLAB 명령 창에 입력하십시오. 웹 브라우저는 MATLAB 명령을 지원하지 않습니다.

kr.mathworks.com

 

% Observation info
obsInfo = rlNumericSpec([3 1],...
    LowerLimit=[-inf -inf 0  ]',...
    UpperLimit=[ inf  inf inf]');

% Name and description are optional and not used by the software
obsInfo.Name = "observations";
obsInfo.Description = "integrated error, error, and measured height";

% Action info
actInfo = rlNumericSpec([1 1]);
actInfo.Name = "flow";

관측값 obs와 액션 act 정의해주기!

 

env = rlSimulinkEnv("rlwatertank","rlwatertank/RL Agent",...
    obsInfo,actInfo);

환경 객체에 관측값과 액션 넣고, 시뮬링크도 넣어주기

 

env.ResetFcn = @(in)localResetFcn(in);


function in = localResetFcn(in)

% Randomize reference signal
blk = sprintf("rlwatertank/Desired \nWater Level");
h = 3*randn + 10;
while h <= 0 || h >= 20
    h = 3*randn + 10;
end
in = setBlockParameter(in,blk,Value=num2str(h));

% Randomize initial height
h = 3*randn + 10;
while h <= 0 || h >= 20
    h = 3*randn + 10;
end
blk = "rlwatertank/Water-Tank System/H";
in = setBlockParameter(in,blk,InitialCondition=num2str(h));

end

함수를 새로 넣어준다.

 

Ts = 1.0;
Tf = 200;

시뮬레이션 시간 Tf와 초 단위 Ts 지정

 

rng(0)

난수 생성기 시드 값 고정

 

% Observation path
obsPath = [
    featureInputLayer(obsInfo.Dimension(1),Name="obsInLyr")
    fullyConnectedLayer(50)
    reluLayer
    fullyConnectedLayer(25,Name="obsPathOutLyr")
    ];

% Action path
actPath = [
    featureInputLayer(actInfo.Dimension(1),Name="actInLyr")
    fullyConnectedLayer(25,Name="actPathOutLyr")
    ];

% Common path
commonPath = [
    additionLayer(2,Name="add")
    reluLayer
    fullyConnectedLayer(1,Name="QValue")
    ];

criticNetwork = layerGraph();
criticNetwork = addLayers(criticNetwork,obsPath);
criticNetwork = addLayers(criticNetwork,actPath);
criticNetwork = addLayers(criticNetwork,commonPath);

criticNetwork = connectLayers(criticNetwork, ...
    "obsPathOutLyr","add/in1");
criticNetwork = connectLayers(criticNetwork, ...
    "actPathOutLyr","add/in2");

크리틱을 만들었다.

관측값과 액션을 받아서 가치를 출력해준다.

 

figure
plot(criticNetwork)

이런 구조로 되어있습니다.

 

criticNetwork = dlnetwork(criticNetwork);
summary(criticNetwork)

신경망을 dl 객채로 변환하고 레이어 설명해주기

 

critic = rlQValueFunction(criticNetwork, ...
    obsInfo,actInfo, ...
    ObservationInputNames="obsInLyr", ...
    ActionInputNames="actInLyr");

크리틱 근사기 객체 만들기

 

getValue(critic, ...
    {rand(obsInfo.Dimension)}, ...
    {rand(actInfo.Dimension)})

랜덤한 관측값과 액션을 넣어서 가치 출력 확인하기

 

이제 액터를 만든다.

actorNetwork = [
    featureInputLayer(obsInfo.Dimension(1))
    fullyConnectedLayer(3)
    tanhLayer
    fullyConnectedLayer(actInfo.Dimension(1))
    ];

여기도 단순하다.

 

actorNetwork = dlnetwork(actorNetwork);
summary(actorNetwork)

이것도 dl로 객체 변환하고, 요약한다.

 

actor = rlContinuousDeterministicActor(actorNetwork,obsInfo,actInfo);

액터 근사기 객체 만들기!

 

getAction(actor,{rand(obsInfo.Dimension)})
임의의 state 넣어서 액션 확인하기

 

agent = rlDDPGAgent(actor,critic);

만든 액터와 크리틱을 통해 에이전트를 만든다.

 

agent.SampleTime = Ts;

agent.AgentOptions.TargetSmoothFactor = 1e-3;
agent.AgentOptions.DiscountFactor = 1.0;
agent.AgentOptions.MiniBatchSize = 64;
agent.AgentOptions.ExperienceBufferLength = 1e6; 

agent.AgentOptions.NoiseOptions.Variance = 0.3;
agent.AgentOptions.NoiseOptions.VarianceDecayRate = 1e-5;

agent.AgentOptions.CriticOptimizerOptions.LearnRate = 1e-03;
agent.AgentOptions.CriticOptimizerOptions.GradientThreshold = 1;
agent.AgentOptions.ActorOptimizerOptions.LearnRate = 1e-04;
agent.AgentOptions.ActorOptimizerOptions.GradientThreshold = 1;

옵션 지정해주기!

에이전트, 액터, 크리틱의 옵션을 정해준다.

 

이제 훈련을 진행한다.

trainOpts = rlTrainingOptions(...
    MaxEpisodes=5000, ...
    MaxStepsPerEpisode=ceil(Tf/Ts), ...
    ScoreAveragingWindowLength=20, ...
    Verbose=false, ...
    Plots="training-progress",...
    StopTrainingCriteria="AverageReward",...
    StopTrainingValue=800);

최대 5000개의 에피소드에 대해 각 훈련을 실행합니다. 각 에피소드가 최대 ceil(Tf/Ts)개(즉, 200개)의 시간 스텝 동안 지속되도록 지정합니다.

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

연속 20개의 에피소드 동안 에이전트가 받은 평균 누적 보상이 800보다 크면 훈련을 중지합니다. 이 시점에서 에이전트는 탱크에 있는 물의 수위를 제어할 수 있습니다.

 

doTraining = false;

if doTraining
    % Train the agent.
    trainingStats = train(agent,env,trainOpts);
else
    % Load the pretrained agent for the example.
    load("WaterTankDDPG.mat","agent")
end

train 함수를 사용하여 학습한다.

여기선 시간 아끼려고 이전의 학습 데이터를 가지고 온다.

 

simOpts = rlSimulationOptions(MaxSteps=ceil(Tf/Ts),StopOnError="on");
experiences = sim(env,agent,simOpts);

환경 내에서 시뮬레이션하고, 경험을 출력값으로 반환한다.

 

728x90