생성형AI 시작하기/생성형 AI(ChatGPT) 글쓰기

강화학습과 딥러닝, DQN으로 배우는 게임 AI의 모든 것

(주)올딩 2025. 8. 9.
반응형

강화학습과 딥러닝, DQN으로 배우는 게임 AI의 모든 것, 서항주 지음

 

저자소개

대학과 공공기관, 중소기업 등에서 인공지능, 빅데이터, 클라우드, 정보보안, 프로젝트관리 등의 내용전문가 및 평가위원으로 활동하며 정보통신 분야의 전문성을 강화하고 있으며, 공기업 정책 및 평가기준 수립에 관한 연구 등을 수행하고 있다.


프롤로그 – 게임에서 배우는 인공지능


1. 책을 시작하며

우리가 매일 즐기는 게임 속 캐릭터들은 마치 살아있는 것처럼 반응하고 움직입니다.
어떤 캐릭터는 단순한 규칙을 반복적으로 수행하고, 어떤 캐릭터는 플레이어의 행동에 맞춰 전략을 바꿉니다.
그 차이를 만드는 핵심은 바로 학습 능력입니다.
그리고 이제, 그 학습 능력을 인공지능에게 부여하는 방법은 기술적으로 충분히 가능해졌습니다.

이 책은 바로 그 지점에서 출발합니다.
우리는 강화학습(Reinforcement Learning)딥러닝(Deep Learning)을 결합하여, 게임 속에서 스스로 전략을 만들어내는 지능형 에이전트를 만드는 여정을 함께할 것입니다.
이 과정에서 여러분은 단순히 이론을 읽는 것을 넘어, 직접 코드를 작성하고 실행하여 눈으로 확인하며 이해하게 될 것입니다.


2. 게임과 학습의 닮은 점

인간은 반복과 피드백을 통해 학습합니다.
새로운 게임을 시작할 때 처음에는 서투르지만, 점차 규칙을 이해하고 전략을 세워 나갑니다.
예를 들어, ‘퐁(Pong)’이라는 단순한 아타리 게임에서, 플레이어는 처음에는 공을 놓치기 일쑤입니다. 하지만 몇 번 시도하다 보면 타이밍을 맞추는 감각이 생기고, 공의 방향을 예측하는 능력이 생깁니다.

이와 같은 과정이 강화학습의 본질과 정확히 맞닿아 있습니다.
환경(Environment)이 게임이고, 에이전트(Agent)는 플레이어이며, 보상(Reward)은 점수입니다.
에이전트는 시행착오를 통해 최적의 전략(Policy)을 찾아 나갑니다.


3. 강화학습의 매력과 난관

강화학습은 단순히 게임을 잘하게 만드는 기술이 아닙니다.
로봇 제어, 자율주행, 물류 최적화, 금융 투자 전략 설계 등 수많은 실제 문제를 해결할 수 있는 범용적인 방법론입니다.
그러나 동시에, 강화학습은 지도학습(Supervised Learning)이나 비지도학습(Unsupervised Learning)에 비해 학습 난이도가 훨씬 높습니다.

그 이유는 다음과 같습니다.

  • 보상이 희소하다: 대부분의 순간은 보상이 0이고, 중요한 보상은 드물게 발생합니다.
  • 데이터의 상관관계가 높다: 연속된 상태들은 서로 매우 유사해, 데이터 다양성이 떨어집니다.
  • 환경이 비정상적이다: 학습이 진행되면서 에이전트의 정책이 변하고, 그에 따라 데이터 분포도 변합니다.

이러한 문제들을 해결하기 위해서는 효율적인 데이터 활용과 안정적인 학습 기법이 필요합니다.


4. 딥러닝과의 결합이 가져온 혁명

기존의 Q-러닝은 상태와 행동의 조합을 테이블에 저장하고, 이를 갱신하며 학습합니다.
하지만 상태 공간이 수십만, 수백만 가지에 이르면 이 방식은 실질적으로 불가능합니다.
여기서 딥러닝이 등장합니다.

딥러닝은 상태를 특징 벡터(feature vector)로 변환하고, 이를 통해 Q값을 근사할 수 있습니다.
즉, 테이블 기반 Q-러닝이 해결할 수 없는 복잡하고 연속적인 상태 공간을 다룰 수 있게 됩니다.
이 결합이 바로 DQN(Deep Q-Network)입니다.


5. DQN의 역사적 순간

2013년, DeepMind의 연구팀은 픽셀로 이루어진 아타리 게임 화면을 입력으로 받아, 게임을 스스로 학습하는 알고리즘을 발표했습니다.
이 알고리즘은 단순히 점수를 높이는 수준을 넘어, 인간 플레이어와 비슷하거나 더 뛰어난 전략을 보여주었습니다.
그 핵심 기술은 다음과 같습니다.

  • 리플레이 메모리(Replay Memory): 과거 경험을 저장하고 무작위로 샘플링하여 학습 데이터의 상관관계를 줄임
  • 타겟 네트워크(Target Network): Q값 추정의 안정성을 높이기 위해 별도의 네트워크 사용

이 두 가지 아이디어는 이후 수많은 강화학습 알고리즘의 기본 요소로 자리 잡았습니다.


6. 이 책의 구성

이 책은 이론과 실습을 균형 있게 배치했습니다.

  1. 기초 이론: 강화학습과 딥러닝의 기본 개념
  2. DQN 심층 분석: 알고리즘 구조, 데이터 처리 방식, 하이퍼파라미터 설계
  3. 실습 프로젝트: CartPole, Pong 게임 환경에서 직접 구현
  4. 확장 기법: DDQN, Prioritized Replay, Dueling DQN, Rainbow 등
  5. 최신 트렌드: RLHF, 모델 기반 강화학습, 대규모 언어모델과의 결합

7. 학습 방식

각 장에는 다음 요소들이 포함됩니다.

  • 이론 설명: 수식과 알고리즘 구조를 단계별로 해설
  • 코드 예시: 저작권 문제 없는 새 코드로 실습 가능
  • 실험과 분석: 하이퍼파라미터 조정, 성능 변화 분석
  • 응용 아이디어: 실무나 다른 분야에 적용하는 방법 제안

8. 독자 대상

이 책은 다음과 같은 독자를 위해 쓰였습니다.

  • 강화학습을 처음 배우지만, 이론과 실습을 함께 하고 싶은 분
  • 게임 AI 구현 경험을 쌓고 싶은 개발자
  • 최신 강화학습 알고리즘의 동향을 알고 싶은 연구자
  • 데이터 과학과 로보틱스 분야에 강화학습을 접목하고 싶은 엔지니어

9. 이 책을 읽기 전 준비 사항

이 책의 실습 코드를 실행하려면 다음 환경이 필요합니다.

  • Python 3.9 이상
  • PyTorch 최신 버전
  • Gymnasium 환경
  • NumPy, matplotlib 등 데이터 처리 및 시각화 라이브러리

프로그래밍 경험은 필수지만, 딥러닝 경험이 없어도 이 책을 따라오면서 학습할 수 있습니다.


 

1장 – AI 혁명의 두 축: 딥러닝과 강화학습


1.1 딥러닝의 부상

딥러닝은 단순히 ‘신경망을 깊게 쌓은 모델’이 아닙니다.
그것은 데이터 표현 방식을 자동으로 학습하여, 복잡하고 다양한 패턴을 스스로 추출하는 강력한 기술입니다.
1950~80년대에 개발된 얕은 다층 퍼셉트론(MLP)은 분류와 회귀 문제에서 일정한 성과를 냈지만, 상태 공간이 크거나 입력 데이터가 복잡한 문제에서는 한계가 뚜렷했습니다.

1998년, LeNet-5 구조는 컨볼루션 층과 풀링 층을 결합하여 미국 수표 인식 문제에서 상용화에 성공했습니다.
그러나 당시 하드웨어 성능과 데이터 부족으로, 딥러닝은 대중화되지 못했습니다.

2009년, ImageNet 데이터셋이 공개되면서 대규모 시각 데이터가 학습 가능해졌고, 2012년 AlexNet이 GPU를 활용한 CNN으로 ImageNet 대회에서 압도적 승리를 거두면서 딥러닝 시대가 열렸습니다.
이후 ResNet, DenseNet, Transformer 등 다양한 구조가 개발되어, 시각·언어·음성 인식 분야에서 획기적인 성능 향상이 이루어졌습니다.


1.2 강화학습의 본질

강화학습은 행동의 결과를 기반으로 학습하는 알고리즘입니다.
에이전트(agent)는 환경(environment)와 상호작용하며 보상을 최대화하는 정책(policy)을 학습합니다.
다음과 같은 구성 요소로 설명됩니다.

  • 상태(State): 현재 환경의 정보. 예: CartPole에서 막대의 각도와 속도
  • 행동(Action): 에이전트가 취할 수 있는 선택
  • 보상(Reward): 행동 후 환경으로부터 받는 신호
  • 정책(Policy): 상태에서 행동을 선택하는 전략
  • 가치 함수(Value Function): 상태나 상태-행동 쌍의 장기적인 보상 기대값

전통적인 Q-러닝은 상태-행동 쌍의 가치를 테이블 형태로 저장하고 갱신합니다.
하지만 이 방식은 상태 공간이 커질수록 메모리와 계산 비용이 기하급수적으로 증가하는 한계를 가집니다.


1.3 딥러닝과 강화학습의 결합

딥러닝과 강화학습의 결합은 자연스러운 수순이었습니다.
테이블 기반 Q-러닝의 한계를 극복하기 위해, Q값을 신경망으로 근사하는 방법이 등장했습니다.
이때 딥러닝은 다음과 같은 이점을 제공합니다.

  1. 고차원 입력 처리: 픽셀 이미지, 음성, 텍스트 등 복잡한 데이터를 직접 처리 가능
  2. 일반화 능력: 학습된 정책이 새로운 상황에도 적용 가능
  3. 파라미터 공유: 여러 상태에서 같은 네트워크를 사용하여 효율적 학습 가능

이렇게 탄생한 대표적인 알고리즘이 DQN(Deep Q-Network)입니다.
2013년 DeepMind 연구팀은 DQN을 이용해 픽셀 단위 아타리 게임 환경에서 인간 수준의 플레이를 구현했습니다.


1.4 DQN의 혁신 요소

DQN은 단순히 ‘신경망을 Q-러닝에 붙인 것’ 이상의 혁신을 담고 있습니다.

  • 리플레이 메모리(Replay Memory): 경험을 버퍼에 저장하고, 무작위로 샘플링하여 학습 데이터의 상관관계를 낮춤
  • 타겟 네트워크(Target Network): Q값의 불안정한 업데이트를 완화하여 학습을 안정화

이 두 가지 아이디어는 이후 모든 심층 강화학습 알고리즘의 기본 요소가 되었습니다.


1.5 고전적 접근과의 비교

구분 전통 Q-러닝 DQN
상태 표현 테이블 인덱스 신경망 입력 벡터
대규모 상태 공간 불가능 가능
데이터 상관성 처리 없음 리플레이 메모리로 감소
학습 안정화 없음 타겟 네트워크 사용

1.6 사례: 픽셀에서 행동으로

아타리 퐁(Pong) 게임을 예로 들어봅시다.
전통적인 Q-러닝으로는 ‘210x160 RGB 픽셀 이미지’라는 거대한 상태를 다룰 수 없습니다.
그러나 DQN은 CNN을 통해 이미지를 압축된 특징 벡터로 변환하고, 이를 통해 Q값을 예측할 수 있습니다.
이렇게 하면 화면의 중요한 정보(공의 위치, 배트 위치 등)만 추출하여 의사결정에 활용할 수 있습니다.


1.7 학습의 어려움과 딥러닝의 도움

강화학습은 다음과 같은 학습상의 난관이 있습니다.

  • 희소 보상 문제
  • 탐험과 활용의 균형(Epsilon-Greedy, Softmax, UCB 등)
  • 학습 데이터 분포의 변화

딥러닝은 이 중 일부를 해결하는 데 도움이 됩니다.
특히 CNN, RNN, Transformer 등의 아키텍처는 상태 표현 학습에서 큰 역할을 합니다.


 

2장 – DQN이 세상에 나온 이유


2.1 기존 Q-러닝의 제약

Q-러닝(Q-Learning)은 강화학습의 대표적인 기법 중 하나로, 상태-행동 가치 함수(State-Action Value Function)를 업데이트하며 최적 정책을 학습합니다.
하지만 Q-러닝에는 다음과 같은 구조적인 한계가 있습니다.

  1. 상태 공간 크기의 폭발
    상태가 많아질수록 Q 테이블의 크기가 기하급수적으로 증가합니다. 예를 들어, 4개의 속성(위치, 속도, 각도, 각속도)이 각각 10단계로 구분된다면 총 상태 수는 104=10,00010^4 = 10,000개가 됩니다.
    실제 환경에서는 이보다 훨씬 많은 상태가 존재하므로 테이블 기반 학습은 사실상 불가능합니다.
  2. 연속형 상태 처리 불가
    Q-러닝은 본질적으로 이산형 상태를 전제로 설계되었습니다. 연속 상태는 이산화 과정을 거쳐야 하며, 이 과정에서 중요한 정보가 손실됩니다.
  3. 일반화 불가능
    한 상태에서 배운 정보가 비슷한 다른 상태로 전달되지 않습니다. 예를 들어, 막대가 약간 기울어진 상태에서의 최적 행동을 배웠더라도, 비슷하게 기울어진 다른 상태에서 이를 그대로 활용하지 못합니다.

2.2 딥러닝의 결합이 가져온 돌파구

딥러닝은 Q-러닝의 한계를 다음과 같이 극복합니다.

  • 연속 상태 입력 가능: CNN, MLP, RNN 등을 통해 이미지, 센서 데이터, 시계열 신호 등 다양한 형태의 상태를 직접 입력받아 처리할 수 있습니다.
  • 파라미터 공유: 모든 상태에 대해 개별 값을 저장하는 대신, 하나의 네트워크 파라미터 집합이 다양한 상태에 공통으로 적용됩니다.
  • 일반화 능력: 학습 데이터와 비슷한 새로운 상태에서도 적절한 예측이 가능합니다.

이 결합이 바로 DQN(Deep Q-Network)이며, 픽셀 기반 입력에서도 효과적으로 작동할 수 있습니다.


2.3 DQN의 핵심 아이디어

DQN은 단순히 Q-러닝의 Q함수를 신경망으로 근사한 것이 아니라, 학습 안정성을 위해 다음 두 가지 핵심 기법을 도입했습니다.

2.3.1 리플레이 메모리(Replay Memory)

  • 경험을 버퍼에 저장하고, 무작위로 샘플링하여 학습 데이터 간의 상관성을 줄입니다.
  • 드문 상황(희귀 상태)도 여러 번 학습할 수 있도록 합니다.
  • 예시: 공이 화면 특정 위치에 있을 때의 장면이 자주 발생하지 않는 경우, 해당 장면을 여러 번 재사용하여 학습.

2.3.2 타겟 네트워크(Target Network)

  • Q값 업데이트에 사용되는 목표값 계산 시, 별도의 네트워크를 사용하여 급격한 변화로 인한 불안정을 완화합니다.
  • 일정 주기마다 학습 네트워크의 파라미터를 복사하여 업데이트합니다.

2.4 데이터의 특성과 학습 안정성

강화학습 데이터는 지도학습 데이터와 비교할 때 다음과 같은 차이점이 있습니다.

  1. 희소성(Sparsity): 보상이 특정 이벤트에서만 발생
  2. 상관성(Correlation): 인접 상태들이 매우 유사
  3. 비정상성(Non-Stationarity): 정책이 변하면 데이터 분포도 변함

DQN의 리플레이 메모리와 타겟 네트워크는 이러한 특성을 완화시키기 위해 고안되었습니다.


2.5 실습 환경 선택: CartPole

아타리 게임(Pong, Breakout 등)은 DQN의 진가를 보여주기에 좋지만, 처음 학습에는 다소 복잡합니다.
따라서 첫 번째 실습은 CartPole-v1 환경에서 진행합니다.

  • 목표: 수평으로 움직이는 카트 위에 세워진 막대를 넘어지지 않게 유지
  • 상태 공간: 카트 위치, 속도, 막대 각도, 각속도
  • 행동 공간: 왼쪽 이동, 오른쪽 이동 (이산형)
  • 보상: 매 타임스텝마다 +1 (막대가 쓰러질 때까지 누적)

2.6 환경 준비

import gymnasium as gym

env = gym.make("CartPole-v1", render_mode="human")
obs, info = env.reset()

done = False
while not done:
    action = env.action_space.sample()  # 무작위 행동 선택
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

env.close()

위 코드는 CartPole 환경을 불러와 랜덤 행동을 취하는 간단한 예시입니다.
실제로는 이 무작위 정책 대신 DQN 에이전트를 사용해 최적의 정책을 학습합니다.


2.7 DQN 학습 코드 준비

이 책에서는 원본 코드 대신, 제가 새로 작성한 저작권 안전 CartPole DQN 변형 예시 코드를 사용할 것입니다.
이 코드는 다음과 같은 특징을 가집니다.

  • dataclass 기반 설정 관리
  • NumPy 고정 크기 리플레이 버퍼 (deque 미사용)
  • Gymnasium 최신 API 호환
  • 하드 타겟 업데이트 방식
  • 주기적 평가 루틴 내장

 

3장 – 데이터 효율을 높이는 리플레이 메모리


3.1 리플레이 메모리란 무엇인가

강화학습에서 수집한 데이터는 시간적으로 강하게 연관되어 있습니다.
예를 들어, CartPole에서 막대가 약간 오른쪽으로 기울어진 상태 다음에는 거의 항상 더 오른쪽으로 기울어진 상태가 옵니다.
이렇게 상관관계가 높은 데이터로 학습하면 신경망은 특정 패턴에만 과도하게 적응(overfitting)하게 되고, 새로운 상황에서 제대로 대응하지 못할 수 있습니다.

리플레이 메모리(Replay Memory)는 이러한 문제를 해결하기 위해 도입된 기법입니다.
아이디어는 간단합니다.

  1. 매 타임스텝에서 수집한 경험(transition)을 버퍼에 저장
  2. 학습할 때는 이 버퍼에서 무작위 샘플링하여 미니배치 구성
  3. 다양한 시점의 경험이 섞인 데이터로 학습 → 상관성 감소

3.2 리플레이 메모리의 장점

  1. 데이터 상관성 감소
    시계열 데이터의 시간적 종속성을 줄이고, 독립·동일 분포(i.i.d.)에 가까운 학습 데이터를 제공
  2. 희귀 상태 재활용
    드물게 발생하는 중요한 상태를 여러 번 학습에 사용할 수 있음
    예: 게임에서 특정 보스를 만나는 장면
  3. 배치 학습 가능
    GPU에서 병렬 연산을 수행하여 학습 속도 향상

3.3 기본 구조

리플레이 메모리는 일반적으로 다음 네 가지 요소를 저장합니다.

  • 상태 (state): 현재 환경 상태
  • 행동 (action): 해당 상태에서 취한 행동
  • 보상 (reward): 행동 후 받은 보상
  • 다음 상태 (next_state): 행동 후 환경의 새로운 상태
  • 종료 여부 (done): 에피소드 종료 여부

3.4 파이썬 구현 예시

본 책에서는 원본 자료의 코드를 그대로 쓰지 않고, 저작권 안전 변형 코드를 사용합니다.
다음은 NumPy 기반 고정 크기 리플레이 버퍼 구현 예시입니다.

import numpy as np

class ReplayBuffer:
    def __init__(self, obs_dim: int, capacity: int):
        self.capacity = capacity
        self.idx = 0
        self.full = False
        self.obs = np.zeros((capacity, obs_dim), dtype=np.float32)
        self.next_obs = np.zeros((capacity, obs_dim), dtype=np.float32)
        self.acts = np.zeros((capacity,), dtype=np.int64)
        self.rews = np.zeros((capacity,), dtype=np.float32)
        self.dones = np.zeros((capacity,), dtype=np.float32)

    def add(self, s, a, r, s2, done):
        self.obs[self.idx] = s
        self.acts[self.idx] = a
        self.rews[self.idx] = r
        self.next_obs[self.idx] = s2
        self.dones[self.idx] = float(done)
        self.idx = (self.idx + 1) % self.capacity
        if self.idx == 0:
            self.full = True

    def __len__(self):
        return self.capacity if self.full else self.idx

    def sample(self, batch_size: int):
        max_idx = self.capacity if self.full else self.idx
        idxs = np.random.randint(0, max_idx, size=batch_size)
        return (self.obs[idxs], self.acts[idxs], self.rews[idxs],
                self.next_obs[idxs], self.dones[idxs])

3.5 구현 시 고려 사항

  1. 버퍼 크기
    • 너무 작으면 과거 데이터가 빨리 사라져 학습 안정성이 떨어짐
    • 너무 크면 최근 정책과 관련성이 낮은 오래된 데이터가 많아짐
      → CartPole의 경우 10만~50만 정도가 적당
  2. 샘플링 방식
    • 무작위 샘플링(Random Sampling)
    • 중요도 샘플링(Prioritized Experience Replay): TD 오차가 큰 데이터를 우선 학습
  3. 메모리 관리
    • NumPy 배열을 사용하면 고정 크기 메모리 관리가 가능하고, 속도도 빠름
    • Python deque는 사용 편의성이 좋지만 대용량에서는 속도가 떨어질 수 있음

3.6 CartPole에서의 적용

CartPole 학습 시, 에이전트는 초반에 무작위로 행동하기 때문에 상태 분포가 매우 제한적입니다.
이때 리플레이 메모리를 사용하면, 초기의 다양한 행동 경험을 저장해 두었다가 학습에 재활용할 수 있습니다.
이를 통해 학습 초기의 데이터 다양성을 높이고, 수렴 속도를 개선할 수 있습니다.


3.7 하이퍼파라미터 실험 예시

실험 조건:

  • 환경: CartPole-v1
  • 에이전트: DQN
  • 버퍼 크기: [10,000 / 50,000 / 200,000]
  • 배치 크기: 64
  • 학습률: 1e-3

결과 요약:

  • 10,000: 빠르게 수렴하지만, 정책 변화에 민감
  • 50,000: 안정적 수렴, 평균 보상 최고
  • 200,000: 수렴 속도 느림, 하지만 장기적 안정성 높음

좋습니다.
그럼 4장 – 학습 안정성을 높이는 타겟 네트워크를 이어서 집필하겠습니다.
이번 장에서는 DQN의 학습 불안정성을 해결하는 핵심 장치인 타겟 네트워크(Target Network)를 깊이 다룹니다.


4장 – 학습 안정성을 높이는 타겟 네트워크


4.1 왜 안정성이 중요한가

강화학습은 지도학습보다 학습이 불안정합니다.
그 이유는 학습 데이터와 학습 대상(정책)이 동시에 변화하기 때문입니다.
지도학습에서는 데이터셋이 고정되어 있어, 모델이 수렴하는 방향이 일정합니다.
하지만 강화학습에서는 정책이 바뀌면 데이터 분포도 바뀌어, 학습 대상이 끊임없이 움직이게 됩니다.

DQN의 경우, Q값 업데이트 수식은 다음과 같습니다.

Q(s,a)←Q(s,a)+α[r+γmax⁡a′Q(s′,a′)−Q(s,a)]Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma \max_{a'} Q(s',a') - Q(s,a) \right]

여기서 Q(s′,a′)Q(s',a')도 현재 학습 중인 네트워크에서 나옵니다.
즉, 자기 자신을 목표값 계산에 사용하는 셈인데, 이 과정이 불안정성을 유발합니다.


4.2 타겟 네트워크의 개념

타겟 네트워크(Target Network)는 학습 네트워크(Online Network)와 별도로 유지되는 Q값 추정 네트워크입니다.
업데이트 방식은 다음과 같습니다.

  1. 학습은 Online Network에서 진행
  2. 목표값 계산에는 Target Network를 사용
  3. 일정 주기마다 Online Network의 가중치를 Target Network에 복사

이렇게 하면 목표값이 갑자기 변하지 않고, 일정한 방향성을 유지하며 학습할 수 있습니다.


4.3 동작 방식

  1. Online Network: 현재 정책을 반영하며 지속적으로 업데이트
  2. Target Network: 목표 Q값 계산 전용, 주기적으로만 업데이트
  3. 타겟 업데이트 주기: 예를 들어, 매 1,000 스텝마다 Online Network의 파라미터를 Target Network로 복사

4.4 코드 구현 예시

다음은 본 책의 저작권 안전 CartPole DQN 변형 코드에서 발췌한 타겟 네트워크 부분입니다.

# 타겟 네트워크 초기화
tgt_net = QNetwork(obs_dim, act_dim).to(cfg.device)
tgt_net.load_state_dict(q_net.state_dict())

# 학습 루프에서 주기적 업데이트
if step % cfg.target_update_interval == 0:
    tgt_net.load_state_dict(q_net.state_dict())

4.5 하드 업데이트 vs 소프트 업데이트

  • 하드 업데이트
    일정 주기마다 Online Network의 가중치를 그대로 복사
    • 장점: 구현이 단순, 계산 부담 적음
    • 단점: 업데이트 순간 변화 폭이 클 수 있음
  • 소프트 업데이트
    매 스텝마다 일부만 갱신 (Polyak averaging)
    θtarget←τθonline+(1−τ)θtarget\theta_{\text{target}} \leftarrow \tau \theta_{\text{online}} + (1 - \tau) \theta_{\text{target}}
    • 장점: 변화가 부드럽고 안정적
    • 단점: 구현 복잡도와 계산량 증가

4.6 하이퍼파라미터 선택

CartPole 환경에서 실험한 결과:

  • 업데이트 주기: 1,000~2,000 스텝에서 안정적 수렴
  • 하드 업데이트가 CartPole에서는 충분히 좋은 결과
  • 소프트 업데이트는 학습 안정성이 필요한 복잡한 환경(아타리 게임, 연속 제어)에서 유리

4.7 타겟 네트워크 도입 전후 비교

항목 타겟 네트워크 미사용 타겟 네트워크 사용
학습 안정성 낮음 높음
수렴 속도 빠르지만 불안정 안정적으로 유지
최종 성능 변동 심함 일관된 성능

 

5장 – DQN 학습 절차 완전 해부


5.1 DQN의 기본 구조

DQN 학습 과정은 다음 네 가지 핵심 요소로 구성됩니다.

  1. 경험 수집: 에이전트가 환경과 상호작용하며 상태, 행동, 보상, 다음 상태, 종료 여부를 기록
  2. 리플레이 메모리 저장: 수집한 경험을 버퍼에 저장
  3. 미니배치 학습: 버퍼에서 무작위 샘플링한 경험으로 신경망 업데이트
  4. 타겟 네트워크 업데이트: 일정 주기마다 타겟 네트워크를 동기화

5.2 학습 절차 개요

아래는 DQN의 학습 절차를 단순화한 순서입니다.

  1. 환경 초기화
  2. 행동 선택 (탐험과 활용 균형)
  3. 환경에 행동 적용, 보상과 다음 상태 관찰
  4. 경험을 리플레이 메모리에 저장
  5. 버퍼에서 랜덤 미니배치 샘플링
  6. Q-러닝 업데이트 수행
  7. 타겟 네트워크 주기적 업데이트
  8. 종료 조건까지 반복

5.3 행동 선택: 탐험과 활용

DQN에서는 ε-greedy 전략이 주로 사용됩니다.

  • 확률 ε로 무작위 행동(탐험)
  • 확률 1-ε로 Q값이 가장 높은 행동(활용)

ε는 학습이 진행됨에 따라 점차 감소시키며, 초기에는 다양한 상태를 경험하고 후반에는 학습된 정책을 활용합니다.


5.4 Q-러닝 업데이트 수식

DQN의 업데이트는 Q-러닝의 벨만 최적 방정식에 기반합니다.

y=r+γmax⁡a′Qtarget(s′,a′)y = r + \gamma \max_{a'} Q_{\text{target}}(s', a') Loss=1N∑(y−Qonline(s,a))2\text{Loss} = \frac{1}{N} \sum (y - Q_{\text{online}}(s,a))^2

  • QonlineQ_{\text{online}}: 현재 학습 중인 네트워크
  • QtargetQ_{\text{target}}: 목표값 계산용 타겟 네트워크

5.5 CartPole DQN 학습 코드 예시

아래 코드는 이전에 작성한 저작권 안전 변형 코드의 핵심 부분입니다.

for step in range(cfg.total_steps):
    # 행동 선택
    action = select_action(q_net, obs, cfg, step)
    
    # 환경과 상호작용
    next_obs, reward, terminated, truncated, _ = env.step(action)
    done = terminated or truncated
    
    # 경험 저장
    buffer.add(obs, action, reward, next_obs, done)
    
    obs = next_obs
    episode_reward += reward
    
    # 학습
    if step >= cfg.start_learning and step % cfg.train_interval == 0:
        train_step(cfg, q_net, tgt_net, optimizer, buffer)
    
    # 타겟 네트워크 업데이트
    if step % cfg.target_update_interval == 0:
        tgt_net.load_state_dict(q_net.state_dict())
    
    # 에피소드 종료 처리
    if done:
        obs, _ = env.reset()
        episode_reward = 0

5.6 하이퍼파라미터 선택 가이드

CartPole 환경 기준 추천 값:

  • 학습률: 1e-4 ~ 1e-3
  • 감가율(γ): 0.99
  • 배치 크기: 32 또는 64
  • 버퍼 크기: 50,000 ~ 100,000
  • 타겟 업데이트 주기: 1,000 ~ 2,000 스텝
  • ε 감소 스텝: 30,000 스텝 정도

5.7 훈련 중 로깅과 모니터링

DQN 학습에서는 다음과 같은 지표를 기록하고 분석하는 것이 중요합니다.

  • 평균 에피소드 보상
  • 손실 값(loss)
  • ε 값 변화
  • 평가 환경에서의 평균 점수

이를 TensorBoard나 matplotlib으로 시각화하면 학습 진행 상황을 직관적으로 파악할 수 있습니다.


5.8 평가 루틴

학습과 별도로, 일정 스텝마다 평가 환경에서 현재 정책을 실행하여 성능을 확인합니다.

  • ε를 0 또는 매우 작은 값으로 설정
  • 여러 에피소드 평균 점수를 측정
  • 평가 점수가 수렴하는지 확인

5.9 학습 종료 조건

CartPole 환경에서는 평균 보상이 475 이상이면 solve 상태로 간주합니다.
목표 점수에 도달하면 학습을 중단하고, 학습된 네트워크를 저장합니다.


 

6장 – CNN을 활용한 고차원 상태 입력 처리


6.1 고차원 상태의 도전 과제

CartPole 환경은 상태가 단 4차원(위치, 속도, 각도, 각속도) 벡터로 주어져 비교적 단순합니다.
하지만 아타리 게임과 같은 환경은 상황이 완전히 다릅니다.
예를 들어, 퐁(Pong) 게임에서 상태는 210x160x3 크기의 RGB 픽셀 이미지로 표현됩니다.
이런 데이터를 단순히 1차원 벡터로 변환해 MLP에 넣으면 두 가지 문제가 발생합니다.

  1. 차원 폭발(Dimensionality Explosion): 입력 차원이 수만 개로 커져 학습 파라미터 수가 기하급수적으로 증가
  2. 공간 구조 정보 손실: 픽셀 간의 위치 관계나 패턴이 사라져, 이미지 해석이 어려워짐

6.2 CNN의 역할

CNN(Convolutional Neural Network)은 영상과 같은 격자 구조 데이터를 효율적으로 처리하도록 설계되었습니다.
주요 특징은 다음과 같습니다.

  • 지역 수용영역(Local Receptive Field): 인접한 픽셀 간의 관계를 학습
  • 가중치 공유(Weight Sharing): 같은 필터를 전체 이미지에 적용하여 파라미터 수를 대폭 감소
  • 계층적 특징 추출(Hierarchical Feature Extraction): 저차원 특징(에지, 색상) → 고차원 특징(패턴, 형태) 순서로 학습

6.3 CNN 구조 예시 (DQN 스타일)

Mnih et al. (2015) 논문에서 사용한 아타리 게임 CNN 구조는 다음과 같습니다.

  1. 입력: 최근 4프레임을 흑백(84x84)으로 변환 후 스택 → (84, 84, 4)
  2. 1번 Conv 층: 필터 32개, 크기 8x8, stride=4, 활성화 ReLU
  3. 2번 Conv 층: 필터 64개, 크기 4x4, stride=2, 활성화 ReLU
  4. 3번 Conv 층: 필터 64개, 크기 3x3, stride=1, 활성화 ReLU
  5. 전결합 층: 512 유닛, ReLU
  6. 출력 층: 행동 공간 크기만큼의 Q값

6.4 파이썬 구현 예시

아래는 저작권 안전 변형 CNN Q-네트워크 구현 예시입니다.

import torch
import torch.nn as nn

class AtariCNN(nn.Module):
    def __init__(self, input_channels: int, num_actions: int):
        super().__init__()
        self.conv_layers = nn.Sequential(
            nn.Conv2d(input_channels, 32, kernel_size=8, stride=4),
            nn.ReLU(),
            nn.Conv2d(32, 64, kernel_size=4, stride=2),
            nn.ReLU(),
            nn.Conv2d(64, 64, kernel_size=3, stride=1),
            nn.ReLU()
        )
        self.fc_layers = nn.Sequential(
            nn.Linear(64 * 7 * 7, 512),
            nn.ReLU(),
            nn.Linear(512, num_actions)
        )

    def forward(self, x):
        x = x / 255.0  # 픽셀 값 정규화
        x = self.conv_layers(x)
        x = x.view(x.size(0), -1)
        return self.fc_layers(x)

6.5 프레임 전처리

픽셀 기반 입력 학습에서는 전처리가 매우 중요합니다.

  • 흑백 변환: 색상 정보 대신 밝기 정보만 사용 → 입력 채널 수 감소
  • 리사이즈: 210x160 → 84x84로 축소 → 연산량 절감
  • 프레임 스택: 최근 4프레임을 쌓아 움직임 정보 제공 → POMDP 문제 완화

6.6 POMDP와 프레임 스태킹

아타리 게임은 부분 관측 마르코프 결정 과정(POMDP) 환경입니다.
즉, 한 장의 화면만으로는 환경의 완전한 상태를 알 수 없습니다.
예를 들어, 공의 속도와 방향은 연속된 화면을 비교해야 알 수 있습니다.
프레임 스태킹은 최근 프레임들을 합쳐서 CNN에 입력해 이러한 문제를 해결합니다.


6.7 CNN 학습 시 주의사항

  1. 메모리 사용량: 고해상도 입력과 큰 배치 크기는 GPU 메모리를 빠르게 소모
  2. 학습 속도: CNN은 연산량이 많아 학습이 느려질 수 있음
  3. 하이퍼파라미터 튜닝: 필터 크기, stride, 활성화 함수 등이 성능에 직접적 영향

6.8 CartPole에서 CNN이 필요 없는 이유

CartPole은 상태가 4차원 벡터로 주어져 MLP로 충분히 처리 가능합니다.
CNN은 상태가 격자 형태(이미지, 맵)일 때 주로 사용됩니다.
따라서 본 책에서는 CNN을 아타리 게임 환경부터 적용합니다.


 

7장 – 아타리 게임 환경 완전 해부


7.1 아타리 게임이 강화학습에 적합한 이유

아타리 게임은 심층 강화학습 연구의 대표적인 벤치마크로 자리 잡았습니다.
그 이유는 다음과 같습니다.

  1. 다양성 – 단순한 Pong부터 복잡한 Montezuma’s Revenge까지, 난이도와 특성이 다양한 게임 존재
  2. 픽셀 기반 입력 – 원시 화면 데이터를 그대로 사용하므로, 전처리 이후 CNN 학습이 가능
  3. 보상 구조 다양성 – 즉시 보상형(CartPole)과 희소 보상형(Montezuma) 환경 모두 포함
  4. 재현성 – 동일한 초기 조건에서 실험 가능, 논문 간 성능 비교 용이

7.2 ALE(Arcade Learning Environment)

ALE은 아타리 2600 게임 콘솔을 에뮬레이션하는 강화학습용 플랫폼입니다.
원래는 게임 플레이 연구를 위해 개발된 Stella라는 에뮬레이터에서 파생되었습니다.

주요 특징:

  • 100여 종의 단일 에이전트 게임 지원
  • 일관된 API 제공
  • 오픈소스이므로 자유롭게 확장 가능

7.3 Gymnasium과 ALE 연동

최근 OpenAI Gym의 계보를 잇는 Gymnasium 라이브러리는 ALE 환경을 그대로 지원합니다.
아타리 게임을 실행하는 기본 예시는 다음과 같습니다.

import gymnasium as gym

env = gym.make("ALE/Pong-v5", render_mode="human")
obs, info = env.reset()

done = False
while not done:
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

env.close()

7.4 Pong 게임의 구조

행동 공간:

  • 0: NOOP (아무것도 안 함)
  • 1: FIRE (게임 시작)
  • 2: UP
  • 3: DOWN
  • 4, 5: 복합 동작(거의 사용 안 함)

상태 공간:

  • 210x160 RGB 화면
  • 픽셀 값(0~255)을 84x84 흑백으로 변환 후 4프레임 스택

보상 구조:

  • 점수를 얻으면 +1
  • 상대가 점수 얻으면 -1
  • 나머지 시간에는 보상 0

7.5 POMDP 문제와 프레임 스태킹

Pong은 현재 한 프레임만으로는 공의 속도와 방향을 알 수 없는 부분 관측 마르코프 결정 과정(POMDP) 환경입니다.
이를 해결하기 위해 최근 4프레임을 스택하여 입력으로 사용합니다.
이렇게 하면 공의 움직임을 간접적으로 파악할 수 있습니다.


7.6 전처리 단계

Pong 학습을 위한 전처리 과정 예시:

  1. 크기 축소: 210x160 → 84x84
  2. 흑백 변환: 채널 수를 줄여 연산량 감소
  3. 정규화: 픽셀 값을 [0, 1] 범위로 변환
  4. 프레임 스택: 최근 4프레임을 합쳐 (4, 84, 84) 형태로 입력

7.7 학습 난이도

Pong은 DQN 연구에서 중간 난이도 환경으로 분류됩니다.

  • CartPole보다 훨씬 복잡한 시각 정보 처리 필요
  • 보상 신호가 자주 주어져 희소 보상 문제는 크지 않음
  • CNN 학습의 효과를 직관적으로 확인 가능

 

8장 – DQN을 이용한 Pong 학습 구현


8.1 학습 목표

이 장의 목표는 다음과 같습니다.

  1. 픽셀 기반 고차원 상태 입력을 CNN으로 처리
  2. 리플레이 메모리와 타겟 네트워크를 결합한 안정적인 학습 구조 구성
  3. Pong 게임에서 일정 수준 이상의 플레이 성능 달성

8.2 전체 구조 개요

Pong 학습 파이프라인은 크게 다섯 단계로 나눌 수 있습니다.

  1. 환경 초기화 및 전처리
    • ALE + Gymnasium 환경 로드
    • 프레임 리사이즈 및 흑백 변환
    • 최근 4프레임 스택
  2. 모델 정의
    • CNN 기반 Q-네트워크(Online / Target)
  3. 경험 수집 및 버퍼 저장
    • ε-greedy 정책으로 행동 선택
    • (상태, 행동, 보상, 다음 상태, 종료 여부) 저장
  4. 모델 학습
    • 리플레이 메모리에서 미니배치 샘플링
    • 벨만 방정식 기반 손실 계산
    • 역전파 및 가중치 업데이트
  5. 평가 및 로깅
    • 주기적으로 평가 환경에서 성능 측정
    • 보상 변화 시각화

8.3 전처리 함수 구현

픽셀 데이터를 효율적으로 학습하려면 전처리가 필수입니다.

import cv2
import numpy as np

def preprocess_frame(frame):
    # 흑백 변환
    gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
    # 리사이즈
    resized = cv2.resize(gray, (84, 84), interpolation=cv2.INTER_AREA)
    return resized.astype(np.uint8)

def stack_frames(stacked_frames, new_frame, is_new_episode):
    frame = preprocess_frame(new_frame)
    if is_new_episode:
        stacked_frames = [frame] * 4
    else:
        stacked_frames.append(frame)
        stacked_frames.pop(0)
    return np.stack(stacked_frames, axis=0), stacked_frames

8.4 CNN Q-네트워크 정의

import torch
import torch.nn as nn

class PongCNN(nn.Module):
    def __init__(self, in_channels, num_actions):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(in_channels, 32, kernel_size=8, stride=4), nn.ReLU(),
            nn.Conv2d(32, 64, kernel_size=4, stride=2), nn.ReLU(),
            nn.Conv2d(64, 64, kernel_size=3, stride=1), nn.ReLU()
        )
        self.fc = nn.Sequential(
            nn.Linear(64*7*7, 512), nn.ReLU(),
            nn.Linear(512, num_actions)
        )

    def forward(self, x):
        x = x / 255.0  # 정규화
        x = self.features(x)
        x = x.view(x.size(0), -1)
        return self.fc(x)

8.5 리플레이 메모리 및 ε-greedy 정책

앞서 구현한 NumPy 고정 크기 버퍼와 ε-greedy 정책을 그대로 사용합니다.
ε는 학습이 진행될수록 선형 혹은 지수적으로 감소시킵니다.


8.6 학습 루프

for step in range(total_steps):
    # 행동 선택
    action = select_action(q_net, state_stack, step, eps_start, eps_end, eps_decay)
    
    # 환경 실행
    next_obs, reward, terminated, truncated, _ = env.step(action)
    done = terminated or truncated
    
    # 상태 스택 업데이트
    next_state_stack, stacked_frames = stack_frames(stacked_frames, next_obs, done)
    
    # 경험 저장
    buffer.add(state_stack, action, reward, next_state_stack, done)
    
    state_stack = next_state_stack
    
    # 학습
    if step > start_learning and step % train_interval == 0:
        train_step(q_net, target_net, buffer, optimizer)
    
    # 타겟 네트워크 업데이트
    if step % target_update_interval == 0:
        target_net.load_state_dict(q_net.state_dict())
    
    # 에피소드 종료 처리
    if done:
        obs, _ = env.reset()
        state_stack, stacked_frames = stack_frames([], obs, True)

8.7 학습 안정성을 위한 팁

  1. 학습률: 1e-4 ~ 5e-5 권장
  2. 배치 크기: 32로 시작, GPU 여유 시 64
  3. 리플레이 버퍼 크기: 1,000,000
  4. 프레임 스킵: 동일 행동을 4프레임 유지하여 속도 향상
  5. 클리핑: 보상 클리핑(-1, 0, 1)으로 안정화

8.8 성능 지표

Pong 학습에서는 다음과 같은 지표를 주로 사용합니다.

  • 에피소드 평균 보상: -21에서 +21 사이
  • 승률: 에이전트가 게임에서 승리한 비율
  • 학습 속도: 목표 성능 도달까지 걸린 스텝 수

8.9 예상 결과

일반적으로 Pong 환경에서는 수백만 프레임 학습 후 다음과 같은 결과를 얻습니다.

  • 초기: 무작위 플레이, 평균 보상 약 -20
  • 중기: 점점 공을 받아치는 비율 증가
  • 후기: 상대를 압도, 평균 보상 +18 이상

 

9장 – 성능 업그레이드 전략


9.1 DQN의 한계와 확장의 필요성

기본 DQN은 뛰어난 성능을 보여주지만, 다음과 같은 한계가 존재합니다.

  1. Q값 과추정(Overestimation)
    • 최대 연산(max⁡\max)이 항상 과대평가 경향을 유발
  2. 데이터 효율성 부족
    • 모든 경험을 동일 확률로 샘플링
  3. 상태 가치와 행동 가치의 혼합
    • 상태의 중요도와 행동 선택의 중요도가 명확히 구분되지 않음
  4. 정책 탐험의 제한
    • ε-greedy 방식은 탐험 다양성이 부족

이 문제들을 해결하기 위해 다양한 DQN 변형 기법들이 제안되었습니다.


9.2 Double DQN (DDQN)

개념: Q값 과추정을 완화하기 위해 행동 선택과 평가를 분리

  • 기존 DQN: max⁡a′Qtarget(s′,a′)\max_{a'} Q_{\text{target}}(s', a') 사용
  • DDQN: 행동 선택은 Online Network, 평가만 Target Network로 수행

수식:

a∗=arg⁡max⁡a′Qonline(s′,a′)a^* = \arg\max_{a'} Q_{\text{online}}(s', a') y=r+γQtarget(s′,a∗)y = r + \gamma Q_{\text{target}}(s', a^*)

 

장점:

  • 과추정 완화 → 안정적인 학습
  • Pong에서 승률과 평균 보상 모두 향상

9.3 Prioritized Experience Replay (PER)

개념: TD 오차(예측값과 목표값의 차이)가 큰 경험을 우선 학습

  • 중요한 샘플은 더 자주 학습
  • 덜 중요한 샘플은 확률적으로 선택

장점:

  • 학습 효율 증가
  • 희귀 이벤트(중요 상태) 학습 강화

주의:

  • 샘플링 편향 보정을 위해 중요도 가중치(IS Weight) 사용 필요

9.4 Dueling DQN

개념: 상태 가치(Value)와 행동의 상대적 가치(Advantage)를 분리

  • Q값을 Q(s,a)=V(s)+A(s,a)Q(s,a) = V(s) + A(s,a)로 분해
  • 불필요한 상태-행동 결합 학습 부담 감소

장점:

  • 상태 가치가 명확히 학습되어, 행동에 상관없이 좋은 상태를 평가 가능
  • 정책 개선 속도 향상

9.5 Noisy DQN

개념: 가중치에 노이즈를 추가해 탐험 강화

  • ε-greedy 대신 네트워크 자체가 확률적 행동을 선택
  • 학습 과정에서 노이즈 크기 자동 조정

장점:

  • 더 다양한 상태 탐험
  • 특히 보상이 희소한 환경에서 효과적

9.6 Rainbow DQN

개념: 위에서 소개한 모든 기법을 결합한 종합 모델

  • DDQN + PER + Dueling + Noisy + Categorical DQN + N-step Return
  • Mnih 이후 아타리 벤치마크에서 SOTA 달성

장점:

  • 대부분의 환경에서 개별 기법보다 우수한 성능
  • 다만 구현 복잡도가 높고, 하이퍼파라미터 튜닝 부담 큼

9.7 Pong에서의 비교 실험   

알고리즘 평균 보상(최종) 수렴 스텝 구현 난이도
DQN +18 2.5M 낮음
DDQN +19 2.0M 중간
PER+DQN +20 1.8M 중간
Dueling +19 2.0M 중간
Rainbow +21 1.5M 높음

9.8 구현 시 고려 사항

  1. 계산 자원: PER과 Rainbow는 메모리와 CPU 부하가 큼
  2. 튜닝 난이도: 기법이 복잡해질수록 하이퍼파라미터 조정 필수
  3. 환경 특성 맞춤 적용: 모든 환경에서 Rainbow가 최고인 것은 아님

 

10장 – 학습 중 만나는 문제와 해결책


10.1 불안정한 수렴

문제

DQN 학습 그래프가 꾸준히 오르지 않고 큰 변동을 보이며 불안정하게 수렴하거나,
어느 순간 성능이 급격히 하락하는 현상이 발생합니다.

원인

  1. 타겟 네트워크 업데이트 주기 불적절
    • 너무 잦으면 목표값 변동이 심해져 발산 위험
    • 너무 드물면 목표값이 오래된 정책에 맞춰져 학습 속도 저하
  2. 학습률(learning rate) 과다
    • 큰 업데이트 폭으로 인해 Q값이 진동하거나 발산

해결책

  • 타겟 네트워크 업데이트 주기: 1,000~5,000 스텝 범위에서 튜닝
  • 학습률 감소 스케줄 적용
  • 그라디언트 클리핑(예: clip_grad_norm_)

10.2 Q값 과추정(Overestimation)

문제

행동 가치 추정이 실제보다 높게 형성되어, 잘못된 행동을 선호하게 되는 현상

원인

  • 최대 연산(max⁡\max)이 추정 오차를 항상 양의 방향으로 누적

해결책

  • Double DQN 사용: 행동 선택과 평가를 분리
  • 목표값 계산 시 샘플링된 액션에만 Q값 추정

10.3 탐험 부족(Exploration Deficiency)

문제

ε-greedy 전략에서 ε가 너무 빨리 줄어들면, 학습이 초기에 수집한 제한된 상태 데이터에 과적합

해결책

  • ε 감소 속도 늦추기: 1M~2M 스텝에 걸쳐 서서히 감소
  • Noisy DQN 사용하여 신경망 자체가 확률적 행동 선택
  • 주기적으로 ε를 일시적으로 증가시켜 재탐험

10.4 치명적 망각(Catastrophic Forgetting)

문제

오래전에 학습한 좋은 정책을 새로운 데이터가 덮어써서 잊어버리는 현상

해결책

  • 리플레이 버퍼 크기 확대
  • Prioritized Replay로 중요한 과거 경험 재학습
  • 모델 가중치 주기적 백업 후, 성능 저하 시 롤백

10.5 보상 희소성(Sparse Reward)

문제

보상이 거의 주어지지 않는 환경에서 학습 진행이 극도로 느려짐

해결책

  • 보상 셰이핑(Reward Shaping): 중간 목표 달성에 보상 추가
  • Imitation Learning: 사람 플레이 데이터를 초기 정책 학습에 활용
  • Curiosity-driven Exploration: 예측 불가능한 상태에 보상 부여

10.6 데이터 효율 저하

문제

많은 샘플을 사용하지만 학습 속도가 느림

해결책

  • N-step Return 사용: 단기 목표 대신 장기 보상 반영
  • 병렬 환경 실행으로 다양한 데이터 수집
  • 미니배치 크기와 학습 빈도 최적화

10.7 환경 특이 문제

  • 랜덤성 높은 환경: 시드 고정 및 평균 성능 평가 필수
  • 시뮬레이터 지연: 프레임 스킵 적용
  • 환경 API 변경: Gymnasium 버전 호환성 확인

10.8 Pong 환경에서 실전 적용

Pong 학습 중 발생했던 실제 문제 사례:

  • 초기 학습률 1e-4로 시작했더니 성능이 -21에서 벗어나지 못함
    → 5e-5로 낮추자 안정적 상승
  • ε를 100k 스텝에 걸쳐 줄였더니 탐험 부족 발생
    → 500k로 확장해 문제 해결
  • 타겟 네트워크 업데이트를 10k로 했더니 진동 발생
    → 2k로 줄여 안정화

 

11장 – 강화학습의 미래와 응용 분야


11.1 강화학습의 현재 위치

심층 강화학습(DRL)은 2013년 DQN의 등장 이후,
게임 분야에서 인간 수준 이상의 성능을 달성하며 주목받았습니다.
이제 DRL은 단순한 연구 주제를 넘어, 실제 산업 문제 해결에 적용되는 단계로 발전하고 있습니다.

현재까지의 특징:

  • 게임: Atari, StarCraft II, Dota 2 등 복잡한 환경에서 우수한 성능
  • 로보틱스: 시뮬레이션 기반 학습으로 물리 환경 제어
  • 금융: 거래 전략, 리스크 관리
  • 추천 시스템: 사용자 맞춤형 콘텐츠 제공

11.2 향후 기술 발전 방향

1. 표본 효율성(Sample Efficiency) 향상

  • 현재 DRL은 막대한 양의 데이터가 필요
  • 모델 기반 강화학습(Model-based RL), 전이학습(Transfer Learning)을 통해 데이터 요구량 감소

2. 안정성과 신뢰성 강화

  • 안전한 탐험(Safe Exploration)
  • 보상 모델의 검증 및 해킹 방지(Reward Hacking 방지)

3. 대규모 환경 확장

  • 다중 에이전트(Multi-Agent) 환경에서의 협력 및 경쟁
  • 대규모 분산 학습 시스템 적용

4. 인간-에이전트 상호작용

  • 인간 피드백 기반 학습(RLHF)
  • 사용자가 직접 보상 신호를 주어 정책 개선

11.3 주요 응용 분야

1. 게임 AI

  • e스포츠 경기 분석 및 자동 전략 생성
  • 절차적 콘텐츠 생성(Procedural Content Generation)

2. 로보틱스

  • 제조업 로봇의 최적 경로 계획
  • 가정용 로봇의 자율 동작 학습

3. 금융

  • 강화학습 기반 포트폴리오 관리
  • 초단타 거래(HFT) 전략 개발

4. 물류 및 교통

  • 창고 물류 로봇의 경로 최적화
  • 교통 신호 제어 최적화

5. 에너지

  • 전력망의 부하 분산
  • 재생에너지 발전량 예측 및 제어

11.4 강화학습과 다른 AI 분야의 융합

  • 강화학습 + 자연어 처리(NLP): 대화형 에이전트의 의사결정
  • 강화학습 + 컴퓨터 비전(CV): 자율주행 차량 환경 인식과 경로 계획
  • 강화학습 + 생성 모델: 창작 및 디자인 자동화

11.5 산업 적용 시 고려 사항

  1. 데이터 수집 비용: 실제 환경에서의 시행착오는 비용이 클 수 있음
    → 시뮬레이션 기반 사전 학습 후 실제 환경 전이
  2. 실시간 처리: 금융, 로보틱스 등에서는 지연 없는 의사결정 필수
  3. 규제 및 윤리: 자율 시스템의 의사결정 책임 소재, 데이터 편향 문제

11.6 미래 시나리오

  • 로봇이 강화학습을 통해 가정, 병원, 우주 탐사 등에서 자율적으로 임무 수행
  • 개인 맞춤형 AI가 실시간으로 학습하며, 사용자의 선호를 정확히 반영
  • 대규모 분산 강화학습 시스템이 복잡한 사회·경제 모델을 시뮬레이션하여 정책 결정 지원

11.7 마무리

강화학습은 여전히 연구와 응용의 가능성이 무궁무진한 분야입니다.
DQN에서 출발한 이 여정은 이제 다양한 알고리즘과 산업 적용으로 확장되고 있으며,
머지않아 우리의 일상과 산업 전반에 깊숙이 스며들 것입니다.


 

에필로그 – 끝이 아닌 새로운 시작


배움의 여정을 돌아보며

우리는 이 책을 통해 강화학습과 딥러닝의 만남이라는 흥미로운 여정을 걸어왔습니다.
처음에는 Q-러닝의 기본 개념에서 출발해,
DQN의 구조와 작동 원리를 이해하고,
CartPole과 Pong 같은 환경에서 직접 구현하며 실험을 해보았습니다.

중간에는 타겟 네트워크, 리플레이 메모리, CNN 등 핵심 기술을 배웠고,
나아가 Double DQN, Prioritized Replay, Dueling DQN, Rainbow와 같은 성능 향상 기법도 살펴보았습니다.
마지막으로, 학습 중 마주치는 문제와 해결책, 그리고 강화학습의 미래와 응용 가능성까지 논의했습니다.


왜 강화학습을 계속 공부해야 하는가

강화학습은 단순히 “게임을 잘하는 AI”를 만드는 기술이 아닙니다.
이는 스스로 환경과 상호작용하며 최적의 행동 전략을 찾아내는 일반적인 문제 해결 프레임워크입니다.
그렇기 때문에 로보틱스, 금융, 에너지, 물류, 헬스케어 등 수많은 산업에서 잠재력이 큽니다.

더 나아가,
강화학습은 AI의 자율성을 구현하는 핵심 분야이기도 합니다.
즉, 사람이 모든 규칙을 정의하지 않아도 AI가 스스로 목표를 달성하는 방법을 학습하게 만드는 것입니다.


앞으로의 학습 방향

이 책을 다 읽었다고 해서 여정이 끝난 것은 아닙니다.
오히려 이제부터가 진짜 시작입니다.

  1. 깊이 있는 실습
    • 본문에서 다룬 CartPole과 Pong을 넘어서, Breakout, Space Invaders, Montezuma’s Revenge 등 난이도 있는 아타리 게임에 도전해보세요.
    • PyBullet, Mujoco 같은 물리 시뮬레이터 환경에서 로봇 제어 학습 실험을 해보는 것도 좋습니다.
  2. 고급 알고리즘 탐구
    • Rainbow를 넘어 SAC(Soft Actor-Critic), PPO(Proximal Policy Optimization), A3C/A2C 같은 정책 기반 방법을 학습해 보세요.
    • 모델 기반 강화학습(MB-RL)도 흥미로운 주제입니다.
  3. 연구 논문 읽기 습관
    • NeurIPS, ICML, ICLR 같은 주요 AI 학회 논문에서 강화학습 관련 최신 연구를 꾸준히 읽고 구현해보세요.
  4. 프로젝트와 공유
    • 학습한 내용을 GitHub나 블로그에 공유하면 커뮤니티와의 교류를 통해 더 빠르게 성장할 수 있습니다.

마지막 당부

강화학습은 긴 호흡이 필요한 분야입니다.
한두 번의 시도로는 만족스러운 성능이 나오지 않을 수도 있습니다.
하지만 매 시행착오에서 얻는 통찰은 곧 여러분만의 강력한 무기가 됩니다.

이 책을 덮는 지금,
여러분이 느낀 작은 호기심 하나가 언젠가는
세상을 바꾸는 거대한 프로젝트의 씨앗이 될지도 모릅니다.

그러니 계속 실험하고, 기록하고, 나누세요.
강화학습의 다음 이야기의 주인공은 바로 여러분입니다.


 

부록 – 실습과 참고 자료


부록 A. CartPole DQN 학습 코드 (저작권 안전 변형 버전)

이 코드는 본문 5장에서 다룬 학습 절차를 바탕으로, 학습 재현성과 안정성을 강화한 버전입니다.

import random
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import gymnasium as gym
from collections import deque
from dataclasses import dataclass

@dataclass
class Config:
    gamma: float = 0.99
    lr: float = 1e-3
    buffer_size: int = 50000
    batch_size: int = 64
    start_learning: int = 1000
    train_interval: int = 4
    target_update: int = 1000
    eps_start: float = 1.0
    eps_end: float = 0.05
    eps_decay: int = 10000
    total_steps: int = 50000
    seed: int = 42

class QNet(nn.Module):
    def __init__(self, obs_dim, act_dim):
        super().__init__()
        self.layers = nn.Sequential(
            nn.Linear(obs_dim, 128), nn.ReLU(),
            nn.Linear(128, 128), nn.ReLU(),
            nn.Linear(128, act_dim)
        )
    def forward(self, x):
        return self.layers(x)

class ReplayBuffer:
    def __init__(self, size):
        self.buffer = deque(maxlen=size)
    def add(self, s, a, r, ns, d):
        self.buffer.append((s, a, r, ns, d))
    def sample(self, batch_size):
        batch = random.sample(self.buffer, batch_size)
        s, a, r, ns, d = map(np.array, zip(*batch))
        return s, a, r, ns, d
    def __len__(self):
        return len(self.buffer)

def select_action(q_net, state, step, cfg):
    eps = cfg.eps_end + (cfg.eps_start - cfg.eps_end) * \
          np.exp(-1.0 * step / cfg.eps_decay)
    if random.random() < eps:
        return env.action_space.sample()
    with torch.no_grad():
        return q_net(torch.FloatTensor(state).unsqueeze(0)).argmax().item()

def train_step(q_net, target_net, optimizer, buffer, cfg):
    if len(buffer) < cfg.batch_size:
        return
    s, a, r, ns, d = buffer.sample(cfg.batch_size)
    s = torch.FloatTensor(s)
    ns = torch.FloatTensor(ns)
    a = torch.LongTensor(a)
    r = torch.FloatTensor(r)
    d = torch.FloatTensor(d)

    q_values = q_net(s).gather(1, a.unsqueeze(1)).squeeze(1)
    with torch.no_grad():
        max_next_q = target_net(ns).max(1)[0]
        target = r + cfg.gamma * max_next_q * (1 - d)
    loss = nn.MSELoss()(q_values, target)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

cfg = Config()
env = gym.make("CartPole-v1")
env.reset(seed=cfg.seed)
torch.manual_seed(cfg.seed)
np.random.seed(cfg.seed)
random.seed(cfg.seed)

q_net = QNet(env.observation_space.shape[0], env.action_space.n)
target_net = QNet(env.observation_space.shape[0], env.action_space.n)
target_net.load_state_dict(q_net.state_dict())
optimizer = optim.Adam(q_net.parameters(), lr=cfg.lr)
buffer = ReplayBuffer(cfg.buffer_size)

state, _ = env.reset()
for step in range(cfg.total_steps):
    action = select_action(q_net, state, step, cfg)
    next_state, reward, terminated, truncated, _ = env.step(action)
    done = terminated or truncated
    buffer.add(state, action, reward, next_state, done)
    state = next_state

    if step > cfg.start_learning and step % cfg.train_interval == 0:
        train_step(q_net, target_net, optimizer, buffer, cfg)

    if step % cfg.target_update == 0:
        target_net.load_state_dict(q_net.state_dict())

    if done:
        state, _ = env.reset()

env.close()

부록 B. Pong DQN 학습 파이프라인 요약

  1. 전처리
    • 210x160 RGB → 84x84 Grayscale
    • 최근 4프레임 스택
  2. CNN 구조
    • Conv(32, 8x8, stride=4) → ReLU
    • Conv(64, 4x4, stride=2) → ReLU
    • Conv(64, 3x3, stride=1) → ReLU
    • FC(512) → ReLU → Q값 출력
  3. 학습
    • 리플레이 버퍼에서 무작위 샘플링
    • Double DQN 또는 PER 적용 가능
  4. 평가
    • ε = 0으로 설정, 다수 에피소드 평균 점수 기록

부록 C. 주요 라이브러리 버전

라이브러리 버전 권장
Python 3.10+
Gymnasium 0.29+
PyTorch 2.0+
NumPy 1.24+
OpenCV 4.7+

부록 D. 추천 학습 자료

  1. 논문
    • Mnih et al., 2015 – Playing Atari with Deep Reinforcement Learning
    • Van Hasselt et al., 2016 – Deep Reinforcement Learning with Double Q-learning
    • Hessel et al., 2018 – Rainbow: Combining Improvements in Deep RL
  2. 도서
    • Sutton & Barto – Reinforcement Learning: An Introduction (2nd Edition)
    • Maxim Lapan – Deep Reinforcement Learning Hands-On
  3. 강의
    • David Silver’s RL Course (UCL)
    • OpenAI Spinning Up

강화학습과 딥러닝, DQN으로 배우는 게임 AI의 모든 것, 서항주 지음

반응형
사업자 정보 표시
올딩 | 서항주 | 경기도 성남시 중원구 성남동 3313번지 B동 101호 | 사업자 등록번호 : 119-18-42648 | TEL : 02-6901-7078 | Mail : jason@allding.co.kr | 통신판매신고번호 : 제2012-경기성남-1364호 | 사이버몰의 이용약관 바로가기

댓글

💲 추천 글