반응형
Q-Learning 기초부터 CartPole 적용까지: 강화학습 첫 번째 알고리즘 배우기
강화학습을 배우다 보면 가장 먼저 접하게 되는 알고리즘이 바로 Q-Learning입니다.
앞서 OpenAI Gym으로 첫 에이전트 만들기에서는 무작위(Random) 에이전트를 CartPole 환경에 적용했는데요, 이번에는 그보다 훨씬 똑똑한 Q-Learning 기반 에이전트를 직접 만들어보겠습니다.
1. Q-Learning이란?
Q-Learning은 “어떤 상태(state)에서 어떤 행동(action)을 하면 얼마나 좋은가”를 학습하는 방법입니다. 여기서 Q는 Quality의 약자로, 각 행동의 '질'을 수치로 표현한다고 보면 됩니다.
핵심 개념
Q-Learning은 Q 테이블을 사용해 상태와 행동의 조합마다 기대되는 보상을 저장합니다.
- Q(s, a): 상태 s에서 행동 a를 했을 때 기대되는 보상
- Q 테이블: (state, action)에 대한 보상 추정값을 저장하는 2차원 배열
학습은 다음과 같은 수식으로 이뤄집니다:
Q(s, a) ← Q(s, a) + α * (r + γ * max(Q(s’, a’)) - Q(s, a))
기호 | 의미 |
---|---|
s | 현재 상태 |
a | 현재 행동 |
r | 즉시 받은 보상 |
s’ | 다음 상태 |
α | 학습률 (learning rate) |
γ | 할인율 (future reward의 중요도) |
2. Q-Learning의 장점과 한계
장점
- 단순한 구조로 강화학습을 이해하기 좋음
- 테이블 기반이라 디버깅 및 시각화가 쉬움
한계
- 상태가 너무 많거나 연속적인 경우, 테이블이 커져서 한계에 도달
- 이런 경우에는 DQN(딥러닝 기반 Q-Learning)으로 확장해야 함
3. CartPole에 Q-Learning 적용하기
CartPole은 상태가 연속값이기 때문에 Q-Learning을 바로 적용하기 어렵습니다. 그래서 상태를 디스크리타이징(구간화)해서 테이블로 변환하는 전처리 과정이 필요합니다.
상태 변수
변수 | 설명 |
---|---|
Cart Position | 수레의 위치 |
Cart Velocity | 수레의 속도 |
Pole Angle | 막대의 기울기 |
Pole Velocity | 막대의 회전 속도 |
이 네 가지 상태를 구간화하여 Q 테이블에 넣을 수 있도록 만들겠습니다.
4. 코드로 배우는 Q-Learning with CartPole
import gym
import numpy as np
import math
# 환경 생성
env = gym.make("CartPole-v1")
# 상태를 디스크리타이징하기 위한 설정
buckets = (1, 1, 6, 12) # 각 상태의 구간 수
q_table = np.zeros(buckets + (env.action_space.n,))
min_bounds = env.observation_space.low
max_bounds = env.observation_space.high
max_bounds[1] = 0.5
max_bounds[3] = math.radians(50)
min_bounds[1] = -0.5
min_bounds[3] = -math.radians(50)
# 하이퍼파라미터
alpha = 0.1
gamma = 0.99
epsilon = 1.0
epsilon_min = 0.01
epsilon_decay = 0.995
episodes = 1000
# 상태 구간화 함수
def discretize(obs):
ratios = [(obs[i] - min_bounds[i]) / (max_bounds[i] - min_bounds[i]) for i in range(len(obs))]
new_obs = [int(round((buckets[i] - 1) * min(max(ratios[i], 0), 1))) for i in range(len(obs))]
return tuple(new_obs)
# Q-Learning 실행
for ep in range(episodes):
obs = discretize(env.reset())
total_reward = 0
done = False
while not done:
if np.random.random() < epsilon:
action = env.action_space.sample()
else:
action = np.argmax(q_table[obs])
next_obs_raw, reward, done, _, = env.step(action)
next_obs = discretize(next_obs_raw)
# Q 업데이트
q_old = q_table[obs + (action,)]
q_max = np.max(q_table[next_obs])
q_table[obs + (action,)] = q_old + alpha * (reward + gamma * q_max - q_old)
obs = next_obs
total_reward += reward
if epsilon > epsilon_min:
epsilon *= epsilon_decay
if (ep + 1) % 100 == 0:
print(f"Episode {ep + 1}, total reward: {total_reward}")
env.close()
5. 결과 해석 및 개선 방법
- 초반에는 랜덤하게 움직이지만, 학습이 진행되면서 평균 보상이 점점 올라갑니다.
- 구간 수(
buckets
)를 조정하거나, 학습률 및 감가율(alpha
,gamma
)을 튜닝하면 성능을 더 높일 수 있습니다. - 이후엔 신경망 기반의 DQN 알고리즘으로 확장해 더 복잡한 문제도 해결할 수 있습니다.
6. 마무리
- Q-Learning은 강화학습의 핵심 개념을 익히기에 가장 적합한 알고리즘입니다.
- CartPole 환경에 Q-Learning을 적용하면 상태 디스크리타이징, Q 테이블 업데이트, ε-greedy 정책 등을 실습할 수 있습니다.
- 다음 목표는 DQN(Deep Q-Network)을 이용해 더 많은 상태를 처리할 수 있는 에이전트를 만드는 것입니다.
반응형
'개발 창고 > AI' 카테고리의 다른 글
DQN으로 CartPole 정복하기: 딥러닝 기반 강화학습 입문 (5) | 2025.07.11 |
---|---|
강화학습 쉽게 시작하기: OpenAI Gym으로 첫 AI 에이전트 만들기 (7) | 2025.07.09 |
LangGraph로 멀티턴 에이전트 워크플로우 만들기 - 파이썬 예제와 함께 배우기 (3) | 2025.07.08 |
중국, 휴머노이드 로봇 축구 리그 개막! 어린이 수준 AI의 실제 경기 도전기 (1) | 2025.07.07 |
파라미터 수는 많지만 계산은 빠르게: Mixture of Experts(MoE)란? (1) | 2025.07.06 |