Skip to main content
Summary

점수가 올랐는데, 정말 똑똑해진 걸까

강화학습을 처음 실습하다 보면 가장 먼저 보게 되는 그래프가 있습니다. 에피소드가 진행될수록 보상이 올라가는 그래프입니다. 처음에는 에이전트가 여기저기 부딪히고, 엉뚱한 곳으로 가고, 금방 실패합니다. 그러다 어느 순간 보상이 조금씩 올라갑니다. 그래프가 우상향하면 마음이 놓입니다.

"됐다. 이제 배웠구나."

하지만 강화학습에서는 이 말이 생각보다 위험합니다. 보상이 올라갔다고 해서 에이전트가 우리가 원하는 행동을 배웠다고 바로 말할 수는 없습니다. 운 좋게 좋은 경로를 몇 번 찾았을 수도 있고, 훈련 중 탐험 방식 때문에 일시적으로 높은 점수를 얻었을 수도 있습니다. 또는 지난 장에서 본 것처럼, 보상 설계의 빈틈을 파고들어 이상한 꼼수를 배웠을 수도 있습니다.

강화학습 모델 평가는 단순히 "평균 보상이 몇 점인가?"를 묻는 일이 아닙니다. 더 정확한 질문은 이렇습니다.

이 에이전트는 새로운 상황에서도 안정적으로, 의도한 방식으로, 반복해서 좋은 선택을 하는가?

이번 장에서는 강화학습 에이전트를 평가하는 방법을 정리합니다. 훈련 보상과 평가 보상을 분리하고, 여러 랜덤 시드로 반복 실험하며, 성공률과 실패 유형, 에피소드 길이, 행동 분포까지 함께 살펴볼 것입니다. 마지막에는 환경이 조금 바뀌었을 때도 정책이 작동하는지 확인하는 일반화 평가까지 다룹니다.

강화학습 모델 평가하기

훈련 보상과 평가 보상은 다르다

강화학습에서는 훈련 중에 얻은 보상을 그대로 모델의 최종 성능으로 보기 어렵습니다. 이유는 간단합니다. 훈련 중의 에이전트는 아직 배우는 중이기 때문입니다.

예를 들어 Q-learning을 학습할 때 우리는 ε-greedy 전략을 사용했습니다. ε-greedy는 대부분의 경우 현재 가장 좋아 보이는 행동을 선택하지만, 가끔은 일부러 무작위 행동을 선택합니다. 이것이 탐험입니다. 탐험은 학습에는 꼭 필요하지만, 평가할 때는 이야기가 달라집니다.

Grid World에서 이미 좋은 길을 배운 에이전트가 있다고 해 봅시다. 그런데 평가 중에도 ε 값이 0.2로 남아 있다면, 다섯 번 중 한 번꼴로 엉뚱한 행동을 할 수 있습니다. 벽으로 가거나, 구멍 쪽으로 가거나, 목적지와 반대 방향으로 갈 수 있습니다. 이때 점수가 낮게 나왔다면 정책이 나쁜 것일까요? 꼭 그렇지는 않습니다. 정책은 괜찮지만 평가 중에도 탐험을 섞었기 때문에 성능이 낮게 측정된 것일 수 있습니다.

반대로 훈련 중에 운 좋게 높은 보상을 얻은 경우도 있습니다. 아직 제대로 된 정책을 배우지 못했는데 우연히 목적지에 도착한 것입니다. 이때 훈련 그래프의 일부만 보면 성능이 좋아 보일 수 있습니다.

그래서 훈련과 평가는 분리해야 합니다. 훈련 중에는 탐험하고, 업데이트하고, 실수합니다. 평가 중에는 학습을 멈추고, 정해진 정책이 실제로 얼마나 잘 작동하는지 확인합니다.

평가할 때는 보통 다음 조건을 사용합니다.

  • 학습 업데이트를 하지 않는다.

  • 탐험률을 낮추거나 0으로 두고 정책을 실행한다.

  • 여러 에피소드에서 평균 성능을 계산한다.

  • 훈련에 사용한 환경뿐 아니라 별도의 테스트 조건에서도 확인한다.

이렇게 해야 "배우는 중에 얻은 점수"와 "배운 뒤 실제로 수행한 점수"를 구분할 수 있습니다.

평가 루프 만들기

평가 루프는 학습 루프와 비슷하지만 한 가지가 결정적으로 다릅니다. 평가 루프에서는 모델을 바꾸지 않습니다. 에이전트가 행동을 선택하고 보상을 받지만, Q값을 업데이트하거나 신경망 파라미터를 조정하지 않습니다.

간단한 평가 함수는 다음과 같은 모양을 가질 수 있습니다.

def evaluate_agent(env, agent, episodes=20):
    returns = []
    lengths = []
    successes = 0

    for _ in range(episodes):
        state = env.reset()
        done = False
        total_reward = 0
        step_count = 0

        while not done:
            action = agent.select_action(state, explore=False)
            next_state, reward, done, info = env.step(action)

            total_reward += reward
            step_count += 1
            state = next_state

        returns.append(total_reward)
        lengths.append(step_count)

        if info.get("success", False):
            successes += 1

    avg_return = sum(returns) / len(returns)
    avg_length = sum(lengths) / len(lengths)
    success_rate = successes / episodes

    return {
        "avg_return": avg_return,
        "avg_length": avg_length,
        "success_rate": success_rate,
        "returns": returns,
        "lengths": lengths,
    }

여기서 중요한 부분은 explore=False입니다. 훈련 중에는 탐험이 필요하지만, 평가할 때는 에이전트가 현재 배운 정책을 그대로 사용해야 합니다. 물론 확률적 정책을 평가하는 경우에는 행동 선택에 확률이 남아 있을 수 있습니다. Policy Gradient나 Actor-Critic 계열에서는 정책 자체가 확률 분포일 수 있기 때문입니다. 그래도 평가 단계에서는 보통 두 가지 방식을 구분해서 봅니다.

하나는 확률적으로 행동을 샘플링하는 평가입니다. 실제 정책이 얼마나 안정적인지 볼 수 있습니다. 다른 하나는 가장 확률이 높은 행동을 선택하는 평가입니다. 정책이 가장 자신 있어 하는 행동만 고르면 어느 정도 성능이 나오는지 확인할 수 있습니다.

이 두 결과가 크게 다르다면 그것도 중요한 신호입니다. 예를 들어 가장 높은 확률의 행동만 고르면 잘하는데, 샘플링하면 자주 실패한다면 정책이 아직 충분히 확신을 갖지 못한 상태일 수 있습니다.

평균 보상 하나로는 부족하다

평균 보상은 좋은 출발점입니다. 하지만 평균은 많은 것을 숨깁니다.

다음 두 에이전트가 있다고 해 봅시다.

에이전트10번 평가 보상평균 보상
A80, 82, 79, 81, 80, 83, 78, 82, 81, 8080.6
B150, 0, 160, 0, 155, 0, 170, 0, 160, 079.5

평균만 보면 A와 B는 비슷합니다. 하지만 실제로는 완전히 다른 정책입니다. A는 매번 안정적으로 80점 안팎을 얻습니다. B는 성공할 때는 크게 성공하지만 절반은 완전히 실패합니다.

게임이라면 B가 더 재미있을 수도 있습니다. 하지만 로봇 제어나 자율주행, 금융 의사결정처럼 실패 비용이 큰 문제라면 B는 위험합니다. 평균 점수는 비슷해도 실제 서비스에 넣기에는 A가 훨씬 믿을 만할 수 있습니다.

그래서 강화학습 모델을 평가할 때는 평균과 함께 분산을 봐야 합니다. 분산은 결과가 얼마나 들쭉날쭉한지를 나타냅니다. 쉽게 말해, 에이전트가 매번 비슷하게 잘하는지 아니면 운에 따라 크게 흔들리는지를 보는 것입니다.

평균 보상 옆에는 최소값, 최대값, 표준편차를 함께 기록하는 습관을 들이면 좋습니다.

import numpy as np

returns = np.array(eval_result["returns"])

print("mean:", returns.mean())
print("std:", returns.std())
print("min:", returns.min())
print("max:", returns.max())

강화학습에서는 "평균 200점"보다 "평균 200점이고 표준편차가 작다"가 더 강한 주장입니다. 좋은 정책은 우연히 한 번 잘하는 정책이 아니라, 반복해서 비슷하게 잘하는 정책입니다.

여러 랜덤 시드로 반복 실험하기

강화학습 실험에는 운이 많이 개입합니다. 처음 신경망 가중치가 어떻게 초기화되었는지, 에피소드 초반에 어떤 경험을 우연히 모았는지, 탐험 중 어떤 행동을 선택했는지에 따라 결과가 달라집니다. 같은 알고리즘, 같은 환경, 같은 하이퍼파라미터를 사용해도 어떤 실행에서는 잘 배우고, 어떤 실행에서는 끝까지 헤맬 수 있습니다.

이때 사용하는 것이 랜덤 시드입니다. 랜덤 시드는 무작위성을 시작하는 번호라고 생각하면 됩니다. 시드를 고정하면 같은 난수 흐름을 재현할 수 있습니다. 반대로 여러 시드로 실험하면 알고리즘이 특정 운에만 의존했는지 확인할 수 있습니다.

한 번의 성공은 증거가 약합니다. 다섯 번, 열 번의 반복 실험에서 꾸준히 잘해야 더 믿을 수 있습니다.

예를 들어 어떤 CartPole 에이전트를 평가했더니 다음과 같은 결과가 나왔다고 해 봅시다.

시드최종 평가 평균 보상표준편차성공률
049831.00
149280.98
250001.00
3185900.30
4476200.94

평균만 보면 꽤 좋아 보일 수 있습니다. 하지만 시드 3에서 크게 실패했습니다. 이 결과는 중요한 질문을 던집니다. 알고리즘이 불안정한 것일까요? 특정 초기 경험에 민감한 것일까요? 학습률이 너무 큰 것일까요? 탐험 전략이 부족했을까요?

강화학습 연구나 실무에서는 이런 질문이 매우 중요합니다. 한 번 잘된 실험만 보고 결론을 내리면, 나중에 환경이 조금 바뀌거나 초기 조건이 달라졌을 때 모델이 쉽게 무너질 수 있습니다.

따라서 실험 결과를 정리할 때는 가능하면 여러 시드의 평균과 분산을 함께 제시해야 합니다.

all_seed_scores = [498, 492, 500, 185, 476]

print("across-seed mean:", np.mean(all_seed_scores))
print("across-seed std:", np.std(all_seed_scores))

여기서 표준편차가 크다면 "성능이 높다"보다 "성능이 불안정하다"는 해석이 먼저 나와야 합니다.

성공률을 따로 보자

평균 보상은 유용하지만, 문제에 따라 성공률이 더 직접적인 지표가 됩니다. 성공률은 전체 에피소드 중 목표를 달성한 비율입니다.

Grid World에서는 목적지에 도착했는지가 성공률이 될 수 있습니다. CartPole에서는 일정 시간 이상 막대를 세웠는지가 성공 기준이 될 수 있습니다. 게임 에이전트라면 스테이지 클리어 여부, 로봇이라면 물체를 집어 올렸는지, 대화 에이전트라면 사용자의 요청을 만족했는지가 성공률의 기준이 될 수 있습니다.

성공률이 중요한 이유는 평균 보상이 성공과 실패를 흐릴 수 있기 때문입니다. 예를 들어 어떤 에이전트가 목적지 근처까지는 잘 가지만 마지막에 자주 실패한다고 해 봅시다. 보상 설계가 목적지에 가까워질수록 점수를 주는 방식이라면 평균 보상은 높게 나올 수 있습니다. 하지만 실제 목표가 "목적지 도착"이라면 이 에이전트는 아직 부족합니다.

반대로 성공률은 높은데 평균 보상이 낮은 경우도 있습니다. 목적지에는 도착하지만 길을 너무 돌아가거나, 불필요한 행동을 많이 해서 시간 벌점을 받는 경우입니다. 이때는 성공률만 보면 괜찮아 보이지만, 실제 정책은 비효율적입니다.

그래서 성공률과 평균 보상은 함께 봐야 합니다. 하나는 목표 달성 여부를 보여 주고, 다른 하나는 그 과정의 품질을 보여 줍니다.

좋은 평가 보고서는 보통 이런 질문에 답해야 합니다.

  • 목표를 얼마나 자주 달성했는가?

  • 성공할 때까지 평균 몇 단계가 걸렸는가?

  • 실패한다면 주로 어떤 방식으로 실패했는가?

  • 성공은 안정적인가, 아니면 일부 에피소드에만 몰려 있는가?

이 질문에 답하기 시작하면 평가는 단순한 점수 확인이 아니라 정책 이해가 됩니다.

실패 유형을 기록하자

강화학습 모델을 평가할 때 가장 아까운 실수는 실패를 그냥 "실패"로만 기록하는 것입니다. 실패에도 종류가 있습니다. 그리고 실패 유형을 보면 모델이 무엇을 잘못 배웠는지 보입니다.

Grid World를 예로 들어 봅시다. 에이전트가 실패했다면 이유는 여러 가지일 수 있습니다. 벽에 계속 부딪혔을 수도 있고, 구멍에 빠졌을 수도 있고, 제한 시간 안에 목적지에 도착하지 못했을 수도 있습니다. 이 세 실패는 모두 다릅니다.

벽에 계속 부딪힌다면 상태 인식이나 행동 가치가 제대로 학습되지 않았을 수 있습니다. 구멍에 빠진다면 위험 상태에 대한 벌점이 부족하거나, 탐험 중 위험한 행동이 지나치게 많이 강화되었을 수 있습니다. 제한 시간 초과라면 목적지 방향은 알지만 경로 효율이 낮은 것일 수 있습니다.

실패 유형은 다음처럼 기록할 수 있습니다.

failure_counts = {
    "hit_wall": 0,
    "fell_into_hole": 0,
    "timeout": 0,
    "other": 0,
}

환경의 info에 실패 이유를 넣어 두면 평가가 훨씬 쉬워집니다.

next_state, reward, done, info = env.step(action)

if done and not info.get("success", False):
    reason = info.get("failure_reason", "other")
    failure_counts[reason] += 1

실패 유형을 기록하면 개선 방향이 선명해집니다. 보상을 바꿔야 하는지, 탐험 전략을 바꿔야 하는지, 상태 표현을 보강해야 하는지 판단할 수 있습니다.

평가란 모델에게 점수를 매기는 일이기도 하지만, 동시에 모델이 왜 실패하는지 듣는 일이기도 합니다. 실패를 자세히 기록할수록 모델은 더 많은 이야기를 들려줍니다.

에피소드 길이는 정책의 습관을 보여 준다

에피소드 길이는 한 에피소드가 몇 단계 만에 끝났는지를 나타냅니다. 이 값은 생각보다 많은 정보를 줍니다.

Grid World에서 목적지에 빨리 도착하는 것이 좋은 문제라면 에피소드 길이는 짧을수록 좋습니다. 하지만 CartPole처럼 오래 버티는 것이 목표인 문제에서는 에피소드 길이가 길수록 좋습니다. 따라서 에피소드 길이는 환경의 목표에 맞게 해석해야 합니다.

중요한 것은 보상과 에피소드 길이를 함께 보는 것입니다.

예를 들어 목적지에 도착하면 +10점을 받고, 매 단계마다 -0.1점을 받는 환경이 있다고 해 봅시다. 두 에이전트 모두 성공률이 100%입니다. 그런데 A는 평균 12단계 만에 도착하고, B는 평균 80단계 만에 도착합니다. 성공률만 보면 둘 다 완벽하지만, B는 길을 빙빙 도는 정책일 가능성이 큽니다.

반대로 매 단계 살아남을 때마다 +1점을 받는 CartPole에서는 길이가 곧 보상과 거의 같습니다. 이때 에피소드 길이가 길다는 것은 막대를 오래 세웠다는 뜻입니다.

에피소드 길이는 특히 보상 해킹을 찾는 데 도움이 됩니다. 에이전트가 목적지로 가지 않고 중간에서 보상을 계속 긁어모으는 행동을 한다면, 에피소드 길이가 비정상적으로 길어질 수 있습니다. 지난 장에서 본 "동전에 가까워지면 보상" 같은 shaping 보상이 잘못 설계되면, 에이전트가 목표 달성 대신 근처를 맴도는 행동을 배울 수 있습니다. 이때 평균 보상만 보면 좋아 보이지만, 에피소드 길이와 행동 궤적을 보면 이상한 습관이 드러납니다.

행동 분포를 보면 에이전트의 성격이 보인다

강화학습 정책은 결국 행동을 선택하는 규칙입니다. 그렇다면 평가할 때 "어떤 행동을 얼마나 자주 선택했는가?"를 보는 것은 매우 자연스러운 일입니다. 이것을 행동 분포라고 부를 수 있습니다.

Grid World에서 행동이 상, 하, 좌, 우 네 가지라고 해 봅시다. 학습된 에이전트가 평가 중에 다음과 같은 비율로 행동했다고 합시다.

행동선택 비율
위5%
아래5%
왼쪽45%
오른쪽45%

이 분포만 보고도 질문이 생깁니다. 환경 구조상 좌우 이동이 많은 것이 자연스러운가? 아니면 에이전트가 세로 이동을 거의 하지 못해 특정 구역에 갇혀 있는가?

CartPole에서는 행동이 왼쪽으로 힘을 주기, 오른쪽으로 힘을 주기 두 가지입니다. 좋은 정책이라면 상황에 따라 좌우 행동을 균형 있게 사용할 수 있습니다. 그런데 한쪽 행동만 지나치게 많이 나온다면 정책이 불안정하거나 상태 입력을 제대로 활용하지 못하고 있을 수 있습니다.

행동 분포는 특히 다음 문제를 찾는 데 유용합니다.

  • 에이전트가 특정 행동에만 과도하게 의존하는 경우

  • 거의 선택되지 않는 행동이 있어 탐험 또는 학습이 부족한 경우

  • 상태와 무관하게 비슷한 행동만 반복하는 경우

  • 보상 설계 때문에 이상한 반복 행동이 강화된 경우

행동 분포는 숫자 하나로 끝나지 않습니다. 상태별 행동 분포까지 보면 더 좋습니다. 예를 들어 Grid World의 각 칸에서 에이전트가 어떤 행동을 주로 선택하는지 화살표로 그려 보면 정책이 한눈에 보입니다. 목적지를 향해 화살표가 자연스럽게 모이면 좋은 정책일 가능성이 큽니다. 반대로 어떤 구역에서 화살표가 빙글빙글 돌고 있다면 그곳이 정책의 약점입니다.

정책을 직접 관찰하자

강화학습 평가에서 가장 강력한 도구 중 하나는 의외로 단순합니다. 직접 보는 것입니다.

숫자는 중요합니다. 평균 보상, 성공률, 표준편차, 에피소드 길이 모두 필요합니다. 하지만 숫자만으로는 에이전트의 행동을 완전히 이해하기 어렵습니다. 특히 보상 해킹이나 이상한 습관은 화면으로 보면 훨씬 빨리 알아차릴 수 있습니다.

Grid World에서는 에이전트가 지나간 경로를 출력해 볼 수 있습니다.

S → → ↓
      ↓
  □ □ ↓
      G

간단한 게임에서는 플레이 영상을 저장할 수 있습니다. CartPole에서는 막대가 어느 순간부터 한쪽으로 치우치는지 확인할 수 있습니다. 로봇 환경이라면 팔이 물체를 잡는 대신 밀어내고 있지는 않은지, 목표를 달성한 것처럼 보이지만 실제로는 불안정한 자세를 취하고 있지는 않은지 살펴봐야 합니다.

정책 관찰은 개발자의 직관을 살려 줍니다. 그래프에서는 평균 보상이 90점으로 보이지만, 실제로 보면 에이전트가 벽에 일부러 부딪힌 뒤 반동처럼 움직이는 이상한 전략을 쓰고 있을 수 있습니다. 숫자는 "성공했다"고 말하지만, 눈은 "이건 우리가 원한 방식이 아니다"라고 말할 수 있습니다.

좋은 강화학습 실험은 로그와 시각화를 함께 남깁니다. 평가 에피소드 몇 개를 저장해 두면, 나중에 성능이 갑자기 좋아지거나 나빠졌을 때 원인을 찾기 쉽습니다.

환경을 조금 바꿔 보기

훈련 환경에서 잘하는 에이전트가 항상 좋은 에이전트는 아닙니다. 진짜 질문은 이것입니다.

조금 다른 상황에서도 잘할까?

강화학습 에이전트는 훈련 환경에 과하게 맞춰질 수 있습니다. 특정 시작 위치, 특정 장애물 배치, 특정 보상 구조에만 익숙해지는 것입니다. 겉으로는 똑똑해 보이지만, 사실은 하나의 시험지만 외운 학생처럼 행동할 수 있습니다.

Grid World에서 항상 같은 시작점과 같은 목적지를 사용했다면, 에이전트는 그 길만 외웠을 수 있습니다. 시작 위치를 한 칸 바꾸면 갑자기 헤맬지도 모릅니다. 장애물을 하나 추가하면 전혀 다른 행동을 할 수도 있습니다.

이것이 일반화 성능입니다. 일반화는 훈련 때 보지 못한 상황에서도 배운 전략을 적용하는 능력입니다. 강화학습에서 일반화는 특히 어렵습니다. 에이전트가 환경과 직접 상호작용하면서 데이터를 모으기 때문에, 훈련 중 경험한 상태 분포에 강하게 묶이기 쉽습니다.

일반화 성능을 확인하려면 평가 환경을 여러 단계로 나눌 수 있습니다.

  • 훈련 환경과 완전히 같은 조건에서 평가한다.

  • 시작 위치나 초기 상태만 바꿔 평가한다.

  • 장애물, 목표 위치, 마찰, 노이즈처럼 일부 조건을 조금 바꿔 평가한다.

  • 훈련 때 보지 못한 새로운 맵이나 난이도에서 평가한다.

처음부터 너무 크게 바꾸면 무엇 때문에 실패했는지 알기 어렵습니다. 작은 변화부터 넣는 것이 좋습니다. 예를 들어 Grid World에서는 시작 위치를 바꾸고, 그다음 장애물 위치를 바꾸고, 그다음 맵 크기를 바꾸는 식으로 진행할 수 있습니다.

중요한 것은 "훈련 점수"와 "테스트 점수"를 따로 기록하는 것입니다.

평가 조건평균 보상성공률평균 길이
훈련과 동일한 맵9.21.008.0
시작 위치 변경8.70.959.1
장애물 위치 변경4.10.4518.3
새로운 맵1.20.1025.0

이 표는 많은 것을 말해 줍니다. 에이전트는 같은 맵에서는 잘하지만, 장애물 위치가 바뀌면 크게 약해집니다. 그렇다면 이 모델은 "목적지를 찾아가는 일반 전략"을 배웠다기보다 "특정 맵의 경로"를 외웠을 가능성이 큽니다.

이 결과가 나쁘다는 뜻은 아닙니다. 오히려 좋은 평가가 문제를 정확히 드러낸 것입니다. 이제 우리는 무엇을 개선해야 하는지 압니다. 더 다양한 맵에서 훈련하거나, 상태 표현을 바꾸거나, 탐험을 늘리거나, 보상 설계를 조정할 수 있습니다.

학습 곡선은 끝이 아니라 시작이다

학습 곡선은 에피소드가 진행되면서 보상이 어떻게 변하는지를 보여 줍니다. 강화학습 실험에서 학습 곡선은 매우 중요합니다. 하지만 그래프를 볼 때는 조심해야 합니다.

보상이 천천히 올라가는 곡선은 학습이 진행되고 있다는 좋은 신호일 수 있습니다. 하지만 곡선이 흔들린다면 불안정한 학습일 수 있습니다. 어느 순간 급격히 올라갔다가 다시 떨어진다면 정책 업데이트가 너무 크거나, 탐험이 줄어들면서 특정 나쁜 습관에 갇혔을 수 있습니다.

학습 곡선을 볼 때는 원본 그래프와 이동 평균을 함께 보는 것이 좋습니다. 이동 평균은 최근 몇 개 에피소드의 평균을 내서 그래프를 부드럽게 만든 값입니다. 원본 그래프는 실제 변동성을 보여 주고, 이동 평균은 전체 추세를 보여 줍니다.

def moving_average(values, window=20):
    result = []
    for i in range(len(values)):
        start = max(0, i - window + 1)
        result.append(sum(values[start:i+1]) / (i - start + 1))
    return result

하지만 학습 곡선이 좋아 보인다고 평가가 끝나는 것은 아닙니다. 학습 곡선은 훈련 과정의 건강 상태를 보여 주는 체온계에 가깝습니다. 체온이 정상이라고 해서 운동 능력, 집중력, 지구력까지 모두 좋다고 말할 수는 없습니다. 마찬가지로 훈련 보상이 올라갔다고 해서 정책이 안정적이고 일반화 가능하다고 말할 수는 없습니다.

학습 곡선은 평가의 출발점입니다. 그다음에는 별도의 평가 에피소드, 여러 시드, 성공률, 실패 유형, 행동 분포, 일반화 테스트가 따라와야 합니다.

평가 지표를 하나의 리포트로 묶기

실험이 조금만 복잡해져도 머릿속으로 결과를 관리하기 어렵습니다. 그래서 평가 지표를 하나의 리포트 형태로 정리하는 습관이 중요합니다.

예를 들어 Grid World 에이전트를 평가한다면 다음처럼 정리할 수 있습니다.

항목값
평가 에피소드 수100
평균 보상8.6
보상 표준편차1.4
성공률0.93
평균 에피소드 길이10.7
최단 에피소드 길이8
최장 에피소드 길이30
timeout 실패5
hole 실패2
행동 분포 최대 편향오른쪽 48%

이런 리포트는 모델을 비교할 때 특히 유용합니다. 알고리즘 A와 B가 있을 때 평균 보상만 비교하면 A가 더 좋아 보일 수 있습니다. 하지만 B가 성공률은 더 높고 실패 분산이 작다면 실제로는 B가 더 안정적인 선택일 수 있습니다.

강화학습에서는 "최고 점수"보다 "신뢰할 수 있는 성능"이 더 중요할 때가 많습니다. 특히 실제 세계와 연결되는 문제에서는 더욱 그렇습니다. 로봇이 열 번 중 아홉 번 물건을 잘 잡아도, 한 번 사람 쪽으로 물건을 던진다면 사용할 수 없습니다. 대화형 AI가 대부분 친절해도, 특정 상황에서 위험한 답변을 반복한다면 좋은 모델이라고 보기 어렵습니다.

평가 리포트는 이런 위험을 드러내기 위한 장치입니다.

좋은 평가 기준은 목표에서 나온다

어떤 지표를 볼지는 문제의 목표에 따라 달라집니다. 모든 강화학습 문제에 완벽하게 맞는 단일 지표는 없습니다.

CartPole에서는 오래 버티는 것이 목표이므로 에피소드 길이와 평균 보상이 중요한 지표가 됩니다. Grid World에서는 목적지 도착 여부와 경로 길이가 중요합니다. 게임 AI에서는 승률, 점수, 플레이 스타일, 난이도별 성능을 함께 봐야 합니다. 로봇 제어에서는 성공률뿐 아니라 움직임의 부드러움, 에너지 사용량, 안전거리 같은 지표도 중요할 수 있습니다.

따라서 평가를 시작하기 전에 먼저 목표를 문장으로 써 보는 것이 좋습니다.

"이 에이전트는 다양한 시작 위치에서 목적지까지 빠르고 안전하게 도착해야 한다."

이 문장에는 이미 평가 지표가 들어 있습니다. "다양한 시작 위치"는 일반화 평가를 뜻합니다. "목적지까지"는 성공률을 뜻합니다. "빠르게"는 에피소드 길이를 뜻합니다. "안전하게"는 위험 상태 방문 횟수나 실패 유형을 뜻합니다.

좋은 평가 기준은 알고리즘에서 시작하지 않습니다. 목표에서 시작합니다. 무엇을 잘해야 하는지 명확히 정해야, 어떤 숫자를 기록해야 하는지도 정해집니다.

평가 중에도 함정은 있다

평가는 모델을 검증하기 위한 과정이지만, 평가 자체도 잘못 설계될 수 있습니다. 대표적인 함정은 평가 환경을 너무 쉽게 만드는 것입니다. 훈련 때와 완전히 같은 조건만 반복하면 모델이 실제로 강한지 알 수 없습니다.

또 다른 함정은 평가 에피소드 수가 너무 적은 것입니다. 강화학습 결과는 흔들릴 수 있으므로, 몇 번의 에피소드만 보고 결론을 내리면 운의 영향을 크게 받습니다. 특히 확률적 정책이나 무작위 초기 상태가 있는 환경에서는 충분한 반복이 필요합니다.

평가 지표를 모델 선택에 너무 많이 사용해도 문제가 생길 수 있습니다. 테스트 환경에서 계속 성능을 확인하고 그 결과에 맞춰 하이퍼파라미터를 조정하다 보면, 결국 테스트 환경도 훈련에 간접적으로 사용한 셈이 됩니다. 머신러닝에서 검증 데이터와 테스트 데이터를 구분하듯이, 강화학습에서도 최종 평가용 환경은 가능하면 마지막까지 아껴 두는 것이 좋습니다.

정리하면 평가에서 조심해야 할 함정은 다음과 같습니다.

  • 너무 적은 에피소드만 평가하고 결론을 내리는 것

  • 한 개의 랜덤 시드 결과만 보고 알고리즘을 판단하는 것

  • 훈련 중 탐험이 섞인 보상을 최종 성능으로 착각하는 것

  • 평균 보상만 보고 실패 유형이나 분산을 무시하는 것

  • 테스트 환경에 맞춰 반복적으로 모델을 조정하는 것

이 함정들을 피하면 평가 결과를 훨씬 더 믿을 수 있습니다.

강화학습 모델 평가 체크리스트

마지막으로 강화학습 모델을 평가할 때 사용할 수 있는 체크리스트를 정리해 봅시다.

  • 훈련 보상과 평가 보상을 분리했는가?

  • 평가 중에는 학습 업데이트를 멈췄는가?

  • 탐험률이나 행동 샘플링 방식을 평가 목적에 맞게 설정했는가?

  • 충분한 수의 평가 에피소드를 실행했는가?

  • 평균 보상뿐 아니라 표준편차, 최솟값, 최댓값을 확인했는가?

  • 여러 랜덤 시드에서 반복 실험했는가?

  • 성공률과 실패 유형을 따로 기록했는가?

  • 에피소드 길이와 행동 분포를 함께 살펴보았는가?

  • 정책의 실제 행동을 시각적으로 관찰했는가?

  • 시작 상태나 환경 조건을 바꿔 일반화 성능을 확인했는가?

이 체크리스트를 모두 만족한다고 해서 완벽한 평가가 되는 것은 아닙니다. 하지만 적어도 "보상이 올라갔으니 성공"이라는 성급한 결론에서는 벗어날 수 있습니다.

평가를 잘해야 다음 학습이 보인다

강화학습은 행동을 배우는 기술입니다. 하지만 행동은 숫자 하나로 다 설명되지 않습니다. 같은 보상을 얻더라도 어떤 경로로 얻었는지, 얼마나 안정적으로 얻었는지, 어떤 상황에서 실패하는지, 환경이 바뀌어도 버티는지까지 봐야 합니다.

이번 장에서 우리는 강화학습 모델을 평가하는 여러 관점을 살펴보았습니다. 훈련 보상과 평가 보상을 분리했고, 여러 랜덤 시드로 반복 실험하는 이유를 배웠습니다. 평균 보상뿐 아니라 성공률, 실패 유형, 에피소드 길이, 행동 분포를 함께 기록해야 한다는 것도 확인했습니다. 마지막으로 환경을 조금 바꿔 보며 일반화 성능을 점검하는 방법까지 살펴보았습니다.

이제 실습 파트는 여기서 한 번 매듭을 짓습니다. 우리는 작은 Grid World에서 출발해 Q-learning으로 길을 찾고, CartPole과 간단한 게임 에이전트를 거쳐 보상 설계와 평가까지 경험했습니다.

다음부터는 이 흐름을 언어 모델로 가져갑니다. 언어 모델은 격자 위를 움직이지 않습니다. 막대를 세우지도 않습니다. 대신 단어를 선택하고 문장을 만듭니다. 그렇다면 언어 모델에서 상태는 무엇이고, 행동은 무엇이며, 보상은 어떻게 줄 수 있을까요?

이 질문이 바로 LLM과 강화학습, 그리고 RLHF로 이어지는 문입니다.

책 목록

처음 만나는 강화학습: 보상으로 행동을 배우는 AI

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기