[강화학습] 벨만 기대 방정식 (Bellman Expectation Equation)

2026. 2. 27. 10:55·개념 정리 step2/강화 학습

1. 벨만 기대 방정식 (Bellman Expectation Equation)

벨만 기대 방정식은 어떤 상태의 가치(Value)가 “현재 받을 보상”과 “다음 상태의 가치의 기대값”으로 표현된다는 관계식입니다.

즉, 지금 이 상태가 얼마나 좋은지는 단순히 현재 보상만으로 결정되는 것이 아니라, 현재 보상 + (정책에 따라 도달할 다음 상태들의 가치의 평균)으로 재귀적으로 정의된다는 의미입니다. 여기서 ‘기대(expectation)’라는 말은, 다음 상태가 확률적으로 결정되기 때문에 그 확률을 고려한 평균값을 사용한다는 뜻입니다.

 

쉽게 말해, 벨만 기대 방정식은 “현재 가치 = 지금 얻는 것 + 미래 가치의 평균”이라는 강화학습의 기본 원리를 수학적으로 표현한 식입니다.

$$V(s) = R + \gamma V(s')$$

1-1 현재만 보기

지금 받는 보상만 고려한 상태입니다.

$$V(s) \approx R$$

1-2 한 번, 두 번 확장

다음 보상, 다다음 보상까지 할인율($\gamma$)을 적용해서 더해나갑니다.

$$V(s) = R + \gamma R'$$
$$V(s) = R + \gamma R' + \gamma^2 R''$$

1-3 무한 확장

이걸 무한히 확장하여 한 줄로 줄인 것이 바로 벨만 기대 방정식입니다.

$$V(s) = R + \gamma R' + \gamma^2 R'' + \gamma^3 R''' + \cdots$$

2. 현실 MDP(Markov Decision Process)에 적용

현실의 강화학습 문제에서는 다음 요소들이 복합적으로 작용합니다.

  • 행동이 여러 개 존재함
  • 다음 상태가 확률적으로 여러 개 나옴
  • 정책에 따라 행동 확률이 달라짐
  • 보상도 확률적임

현재 가치 = (행동 확률 평균) $\times$ (전이 확률 평균) $\times$ (보상 + 감마 $\times$ 다음 가치)

 

이 식은 사실 아래 4가지를 차례대로 평균 내는 구조입니다.

  1. $\sum_a \pi(a|s)$ : 상태에서 정책이 고르는 행동들의 평균(기대값)
  2. $\sum_{s'} P(s'|s,a)$ : 그 행동을 했을 때 나올 수 있는 다음 상태들의 평균(기대값)
  3. $R(s,a,s')$ : 그 전이에서 받는 즉시 보상
  4. $\gamma V_\pi(s')$ : 다음 상태 가치의 할인된 미래 부분

이를 수식으로 완벽하게 조립하면 다음과 같습니다.

$$V_\pi(s) = \sum_{a} \pi(a|s) \sum_{s'} P(s'|s,a) \left[ R(s,a,s') + \gamma V_\pi(s') \right]$$

💡 핵심 요약:
상태 $s$에서 정책대로 움직일 때, (지금 보상 + 할인된 다음 상태 가치)의 평균이 바로 상태 가치 함수 $V_\pi(s)$가 됩니다.


3. 술취한 사람 문제 (1D Random Walk)

술취한 사람 문제는 강화학습이나 마르코프 과정에서 아주 자주 나오는 대표적인 예제입니다. 길 위에 서 있는 사람이 술에 취해 원하는 방향으로 정확히 가지 못하고 확률적으로 비틀거리며 이동한다고 가정합니다.

이 문제를 통해 “지금 이 위치가 안전한가?”, “이 위치에서 앞으로 좋은 결과를 얻을 가능성이 얼마나 되는가?”를 계산해 볼 수 있습니다. 현재 위치를 상태(State)로 보고, 다음 위치로 이동하는 확률을 상태 전이 확률로 표현하면 벨만 기대 방정식을 적용할 수 있습니다.

3-1 1차원 길 환경

[집(Home)] --- A --- B --- C --- [술집(Bar)]
  • 맨 왼쪽 집(Home): 도착하면 좋은 상태
  • 맨 오른쪽 술집(Bar): 도착하면 좋지 않은 상태
  • 중간 상태: A, B, C
  • 술취한 사람은 현재 위치에서 왼쪽 또는 오른쪽으로 움직이지만, 확률적으로 움직입니다.

3-2 상태(State) 정의

상태 공간(State Space)에는 5가지 상태가 들어있습니다.

$$S = \{Home, A, B, C, Bar\}$$
  • Home, Bar는 도달하면 끝나는 **종료 상태(Terminal State)**입니다.

3-3 전이 확률 (Transition Probability)

중간 상태에서는 다음과 같이 좌우 50% 확률로 한 칸씩 이동합니다.

  • A에서: 50% 확률로 Home, 50% 확률로 B
  • B에서: 50% 확률로 A, 50% 확률로 C
  • C에서: 50% 확률로 B, 50% 확률로 Bar

3-4 보상(Reward) 설정

  • Home에 도착하면 +1 (좋은 결과)
  • Bar에 도착하면 -1 (나쁜 결과)
  • 그 외 중간 이동은 0 (특별한 즉시 보상 없음)

3-5 각 상태의 의미 (가치 함수)

  • A의 가치가 높다면 $\rightarrow$ 집에 갈 가능성이 높고 좋은 상태
  • C의 가치가 낮다면 $\rightarrow$ 술집으로 갈 가능성이 높고 나쁜 상태
  • B는 $\rightarrow$ 중간 정도

💡 가치(Value)란? “그 상태에서 시작했을 때 앞으로 얼마나 좋은 결과를 기대할 수 있는가?” 를 나타내는 점수입니다.

3-6 벨만 기대 방정식 적용

  • 할인율 $\gamma = 1$로 설정 (미래 보상을 감가 없이 그대로 다 반영하겠다는 뜻)
  • $$V(s) = \text{즉시 보상} + 1 \times \text{다음 상태 가치의 기대값}$$

3-7 종료 상태의 가치

$$V(Home) = 1$$
$$V(Bar) = -1$$

3-8 수식으로 푸는 상태 가치 업데이트

각 상태의 가치는 이웃한 상태들의 가치 평균으로 수렴합니다.

  • $V(A) = 0.5 \times V(Home) + 0.5 \times V(B)$
  • $V(B) = 0.5 \times V(A) + 0.5 \times V(C)$
  • $V(C) = 0.5 \times V(B) + 0.5 \times V(Bar)$

계산 결과, 각 상태의 점수는 위치의 좋고 나쁨을 직관적으로 보여줍니다.

  • A = 0.5 (집에 가까워 비교적 좋은 상태)
  • B = 0 (집과 술집의 딱 가운데 위치하는 중립적인 상태)
  • C = -0.5 (술집에 가까워 좋지 않은 상태)
Home(+1) --- A(+0.5) --- B(0) --- C(-0.5) --- Bar(-1)

실습 코드

[코드 1] 가치 반복(Value Iteration)으로 풀기

초기 가치를 0으로 놓고, 방정식을 여러 번 반복(Iteration)하여 값을 업데이트하는 방식입니다.

V = {
    "Home": 1.0,
    "A": 0.0,
    "B": 0.0,
    "C": 0.0,
    "Bar": -1.0
}
iterations = 10

for i in range(1, iterations + 1):
    u_V = V.copy()
    u_V["A"] = 0.5 * V["Home"] + 0.5 * V["B"]
    u_V["B"] = 0.5 * V["A"] + 0.5 * V["C"]
    u_V["C"] = 0.5 * V["B"] + 0.5 * V["Bar"]
    V = u_V
    print(f"{i:d}회 반복 -> A={V['A']:.4f}, B={V['B']:.4f}, C={V['C']:.4f}")

for state, value in V.items():
    print(f'{state}: {value:.4f}')

[코드 2] 몬테카를로 시뮬레이션으로 풀기 (재귀 구조)

무작위로 좌우로 이동하는 시뮬레이션을 수만 번 반복하여 평균 보상을 계산합니다.

import random

def run(start_state):
    while True:
        if start_state == "Home":
            return 1
        elif start_state == "Bar":
            return -1
            
        move = random.choice(['left', 'right'])
        
        if start_state == "A":
            start_state = "Home" if move == "left" else "B"
        elif start_state == "B":
            start_state = "A" if move == "left" else "C"
        elif start_state == "C":
            start_state = "B" if move == "left" else "Bar"

def estimate_value(start_state, n=10000):
    total = 0
    for i in range(n):
        total += run(start_state)
    return total / n

print(f"A ≈ {estimate_value('A'):.4f}")
print(f"B ≈ {estimate_value('B'):.4f}")
print(f"C ≈ {estimate_value('C'):.4f}")

[코드 3] 몬테카를로 시뮬레이션 (반복문 구조)

import random

episodes = 100000
total_reward = 0

for _ in range(episodes):
    state = "A"

    while state not in ["Home", "Bar"]:
        if state == "A":
            state = random.choice(["Home", "B"])
        elif state == "B":
            state = random.choice(["A", "C"])
        elif state == "C":
            state = random.choice(["B", "Bar"])

    if state == "Home":
        total_reward += 1
    elif state == "Bar":
        total_reward -= 1

average_reward = total_reward / episodes
print(f"A에서 시작 시 평균 보상: {average_reward:.4f}")

5x5 격자 술취한 사람 문제 (2D Grid World)

이번에는 1차원 선상이 아니라 5x5 2차원 격자 위에서 술취한 사람이 비틀거리는 환경입니다.

+-----+-----+-----+-----+-----+
|  H  |  A  |  B  |  C  | BAR |
+-----+-----+-----+-----+-----+
|  D  |  E  |  F  |  G  |  I  |
+-----+-----+-----+-----+-----+
|  J  |  K  |  L  |  M  |  N  |
+-----+-----+-----+-----+-----+
|  O  |  P  |  Q  |  R  |  S  |
+-----+-----+-----+-----+-----+
|  T  |  U  |  V  |  W  |  X  |
+-----+-----+-----+-----+-----+

상태 및 보상 정의

  • H (Home): (0, 0) 위치. 도착 시 보상 +1 (종료 상태)
  • BAR (술집): (0, 4) 위치. 도착 시 보상 -1 (종료 상태)
  • 나머지 (일반 상태): 이동 시 보상 0

4-2 이동 규칙

  • 술취한 사람은 위, 아래, 왼쪽, 오른쪽 4방향으로 각각 25% 확률로 이동하려 합니다.
  • 격자 밖으로 벗어나려고 하면 이동하지 않고 제자리를 유지합니다.
  • 할인율 $\gamma = 1.0$을 사용하여 각 상태의 가치 $V(s)$를 구합니다.

[코드 4] 5x5 환경의 상태 가치 반복 (Value Iteration)

SIZE = 5
GAMMA = 1.0
ITERATIONS = 30
HOME = (0, 0)
BAR = (0, 4)
DIRECTIONS = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 상, 하, 좌, 우

def is_terminal(state):
    return state == HOME or state == BAR

def move(state, direction):
    r, c = state
    dr, dc = direction
    nr, nc = r + dr, c + dc
    # 격자 밖으로 나가면 제자리 유지
    if nr < 0 or nr >= SIZE or nc < 0 or nc >= SIZE:
        return state
    return (nr, nc)

def get_reward(next_state):
    if next_state == HOME:
        return 1.0
    elif next_state == BAR:
        return -1.0
    else:
        return 0.0

def print_grid(values, title=""):
    if title:
        print(f'\n{title}')
    for r in range(SIZE):
        row = []
        for c in range(SIZE):
            state = (r, c)
            if state == HOME:
                row.append(" HOME ")
            elif state == BAR:
                row.append(" BAR  ")
            else:
                row.append(f"{values[r][c]:6.2f}")
        print(" | ".join(row))
    print()

def value_iteration():
    V = [[0.0 for _ in range(SIZE)] for _ in range(SIZE)]

    # 종료 상태 가치 고정
    V[HOME[0]][HOME[1]] = 1.0
    V[BAR[0]][BAR[1]] = -1.0

    print_grid(V, title="초기 상태 가치")

    for iteration in range(1, ITERATIONS + 1):
        new_V = [[V[r][c] for c in range(SIZE)] for r in range(SIZE)]

        for r in range(SIZE):
            for c in range(SIZE):
                state = (r, c)

                # 종료 상태는 업데이트 안 함
                if is_terminal(state):
                    continue

                value = 0.0

                # 4방향(각 25% 확률)에 대한 기대값 계산
                for direction in DIRECTIONS:
                    next_state = move(state, direction)
                    reward = get_reward(next_state)
                    nr, nc = next_state
                    value += 0.25 * (reward + GAMMA * V[nr][nc])

                new_V[r][c] = value

        V = new_V

        if iteration in [1, 2, 5, 10, 20, 30]:
            print_grid(V, title=f"{iteration}회 반복 후 상태 가치")

    return V

if __name__ == "__main__":
    final_V = value_iteration()
    print_grid(final_V, title='최종 상태 가치')

[코드 5] 5x5 환경의 몬테카를로 시뮬레이션

import random

# 상, 하, 좌, 우
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]

episodes = 100000
total_reward = 0

for _ in range(episodes):
    # 시작 지점 (0, 1) 즉 'A' 위치
    y, x = 0, 1

    # 도착지에 도달할 때까지 반복
    while (y, x) not in [(0, 0), (0, 4)]:
        d = random.randint(0, 3)
        ny = y + dy[d]
        nx = x + dx[d]

        # 격자 내부에 있을 때만 이동 (벗어나면 무시하고 다음 루프에서 제자리 취급 효과)
        if 0 <= ny <= 4 and 0 <= nx <= 4:
            y, x = ny, nx

    if (y, x) == (0, 0):
        total_reward += 1
    elif (y, x) == (0, 4):
        total_reward -= 1

average_reward = total_reward / episodes
print(f"(0, 1)에서 시작 시 평균 보상: {average_reward:.4f}")

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

[강화학습] Deep Reinforcement Learning 개념  (0) 2026.03.03
[강화학습] TD Learning (시간차 학습) 개념, 랜덤 벽 GridWorld 실습  (0) 2026.03.01
[강화학습] Monte Carlo Learning 정리  (0) 2026.02.28
[강화학습] 마르코프 결정 과정 MDP 정리 (MP, MRP, MDP)  (0) 2026.02.26
[강화학습] 강화학습 기본 개념 정리  (0) 2026.02.21
'개념 정리 step2/강화 학습' 카테고리의 다른 글
  • [강화학습] TD Learning (시간차 학습) 개념, 랜덤 벽 GridWorld 실습
  • [강화학습] Monte Carlo Learning 정리
  • [강화학습] 마르코프 결정 과정 MDP 정리 (MP, MRP, MDP)
  • [강화학습] 강화학습 기본 개념 정리
고니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
  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[강화학습] 벨만 기대 방정식 (Bellman Expectation Equation)
상단으로

티스토리툴바