강화학습에서 사용하는 MDP의 목적은 보상을 최대한 많이 얻는 최적의 행동 방법, 즉 최적정책(π*)을 찾는 것이다. 정책이란 말은 어떤 상태에서 어떤 행동을 선택할지를 정하는 기준을 뜻하며, 좋은 정책일수록 행동을 잘 선택해서 많은 보상을 받을 수 있다.
이때 정책이 얼마나 좋은지를 평가하기 위해 필요한 것이 바로 가치함수(Value Function)이다. 가치함수는 어떤 정책을 따랐을 때 얼마나 많은 보상을 기대할 수 있는지를 수치로 알려주는 함수이다.
가치함수는 크게 두 가지가 있다. 하나는 상태가치함수 v(s)이고, 다른 하나는 행동가치함수 q(s, a)이다.
상태가치함수는 특정 상태에 도착했을 때, 정책에 따라 행동해 나가면 앞으로 얼마나 많은 보상을 받을 수 있는지를 계산한다. 반면 행동가치함수는 상태만 아니라, 지금 어떤 행동을 했을 때 앞으로 받을 수 있는 보상의 총합을 계산한다. 이렇게 행동까지 포함하는 가치함수는, 어떤 행동이 실제로 얼마나 좋은지를 더 구체적으로 평가할 수 있게 도와준다.
여기에서 한 걸음 더 나아간 것이 바로 최적가치함수(Optimal Value Function)이다. 최적가치함수란, 가능한 모든 정책들 중에서 가장 보상을 많이 주는 정책을 따랐을 때 나오는 가치함수이다.
최적상태가치함수와 최적행동가치함수
(1) 최적상태가치함수 v*(s)는 상태 s에서 출발했을 때, 가장 좋은 정책을 따랐을 때 받을 수 있는 최대 기대 보상을 의미한다. (2) 최적행동가치함수 q*(s, a)는 상태 s에서 어떤 행동 a를 했을 때, 그 이후 가장 좋은 정책을 계속 따랐을 경우 얻을 수 있는 최대 보상이다.
v*(s)와 q*(s, a)는 서로 연결되어 있다. 어떤 상태에서 가능한 모든 행동에 대해 q*(s, a) 값을 계산해 보고, 그 중 가장 큰 값을 고르면 그게 v*(s)가 된다. 즉, 상태가치함수는 가장 좋은 행동의 가치를 고른 결과이다.
최적정책의 다양한 특성
이제까지 상태가치함수와 행동가치함수, 그리고 최적가치함수에 대해 살펴봤다면, 이제 우리는 자연스럽게 최적정책(π*)이라는 개념을 이해할 수 있게 된다.
최적정책(π*)이란, 말 그대로 가장 보상을 많이 받을 수 있게 해주는 행동 선택 방식이다. 에이전트가 이 정책을 따르게 되면, 어떤 상태에 있든지 항상 최적의 행동만을 선택하게 된다.
최적정책은 다음과 같은 특징을 가진다:
(1) 최적정책은 다른 어떤 정책보다 항상 더 높은 가치를 만든다. 즉, 어떤 정책 π와 비교해도 π*가 주는 보상이 더 크다는 뜻이다.
(2) 최적정책을 사용해서 계산한 상태가치함수는 최적상태가치함수와 같다. 다시 말해, 상태 s에서 π*를 따를 때의 기대 보상은 곧 v*(s)이다.
(3) 최적정책을 사용해서 계산한 행동가치함수는 최적행동가치함수와 같다. 즉, 상태 s에서 행동 a를 했을 때, 이후 π*를 따를 경우 기대되는 보상은 q*(s, a)가 된다.
최적정책을 나타내는 하나의 방법
MDP에서 최적정책을 표현하는 방법 중 하나는 가장 가치 있는 행동만을 선택하도록 만드는 방식이다.
어떤 상태 s에서 여러 행동 a들 중에서 q*(s, a) 즉, 최적행동가치함수의 값이 가장 큰 행동을 먼저 찾는다. 그리고 그 행동 하나만을 확률 1로 선택하고, 나머지 행동은 확률 0으로 설정한다.
정책은 결국 확률적인 선택 규칙이기 때문에 확률이 1이라는 것은 "무조건 이 행동만 한다"는 뜻이고, 확률이 0이라는 것은 "이 행동은 절대 하지 않는다"는 뜻이다.
결과적으로 이 정책은 각 상태에서 가장 좋은 행동 하나만 고르게 만들고, 항상 그 행동만을 수행하게 된다.
이렇게 정의된 정책이 바로 결정적 최적정책(deterministic optimal policy)이라고 할 수 있다. 복잡하게 생각할 필요 없이, "항상 가장 보상이 큰 행동만 한다"*는 아주 단순한 전략이다.
이처럼 최적정책은 가치 측면에서 항상 최고이고, 그 정책을 따르기 만하면 보상을 가장 많이 받을 수 있게 된다.
정리하자면, 다음과 같다.
- 상태가치함수는 상태의 ‘좋음’을 평가하고,
- 행동가치함수는 행동의 ‘효율’을 평가하며,
- 최적가치함수는 보상이 가장 큰 정책을 따랐을 때의 기대 값이고,
- 최적정책은 그 최적가치함수를 만드는 행동만을 선택하는 방식이다.
이것이 MDP의 핵심이자, 강화학습이 목표로 하는 최종 개념이다.
여기서 잠깐 〮 수학기호 ∀와 argmax 수학기호 ∀는 임의의 또는 전체의 의미를 가지고 있다. ∀π란 모든 정책에 대해 해당한다는 의미를 가지고 있다. argmax함수(x)는 조건을 만족하는 함수의 값을 가장 크게 만드는 x를 찾는 것이다. 예를 들어 argmax sin(x), 0 ≤ x ≤ 2π의 경우 sin값을 최대로 하는 x값인 0.5π가 된다. |
최적가치함수의 이해를 돕기 위해 예제를 살펴보자.
import numpy as np
# (1) 상태와 행동 정의
states = ["S", "R1", "R2", "R3", "F"]
actions = ["A1", "A2"]
gamma = 0.5 # 감가율
# (2) 정책 π(s, a): 상태에서 행동을 선택할 확률
policy = {
"S": {"A1": 0.6, "A2": 0.4},
"R1": {"A1": 0.7, "A2": 0.3},
"R2": {"A1": 1.0},
"R3": {"A1": 1.0}
}
# (3) 상태 전이 확률 P(s, a, s')
transition_probs = {
("S", "A1"): "R1",
("S", "A2"): "R2",
("R1", "A1"): "R3",
("R1", "A2"): "R2",
("R2", "A1"): "R3",
("R3", "A1"): "F"
}
# (4) 보상 함수 R(s, a)
rewards = {
("S", "A1"): 0.5,
("S", "A2"): 1.5,
("R1", "A1"): 1.0,
("R1", "A2"): 1.5,
("R2", "A1"): 2.0,
("R3", "A1"): 3.0
}
# (5) 에피소드 시뮬레이션 함수 (정책 기반 경로)
def simulate_episode(start_state="S"):
state = start_state
total_return = 0
discount = 1.0
while state != "F":
action_probs = policy[state]
actions_list = list(action_probs.keys())
probs = list(action_probs.values())
action = np.random.choice(actions_list, p=probs)
reward = rewards.get((state, action), 0)
total_return += discount * reward
next_state = transition_probs.get((state, action), "F")
state = next_state
discount *= gamma
return total_return
n_episodes = 10000
state_values = {}
q_values = {}
# (6) 상태가치함수 계산
for state in states:
episode_returns = []
for _ in range(n_episodes):
result = simulate_episode(start_state=state)
episode_returns.append(result)
state_values[state] = np.mean(episode_returns)
# (7) 행동가치함수 계산
for state in policy:
for action in policy[state]:
returns = []
for _ in range(n_episodes):
temp_state = state
total_return = 0
discount = 1.0
reward = rewards.get((temp_state, action), 0)
total_return += discount * reward
next_state = transition_probs.get((temp_state, action), "F")
temp_state = next_state
discount *= gamma
while temp_state != "F":
action_probs = policy[temp_state]
actions_list = list(action_probs.keys())
probs = list(action_probs.values())
next_action = np.random.choice(actions_list, p=probs)
reward = rewards.get((temp_state, next_action), 0)
total_return += discount * reward
temp_state = transition_probs.get((temp_state, next_action), "F")
discount *= gamma
returns.append(total_return)
q_values[(state, action)] = np.mean(returns)
# (8) 결과 출력
print("\n✅ 상태가치함수 Vπ(s):")
for s, v in state_values.items():
print(f" {s}: {v:.4f}")
print("\n✅ 행동가치함수 Qπ(s,a):")
for (s, a), q in q_values.items():
print(f" ({s}, {a}): {q:.4f}")
# (9) 최적정책 계산 (가장 Q값이 높은 행동만 선택)
optimal_policy = {}
for state in policy:
best_action = None
best_q_value = float("-inf")
# 가능한 모든 행동에 대해 Q값을 비교해서 가장 큰 것 선택
for action in policy[state]:
q = q_values.get((state, action), float("-inf"))
if q > best_q_value:
best_q_value = q
best_action = action
# 최적정책: 가장 좋은 행동만 확률 1로 설정
action_probabilities = {}
for action in policy[state]:
if action == best_action:
action_probabilities[action] = 1.0
else:
action_probabilities[action] = 0.0
optimal_policy[state] = action_probabilities
# (10) 최적정책 출력
print("\n🌟 최적정책 π*(s):")
for state in optimal_policy:
for action, prob in optimal_policy[state].items():
if prob == 1.0:
print(f" 상태 {state} → 최적 행동: {action}")
✅ 상태가치함수 Vπ(s):
S: 2.4114
R1: 2.7238
R2: 3.5000
R3: 3.0000
F: 0.0000
✅ 행동가치함수 Qπ(s,a):
(S, A1): 1.8616
(S, A2): 3.2500
(R1, A1): 2.5000
(R1, A2): 3.2500
(R2, A1): 3.5000
(R3, A1): 3.0000
🌟 최적정책 π*(s):
상태 S → 최적 행동: A2
상태 R1 → 최적 행동: A2
상태 R2 → 최적 행동: A1
상태 R3 → 최적 행동: A1
마르코프 결정과정 최적가치함수
(9) 최적정책 계산 단계에서는 앞에서 구한 행동가치함수(Qπ(s, a))를 기반으로 각 상태별로 가장 좋은 행동만을 선택하는 최적정책(π*)을 만들어낸다.
그 과정은 다음과 같이 이루어진다:
- 각 상태 s에 대해 가능한 모든 행동 a의 Q값을 비교한다.
- Q값이 가장 높은 행동을 하나 선택한다. 이 행동은 “현재 상태에서 가장 많은 보상을 기대할 수 있는 행동”이다.
- 정책을 확률로 표현해야 하므로, 가장 좋은 행동에 대한 확률은 1.0으로 설정하고, 나머지 행동에 대해서는 확률을 0.0으로 설정한다.
이렇게 만들어진 정책은 결정적 정책(deterministic policy)으로, 각 상태에서 항상 최적의 행동 하나만을 선택하게 만든다.
결과적으로 이 과정은 “각 상태에서 어떤 행동을 해야 보상을 가장 많이 받을 수 있을까?”에 대한 가장 직접적이고 명확한 해답을 제공한다.
(10) 최적정책 출력 단계에서는 앞에서 계산한 최적정책(π*)을 사용자에게 보기 쉽게 출력한다.
각 상태마다 최적정책은 확률이 1인 행동 하나만을 포함하고 있다. 즉, 최적정책은 “이 상태에서는 반드시 이 행동을 해야 한다”고 알려주는 결정적 지침을 담고 있다.
출력 과정은 다음과 같다:
- 각 상태 s에 대해 정책에 저장된 행동 중, 확률이 1.0인 행동을 찾아낸다.
→ 이 행동이 바로 최적정책이 추천하는 최적의 선택이다. - 출력 형식은 다음과 같은 방식으로 보여준다:
- 상태 S → 최적 행동: A2
- 상태 R1 → 최적 행동: A1
이 결과를 통해 사용자는 어떤 상태에서 가장 효율적인 행동이 무엇인지를 한눈에 확인할 수 있다. 강화학습의 핵심 목표인 “좋은 정책을 찾기”가 실제로 어떤 행동 선택으로 이어지는지를 직관적으로 이해할 수 있도록 도와주는 마무리 단계라 할 수 있다.