본문 바로가기
컴퓨터과학

Q-Learning과 Deep Q-Network(DQN)구현 (Python + OpenAI Gym)

by 코드그래피 2025. 2. 10.
반응형

Q-Learning 구현 (Python + OpenAI Gym)

Q-Learning은 기본적인 강화 학습 알고리즘으로, 환경(Environment)과 에이전트(Agent)가 상호작용하며 최적의 정책을 학습하는 방식입니다.

여기서는 OpenAI Gym의 Taxi-v3 환경을 이용해서 간단한 Q-Learning 예제를 구현해 보겠습니다.

🚖 OpenAI Gym의 Taxi-v3 환경

  • 목표: 승객을 태우고 목적지에 내려주는 것
  • 행동(Action): 위, 아래, 왼쪽, 오른쪽 이동, 승객 태우기/내리기
  • 보상(Reward): 성공적으로 승객을 목적지에 내리면 +20, 잘못된 행동을 하면 -1

📌 Q-Learning 코드 구현

import numpy as np
import gym

# 환경 생성
env = gym.make("Taxi-v3")
state_size = env.observation_space.n
action_size = env.action_space.n

# Q-테이블 초기화
Q_table = np.zeros((state_size, action_size))

# 학습 파라미터 설정
alpha = 0.1  # 학습률
gamma = 0.9  # 할인율
epsilon = 1.0  # 탐험 탐색 비율 (초기값)
epsilon_decay = 0.99
epsilon_min = 0.01
num_episodes = 1000  # 학습 반복 횟수

# Q-Learning 학습 시작
for episode in range(num_episodes):
    state = env.reset()[0]
    done = False

    while not done:
        # Epsilon-Greedy 정책 적용
        if np.random.uniform(0, 1) < epsilon:
            action = env.action_space.sample()  # 랜덤 액션 선택 (탐험)
        else:
            action = np.argmax(Q_table[state, :])  # 최적 액션 선택 (탐색)

        # 환경과 상호작용
        next_state, reward, done, _, _ = env.step(action)

        # Q-테이블 업데이트 (벨만 방정식)
        Q_table[state, action] = Q_table[state, action] + alpha * (
            reward + gamma * np.max(Q_table[next_state, :]) - Q_table[state, action]
        )

        state = next_state

    # Epsilon 감소 (탐험 줄이고 탐색 증가)
    epsilon = max(epsilon_min, epsilon * epsilon_decay)

# 학습된 Q-테이블 확인
print("학습된 Q-테이블:")
print(Q_table)

🔍 코드 설명

  • Q-테이블 초기화 → 모든 상태-액션 쌍에 대해 0으로 설정
  • Epsilon-Greedy 탐색 → 랜덤으로 행동하거나, 최적의 행동을 선택
  • 환경과 상호작용하며 학습 → 보상을 받으며 Q-테이블 업데이트
  • 벨만 방정식 적용 → 새로운 Q-값을 계산하고 업데이트
  • Epsilon 감소 → 점점 더 최적의 행동을 찾도록 유도

이제 Q-테이블이 학습되었으니, 강화 학습 에이전트가 최적의 행동을 선택하면서 점점 더 성능이 향상됩니다!

Deep Q-Network (DQN) 구현

Q-Learning의 한계는 "상태 공간이 너무 커지면 Q-테이블을 저장하기 어려움"이라는 점이에요.

이를 해결하기 위해 딥러닝(Deep Learning)을 활용한 DQN(Deep Q-Network)이 등장했습니다.

🧠 DQN의 핵심 개념

  • 신경망(Neural Network)을 활용하여 Q-값을 근사
  • Q-테이블 대신 딥러닝 모델을 이용해 학습
  • 경험 재사용(Experience Replay)과 타깃 네트워크(Target Network) 개념을 도입하여 안정적인 학습 수행

📌 DQN 코드 구현 (TensorFlow + OpenAI Gym)

import gym
import numpy as np
import tensorflow as tf
from tensorflow import keras
from collections import deque
import random

# 환경 생성
env = gym.make("CartPole-v1")
state_size = env.observation_space.shape[0]
action_size = env.action_space.n

# 하이퍼파라미터 설정
learning_rate = 0.001
gamma = 0.99
epsilon = 1.0
epsilon_min = 0.01
epsilon_decay = 0.995
batch_size = 32
memory = deque(maxlen=2000)

# DQN 모델 정의
def build_model():
    model = keras.Sequential([
        keras.layers.Dense(24, activation='relu', input_shape=(state_size,)),
        keras.layers.Dense(24, activation='relu'),
        keras.layers.Dense(action_size, activation='linear')
    ])
    model.compile(optimizer=keras.optimizers.Adam(learning_rate=learning_rate), loss='mse')
    return model

# 모델 생성
model = build_model()

# 경험 저장 및 학습 함수
def train_model():
    if len(memory) < batch_size:
        return

    minibatch = random.sample(memory, batch_size)
    
    for state, action, reward, next_state, done in minibatch:
        target = reward
        if not done:
            target += gamma * np.max(model.predict(next_state.reshape(1, -1))[0])

        target_f = model.predict(state.reshape(1, -1))
        target_f[0][action] = target
        model.fit(state.reshape(1, -1), target_f, epochs=1, verbose=0)

# DQN 학습
num_episodes = 1000

for episode in range(num_episodes):
    state = env.reset()[0]
    state = np.reshape(state, [1, state_size])
    done = False
    total_reward = 0

    while not done:
        if np.random.rand() <= epsilon:
            action = random.randrange(action_size)
        else:
            action = np.argmax(model.predict(state)[0])

        next_state, reward, done, _, _ = env.step(action)
        next_state = np.reshape(next_state, [1, state_size])

        memory.append((state, action, reward, next_state, done))
        state = next_state
        total_reward += reward

        train_model()

    epsilon = max(epsilon_min, epsilon * epsilon_decay)

    print(f"Episode {episode+1}, Reward: {total_reward}, Epsilon: {epsilon:.3f}")

# 학습 완료 후 저장
model.save("dqn_cartpole.h5")

🔍 DQN 코드 설명

  • 신경망 모델 생성 → 상태를 입력받아 Q-값을 예측하는 신경망 설계
  • 경험 메모리(Replay Buffer) 활용 → 과거 경험을 저장하고 랜덤 샘플링하여 학습
  • Epsilon-Greedy 탐색 → 초기에는 랜덤 탐색, 학습이 진행될수록 최적 행동을 선택
  • 벨만 방정식 업데이트 → 타깃 Q-값을 계산하고 신경망을 통해 업데이트
  • DQN 학습 → 게임을 진행하면서 보상(reward)을 최대화하는 방향으로 강화 학습 진행

이제 DQN을 통해 더욱 강력한 AI 에이전트를 만들 수 있어요!

반응형