📘 2장 이론: 상태가치와 벨만 방정식
❓ 에이전트는 어떻게 보상을 최대화하는 행동을 학습할까?
에이전트는 각 상태 또는 상태에서 가능한 행동들의 가치를 수치화한 후, 그 중 가장 가치가 높은 선택지를 고르는 방식으로 학습한다.
즉, 상태가치(state-value) 또는 행동가치(action-value)를 기준으로 행동을 결정한다.
📊 상태가치와 행동가치 (그림 2.19)
- 그림 2.19a는 각 상태의 상태가치(V)를 나타낸다.
- 도착지점에 가까울수록 상태가치가 높다.
- 에이전트는 어디서든 가치가 높은 이웃 상태를 따라 이동하게 된다.
- 그림 2.19b는 각 상태에서 선택할 수 있는 행동들의 가치(Q)를 보여준다.
- 에이전트는 각 상태에서 행동가치가 가장 높은 행동을 선택해 도착지점에 도달한다.
이처럼 강화학습은 수익 G를 기준으로 상태나 행동의 가치를 수치화하여 학습을 수행한다.
🔍 상태가치함수 ( V_π(s) )
어떤 정책 π를 따를 때, 상태 s에서 얻을 수 있는 기대 수익 G를 상태가치 V_π(s)라 한다.
V_π(s) = E_π[G_t | S_t = s] # 식 2.5
여기서 수익 G_t는 다음과 같이 정의된다:
G_t = r_{t+1} + γr_{t+2} + γ²r_{t+3} + … # 할인된 보상의 합
따라서 식 2.5에 G_t를 대입하면 다음과 같이 된다:
V_π(s) = E_π[r_{t+1} + γr_{t+2} + γ²r_{t+3} + ... | S_t = s] # 식 2.6
→ 그림 2.20은 이 식의 구조를 시각적으로 표현한 것이다.
🔁 식 2.6의 정리: 벨만 기대 방정식 (식 2.7)
식 2.6에서 보상 항에서 r_{t+1} 이후의 식을 다음과 같이 묶어보면,
γr_{t+2} + γ²r_{t+3} + γ³r_{t+4} + …
= γ(r_{t+2} + γr_{t+3} + γ²r_{t+4} + …)
= γG_{t+1} = γV_π(s_{t+1})
따라서 상태가치는 다음과 같이 표현된다:
V_π(s) = E_π[r_{t+1} + γV_π(s_{t+1}) | S_t = s] # 식 2.7
이 식은 현재 상태의 가치가 즉시 보상과 다음 상태의 가치로 계산됨을 보여준다.
→ 이를 벨만 방정식(Bellman equation)이라고 한다.
🎯 강화학습은 결국 이 벨만 방정식을 반복적으로 풀어 최적의 상태가치를 찾는 과정이다.
🧭 다양한 행동이 가능한 환경: 식 2.8
지금까지는 다음 상태가 하나라고 가정했지만, 실제로는 하나의 상태에서 여러 행동이 가능하다. 예를 들어, 미로에서 상태 s7
에서 상하좌우로 이동할 수 있는 경우 다음과 같은 4개의 상태로 전이된다:
s7 → s4 (위), s8 (오른쪽), cliff (아래), s6 (왼쪽)
이를 반영한 상태가치 계산식은 다음과 같다:
V_π(s7) = π(a1|s7) * P(s4|s7,a1) * [r(s7,a1,s4) + γV_π(s4)]
+ π(a2|s7) * P(s8|s7,a2) * [r(s7,a2,s8) + γV_π(s8)]
+ π(a3|s7) * P(cliff|s7,a3) * [r(s7,a3,cliff) + γV_π(cliff)]
+ π(a4|s7) * P(s6|s7,a4) * [r(s7,a4,s6) + γV_π(s6)] # 식 2.8
- π(a|s): 정책 π가 상태 s에서 행동 a를 선택할 확률
- P(s'|s,a): 상태 s에서 행동 a를 했을 때 상태 s'로 전이될 확률
- r(s,a,s'): 그에 대한 보상
📌 이 식은 식 2.7의 기댓값을 명시적으로 풀어 쓴 형태이다.
📐 일반화된 상태가치 계산식 (식 2.9)
식 2.8을 일반화하면 다음과 같다:
V_π(s) = ∑_a π(a|s) ∑_{s'} P(s'|s,a) [r(s,a,s') + γV_π(s')] # 식 2.9
모든 가능한 행동과 그 행동의 결과로 도달할 상태를 고려한 기대 상태가치 계산 공식이다.
🔁 식 2.10: 상태가치 계산의 통합 표현
앞서 소개한 식들을 통합하면 다음과 같이 정리할 수 있다:
V_π(s) = E_π[G_t | S_t = s]
= E_π[r_{t+1} + γG_{t+1} | S_t = s]
= E_π[r_{t+1} + γV_π(s_{t+1}) | S_t = s]
= ∑_a π(a|s) ∑_{s'} P(s'|s,a) [r(s,a,s') + γV_π(s')] # 식 2.10
→ 식 2.10은 확률적 환경에서도 일반적으로 사용할 수 있는 상태가치 계산식이다.
⚙️ 결정론적 환경에서의 단순화
이 책에서는 결정론적 환경을 전제로 한다.
즉, 어떤 행동 a를 선택하면 항상 하나의 상태 s′로 이동하며, P(s′|s,a) = 1
이다.
따라서 식 2.10은 다음과 같이 간략화된다:
V_π(s) = ∑_a π(a|s) [r(s,a,s') + γV_π(s')] # 상태 전이 확률 생략
📌 백업 다이어그램 (그림 2.24)
그림 2.24는 결정론적 환경과 확률적 환경에서 상태가치가 어떻게 계산되는지를 시각적으로 보여주는 상태가치 백업 다이어그램이다.
- 상태 → 행동 → 다음 상태 → 보상 및 가치
- 이를 통해 벨만 방정식이 실제로 어떻게 계산되는지를 직관적으로 이해할 수 있다.
🧮 2장 코드 구현: 상태가치 함수 구현과 시각화
🔧 상태가치 계산 개요
강화학습에서 상태가치 V_π(s)는 정책 π를 따를 때, 상태 s에서 얻을 수 있는 기대 수익이다. 하지만 실제 구현에서는 다음 상태를 어디까지 참고할 것인가를 정해야 한다.
- 만약 가능한 모든 다음 상태를 무한히 탐색한다면 계산이 끝나지 않는다.
- 따라서 프로그램에서는 max_step이라는 변수로 얼마나 먼 미래까지의 상태를 참고할지를 제한한다.
- max_step = 0: 현재 상태와 다음 상태까지만 고려
- max_step = 3: 현재 상태부터 최대 3단계 뒤 상태까지 고려
📌 now_step은 현재 얼마나 진행되었는지를 추적하며, now_step == max_step이거나 도착지점(goal)에 도달하면 재귀를 종료한다.
🔁 상태가치 함수 구현: state_value_function()
# 상태 가치 계산
def state_value_function(env, agent, G, max_step, now_step):
# 1. 감가율 설정
gamma = 0.9
# 2. 현재 위치가 도착 지점인지 확인
if env.reward_list1[agent.pos[0]][agent.pos[1]] == "goal":
return env.goal # 도착지점이면 보상 1 반환, 재귀 종료
# 3. 마지막 상태는 보상만 계산
if max_step == now_step:
pos1 = agent.get_pos()
# 3.1 가능한 모든 행동의 보상을 계산
for i in range(len(agent.action)):
agent.set_pos(pos1)
observation, reward, done = env.move(agent, i)
G += agent.select_action_pr[i] * reward
return G
- max_step == now_step이면 현재 상태에서만 행동을 수행하고 보상만 계산
- 보상은 가능한 행동에 대한 기대값으로 계산
🔄 다음 상태 고려: 재귀 호출
else:
# 4. 현재 상태의 보상을 계산한 후 다음 step으로 이동
# 4.1 현재 위치 저장
pos1 = agent.get_pos()
# 4.2 가능한 모든 행동을 시도
for i in range(len(agent.action)):
observation, reward, done = env.move(agent, i)
# 4.2.1 현재 상태에서 보상을 계산
G += agent.select_action_pr[i] * reward
# 4.2.2 미로 밖일 경우 이전 좌표로 복귀
if done:
if observation[0] < 0 or observation[0] >= env.reward.shape[0] or \
observation[1] < 0 or observation[1] >= env.reward.shape[1]:
agent.set_pos(pos1)
# 4.2.3 다음 step에 대한 상태가치 계산
next_v = state_value_function(env, agent, 0, max_step, now_step+1)
G += agent.select_action_pr[i] * gamma * next_v
# 4.2.4 현재 위치 복구
agent.set_pos(pos1)
return G
- 각 행동을 시도한 후 다음 상태의 가치를 재귀적으로 계산
- 이동 결과가 미로 밖이면 원래 위치로 되돌림
- 다음 상태의 가치는 감가율 γ을 곱해 누적
🧪 전체 상태의 상태가치 계산
# 1. 환경 초기화
env = Environment()
# 2. 에이전트 초기화
agent = Agent()
# 3. 최대 max_step_number 세팅
max_step_number = 13
# 4. 계산 시간 저장을 위한 list
time_len = []
# 5. 재귀함수 state_value_function을 이용해 각 상태 가치 계산
for max_step in range(max_step_number):
# 5.1 상태 가치 테이블 초기화
v_table = np.zeros((env.reward.shape[0], env.reward.shape[1]))
start_time = time.time()
# 5.2 각 상태에 대해 상태가치 계산
for i in range(env.reward.shape[0]):
for j in range(env.reward.shape[1]):
agent.set_pos([i, j])
v_table[i, j] = state_value_function(env, agent, 0, max_step, 0)
# 5.3 계산 시간 저장
time_len.append(time.time() - start_time)
print("max_step = {} total_time = {}(s)".format(max_step, np.round(time.time() - start_time, 2)))
show_v_table(np.round(v_table, 2), env)
# 6. step별 계산 시간 그래프 그리기
plt.plot(time_len, 'o-k')
plt.xlabel('max_step')
plt.ylabel('time (s)')
plt.title('max_step별 계산 시간')
plt.show()
📈 결과 해석
그림 2.26 상태가치 계산의 범위
- (a) max_step = 0: 현재 상태와 바로 다음 상태까지만 참고
- (b) max_step = 1: 다음 상태의 다음 상태까지 포함
→ 이처럼 max_step을 늘려가며 더 멀리 있는 미래 보상을 고려한다.
그림 2.27 상태가치의 수렴
- max_step이 작을 때는 상태가치가 불안정함
- max_step = 7~8부터는 도착지점에 가까운 상태일수록 상태가치가 높아짐
- 작은 미로에서는 max_step ≈ 8 정도면 수렴된 상태가치를 얻을 수 있다
그림 2.28 계산 시간의 증가
- max_step이 얼마일 때 각 상태의 상태가치가 수렴될지 알 수 없음.
- max_step이 증가할수록 계산 시간은 지수적으로 증가
- max_step > 10 이후에는 시간이 급격히 늘어나며, 수렴까지 걸리는 시간 예측이 어려움
⚠️ 단순 재귀 기반 계산으로는 효율적인 상태가치 추정이 어렵기 때문에, 이후에는 정책 반복, 가치 반복과 같은 개선된 알고리즘을 사용한다.
'독서 > 기초부터 시작하는 강화학습 신경망 알고리즘' 카테고리의 다른 글
4.1 정책 평가와 반복 정책 평가 (0) | 2025.03.31 |
---|---|
3.2 가치함수: 행동 가치 계산 (0) | 2025.03.31 |
2.5 환경과 에이전트 준비 (0) | 2025.03.28 |
2. 강화학습의 기본 요소 (1) | 2025.03.28 |
1. 인공지능이란? (0) | 2025.03.28 |