[강화학습] "PPO" 알고리즘 핵심 이론 및 최신 RL 트렌드 정리

2026. 3. 15. 14:46·개념 정리 step2/강화 학습

PPO(Proximal Policy Optimization)는 강화학습에서 정책(Policy)을 안정적으로 업데이트하기 위해 제안된 정책 기반(Policy-based) 알고리즘입니다. 구현이 비교적 간단하면서도 안정성과 성능이 뛰어나 OpenAI Baselines, Stable-Baselines, RLlib 등 다양한 강화학습 프레임워크에서 기본 알고리즘으로 채택하고 있습니다.

1. PPO (Proximal Policy Optimization)

기존의 정책 경사(Policy Gradient) 방법은 정책을 한 번에 크게 업데이트할 경우 학습이 불안정해지는 치명적인 단점이 있었습니다. PPO는 정책이 이전 정책에서 너무 멀리 벗어나지 않도록 제한(Clip)하여 이 문제를 해결합니다.

1.1 PPO가 등장한 이유: TRPO의 한계

정책이 한 번 업데이트될 때 기존 정책과 너무 많이 달라지면 학습이 붕괴되고 성능이 급격히 하락할 수 있습니다. 이를 방지하기 위해 먼저 등장한 알고리즘이 TRPO(Trust Region Policy Optimization)입니다.

TRPO는 정책이 이전 정책에서 너무 멀어지지 않도록 KL Divergence를 사용하여 정책 변화량을 엄격하게 제한했습니다. 하지만 다음과 같은 명확한 한계가 있었습니다.

  1. 구현이 매우 복잡함.
  2. 2차 미분인 헤시안 행렬(Hessian Matrix)을 사용하여 계산량이 지나치게 많음.

PPO는 TRPO의 '안정적인 업데이트'라는 목적은 유지하면서, 1차 미분만을 사용하여 계산을 단순화한 알고리즘입니다.


1.2 PPO의 핵심 아이디어

PPO는 Advantage Actor-Critic 구조를 기반으로 합니다. Actor는 행동 정책을 학습하고, Critic은 상태 가치(Value)를 추정하여 Advantage를 계산합니다.

1) 비율(Ratio) 계산

PPO는 정책의 변화량을 측정하기 위해 현재 정책과 이전 정책의 확률 비율을 계산합니다.

  • $\pi(a|s)$: 상태 $s$에서 행동 $a$를 할 확률 (현재 정책)
  • $\pi_{old}(a|s)$: 이전 정책
$$ratio = \frac{\pi(a|s)}{\pi_{old}(a|s)}$$

2) Advantage 계산

Advantage는 특정 행동이 해당 상태에서의 평균적인 기대치보다 '얼마나 더 좋은가'를 의미합니다. 즉, 실제로 얻은 가치와 Critic이 예측한 상태 가치의 차이입니다.

$$Advantage = Q(s, a) - V(s)$$

3) PPO Clipped Objective (핵심 손실 함수)

PPO는 확률 비율(ratio)이 일정 범위를 벗어나면 업데이트를 강제로 제한하는 Clipped Objective Function을 사용합니다.

$$L^{CLIP}(\theta) = \mathbb{E} \left[ \min(ratio \cdot Advantage, \text{clip}(ratio, 1-\epsilon, 1+\epsilon) \cdot Advantage) \right]$$

($\epsilon$은 보통 $0.1$ ~ $0.2$로 설정합니다.)

4) Clip의 작동 원리

PPO의 지상 목표는 "정책이 한 번에 너무 많이 바뀌지 않게 하자"입니다.

  • $\epsilon = 0.2$ 일 때, ratio의 허용 범위는 $0.8$ ~ $1.2$가 됩니다.

[정상 업데이트의 경우]

  • 이전 정책 확률 = $0.4$
  • 새 정책 확률 = $0.42$
  • $ratio = 0.42 / 0.4 = 1.05$
  • 허용 범위($0.8$ ~ $1.2$) 안이므로 그대로 업데이트를 진행합니다.

[Clip이 적용되는 경우]

  • 만약 ratio 계산 결과가 $1.5$가 나왔다면, 허용 범위를 초과한 것입니다.
  • 업데이트 크기가 너무 크다고 판단하여, ratio를 상한선인 $1.2$로 강제 제한(Clip)합니다. 이를 통해 정책이 파괴되는 것을 막습니다.

1.3 PPO 전체 알고리즘 흐름

  1. 초기 정책 $\pi_\theta$ 설정
  2. 반복(Iteration):
    • 환경에서 데이터를 수집 (상태, 행동, 보상)
    • Advantage 계산
    • 여러 Epoch 동안 반복:
      • ratio 계산
      • Clip 적용하여 Loss 계산
      • Gradient 계산 및 정책 업데이트

1.4 PPO PyTorch 구현 코드

import gymnasium as gym
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.distributions import Categorical

# Hyperparameters
learning_rate = 0.0005
gamma         = 0.98
# GAE(Generalized Advantage Estimation): 
# Monte Carlo의 높은 분산과 TD의 높은 편향(bias) 사이의 균형을 맞추기 위해 TD 오차를 여러 스텝 섞어 계산
lmbda         = 0.95
eps_clip      = 0.1
K_epoch       = 3
T_horizon     = 20

class PPO(nn.Module):
    def __init__(self):
        super(PPO, self).__init__()
        self.data = []

        self.fc1   = nn.Linear(4, 256)
        self.fc_pi = nn.Linear(256, 2)
        self.fc_v  = nn.Linear(256, 1)
        self.optimizer = optim.Adam(self.parameters(), lr=learning_rate)

    def pi(self, x, softmax_dim=0):
        x = F.relu(self.fc1(x))
        x = self.fc_pi(x)
        prob = F.softmax(x, dim=softmax_dim)
        return prob

    def v(self, x):
        x = F.relu(self.fc1(x))
        v = self.fc_v(x)
        return v

    def put_data(self, transition):
        self.data.append(transition)

    def make_batch(self):
        s_lst, a_lst, r_lst, s_prime_lst, prob_a_lst, done_lst = [], [], [], [], [], []

        for transition in self.data:
            s, a, r, s_prime, prob_a, done = transition

            s_lst.append(s)
            a_lst.append([a])
            r_lst.append([r])
            s_prime_lst.append(s_prime)
            prob_a_lst.append([prob_a])

            done_mask = 0 if done else 1
            done_lst.append([done_mask])

        s = torch.tensor(np.array(s_lst), dtype=torch.float)
        a = torch.tensor(np.array(a_lst), dtype=torch.long)
        r = torch.tensor(np.array(r_lst), dtype=torch.float)
        s_prime = torch.tensor(np.array(s_prime_lst), dtype=torch.float)
        done_mask = torch.tensor(np.array(done_lst), dtype=torch.float)
        prob_a = torch.tensor(np.array(prob_a_lst), dtype=torch.float)

        self.data = []
        return s, a, r, s_prime, done_mask, prob_a

    def train_net(self):
        s, a, r, s_prime, done_mask, prob_a = self.make_batch()

        for _ in range(K_epoch):
            td_target = r + gamma * self.v(s_prime) * done_mask
            delta = td_target - self.v(s)
            delta = delta.detach().cpu().numpy()

            advantage_lst = []
            advantage = 0.0
            # GAE 계산: 보상 리스트를 뒤에서부터 역순으로 순회하며 누적 연산
            for delta_t in delta[::-1]:
                advantage = gamma * lmbda * advantage + delta_t[0]
                advantage_lst.append([advantage])

            advantage_lst.reverse()
            advantage = torch.tensor(advantage_lst, dtype=torch.float)

            pi = self.pi(s, softmax_dim=1)
            pi_a = pi.gather(1, a)

            # ratio 계산: exp(log(pi) - log(prob_old)) = pi / prob_old
            ratio = torch.exp(torch.log(pi_a + 1e-8) - torch.log(prob_a + 1e-8))

            surr1 = ratio * advantage
            surr2 = torch.clamp(ratio, 1 - eps_clip, 1 + eps_clip) * advantage
            loss = -torch.min(surr1, surr2) + F.smooth_l1_loss(self.v(s), td_target.detach())

            self.optimizer.zero_grad()
            loss.mean().backward()
            self.optimizer.step()

def main():
    env = gym.make('CartPole-v1')
    model = PPO()
    score = 0.0
    print_interval = 20

    for n_epi in range(10000):
        s, _ = env.reset()
        done = False

        while not done:
            for _ in range(T_horizon):
                prob = model.pi(torch.from_numpy(s).float())
                m = Categorical(prob)
                a = m.sample().item()

                s_prime, r, terminated, truncated, info = env.step(a)
                done = terminated or truncated

                model.put_data((s, a, r / 100.0, s_prime, prob[a].item(), done))
                s = s_prime
                score += r

                if done:
                    break

            model.train_net()

        if n_epi % print_interval == 0 and n_epi != 0:
            print("# of episode :{}, avg score : {:.1f}".format(n_epi, score / print_interval))
            score = 0.0

    env.close()

if __name__ == '__main__':
    main()

2. 최신 강화학습 트렌드 및 주요 알고리즘

최근 강화학습은 환경 내에서 단순히 상호작용하는 것을 넘어, 시뮬레이션 활용, 오프라인 데이터 활용, 트랜스포머 아키텍처 도입 등 다양한 방식으로 진화하고 있습니다.

2.1 SAC (Soft Actor-Critic)

  • 핵심 개념: 최대 엔트로피(Maximum Entropy) 기반의 Off-policy Actor-Critic 알고리즘입니다.
  • 특징: 단순히 주어지는 보상(Reward)을 최대화하는 것을 넘어, 정책의 무작위성(엔트로피)도 함께 최대화하도록 학습합니다.
  • 장점: 에이전트가 특정 행동에 과도하게 수렴하는(Local Optima) 현상을 방지하고, 더 다양한 행동 공간을 탐험하게 하여 학습 안정성을 대폭 끌어올립니다. 두 개의 Q-네트워크를 사용하는 Double Q-learning 구조를 채택하여 연속적인 행동 공간(Continuous Action Space) 제어 환경(예: 로봇 제어)에서 매우 강력한 성능을 발휘합니다.
  • 참고: 추후 블로그 작성 예정.

2.2 MuZero

  • 핵심 개념: 환경의 규칙이나 모델을 미리 알지 못해도 스스로 학습하는 모델 기반(Model-based) 강화학습입니다. DeepMind에서 제안했습니다.
  • 특징: 전작인 AlphaZero는 바둑이나 체스처럼 룰이 완벽히 정의된 환경에서만 동작했지만, MuZero는 환경 자체를 모델링하는 신경망(Representation, Dynamics, Prediction Network)을 학습합니다.
  • 의사결정: 내재된 모델을 통해 미래 상태를 예측하고, 이를 바탕으로 MCTS(Monte Carlo Tree Search)를 수행하여 최적의 행동을 찾아냅니다.

2.3 MCTS (Monte Carlo Tree Search)

  • 핵심 개념: 가능한 경우의 수를 트리(Tree) 구조로 탐색하며, 여러 번의 무작위 시뮬레이션을 통해 최적의 경로를 찾는 탐색 알고리즘입니다. AlphaGo의 핵심 엔진입니다.
  • 4단계 프로세스: 1. 선택(Selection): 현재 상태에서 유망한 노드를 골라 내려갑니다.3. 시뮬레이션(Simulation): 해당 노드에서 끝까지 랜덤 플레이를 돌려봅니다.
  • 4. 역전파(Backpropagation): 시뮬레이션 결과(승/패, 보상)를 거슬러 올라가며 트리의 통계값을 업데이트합니다.
  • 2. 확장(Expansion): 탐색하지 않은 새로운 행동 노드를 추가합니다.

2.4 Dreamer

  • 핵심 개념: 환경과 직접 상호작용하며 데이터를 모으는 대신, 학습된 세계 모델(World Model) 내부에서 상상(Imagination)하며 학습하는 모델 기반 강화학습 알고리즘입니다.
  • 특징: 에이전트가 현실 경험을 바탕으로 잠재 공간(Latent Space) 기반의 동적 모델을 구축합니다. 정책 업데이트는 현실 데이터가 아닌, 이 세계 모델이 생성한 가상의 미래 시나리오(Trajectory) 안에서 이루어집니다. 고차원 이미지 입력이 필요한 환경에서 샘플 효율성(Sample Efficiency)을 극대화합니다.

2.5 Decision Transformer

  • 핵심 개념: 강화학습을 최적화 제어 문제가 아닌 시퀀스 모델링(Sequence Modeling) 문제로 치환한 혁신적인 접근법입니다.
  • 특징: Transformer 아키텍처를 사용하여 과거의 (상태, 행동, 보상) 시퀀스를 입력받아 다음 행동을 예측합니다.
  • 오프라인 지도학습: 환경과 상호작용하며 정책을 업데이트하는 기존 방식이 아닙니다. 이미 수집된 거대한 오프라인 데이터셋을 지도학습 방식으로 학습합니다. 특히, 목표로 하는 총 보상값인 **"Return-to-Go"**를 입력에 조건으로 달아주어, 원하는 성능 수준의 행동을 생성하도록 유도할 수 있습니다.

'개념 정리 step2 > 강화 학습' 카테고리의 다른 글

[강화학습] A3C, A2C, ACER 알고리즘 핵심 정리 및 구현  (0) 2026.03.14
[강화학습] Policy Gradient부터 Actor-Critic까지 정리  (0) 2026.03.10
[강화학습] Q-learning의 개념부터 Gym을 활용한 DQN 구현까지  (0) 2026.03.04
[강화학습] Deep Reinforcement Learning 개념  (0) 2026.03.03
[강화학습] TD Learning (시간차 학습) 개념, 랜덤 벽 GridWorld 실습  (0) 2026.03.01
'개념 정리 step2/강화 학습' 카테고리의 다른 글
  • [강화학습] A3C, A2C, ACER 알고리즘 핵심 정리 및 구현
  • [강화학습] Policy Gradient부터 Actor-Critic까지 정리
  • [강화학습] Q-learning의 개념부터 Gym을 활용한 DQN 구현까지
  • [강화학습] Deep Reinforcement Learning 개념
고니3000원
고니3000원
공부 내용 정리, 자기발전 블로그 입니다. 기존 네이버 블로그에서 티스토리로 이전했습니다. https://blog.naver.com/pak1010pak
  • 고니3000원
    곤이의 공부 블로그
    고니3000원
  • 전체
    오늘
    어제
    • 분류 전체보기 (178) N
      • 1. AI 논문 + 모델 분석 (20)
        • AI 논문 분석 (13)
        • AI 모델 분석 (7)
      • 2. 자료구조와 알고리즘 (16)
        • 2-1 자료구조와 알고리즘 (13)
        • 2-2 강화학습 알고리즘 (3)
      • 3. 자습 & 메모(실전, 실습, 프로젝트) (25)
        • 3-1 문제 해석 (4)
        • 3-2 메모(실전, 프로젝트) (14)
        • 3-3 배포 실전 공부 (7)
      • 4. [팀] 프로젝트 및 공모전 (14)
        • 4-1 팀 프로젝트(메모, 공부) (1)
        • 4-2 Meat-A-Eye (6)
        • 4-3 RL-Tycoon-Agent (3)
        • 4-4 구조물 안정성 물리 추론 AI 경진대회(D.. (4)
      • 5. [개인] 프로젝트 및 공모전 (0)
        • 4-1 귀멸의칼날디펜스(자바스크립트 활용) (5)
        • 4-2 바탕화면 AI 펫 프로그램 (4)
        • 4-3 개인 프로젝트(기타) (3)
      • 개념 정리 step1 (32)
        • Python 기초 (7)
        • DBMS (1)
        • HTML | CSS (3)
        • Git | GitHub (1)
        • JavaScript (5)
        • Node.js (5)
        • React (1)
        • 데이터 분석 (6)
        • Python Engineering (3)
      • 개념 정리 step2 (57) N
        • Machine | Deep Learning (15)
        • 멀티모달(Multi-modal) (23)
        • 강화 학습 (10)
        • AI Agent (9) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 네이버 곤이의 블로그(Naver->Tistory)
    • Github
  • 공지사항

  • 인기 글

  • 태그

    ViT
    귀칼
    github
    프로젝트
    Vision
    자바스크립트
    논문 리뷰
    Attention Is All You Need
    자료구조
    EfficientNet
    알고리즘
    학습
    OCR학습
    파이썬
    bottleneck
    파인튜닝
    javascript
    Python
    Ai
    OCR
    데이터분석
    강화 학습
    pandas
    공모전
    transformer
    Grad-CAM
    구현
    강화학습
    paddleocr
    html
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[강화학습] "PPO" 알고리즘 핵심 이론 및 최신 RL 트렌드 정리
상단으로

티스토리툴바