포스트

파이썬과 케라스로 배우는 강화학습 | 강화학습 기초 10

파이썬과 케라스로 배우는 강화학습 Chapter 4 정리

파이썬과 케라스로 배우는 강화학습 | 강화학습 기초 10

책 정보 📖

  • 책 제목: 파이썬과 케라스로 배우는 강화학습
  • 글쓴이: 이웅원, 양혁렬, 김건우, 이영무, 이의령
  • 출판사: 위키북스
  • 발행일: 2020년 04월 07일
  • 챕터: Chapter 4. 강화학습 기초 3: 그리드월드와 큐러닝

책소개

강화학습의 기초부터 최근 알고리즘까지 친절하게 설명합니다! ‘알파고’로부터 받은 신선한 충격으로 많은 사람들이 강화학습에 관심을 가지기 시작했다. 하지만 처음 강화학습을 공부하는 분들을 위한 쉬운 자료나 강의를 찾아보기 어려웠다. 외국 강의를 통해 어렵게 이론을 공부하더라도 강화학습을 구현하는 데는 또 다른 장벽이 있었다. 이 책은 강화학습을 처음 공부하는 데 어려움을 겪는 독자를 위해 이론부터 코드 구현까지의 가이드를 제시한다.

특히 이번 개정판에서는 텐서플로 버전업에 맞춰서 코드를 업데이트하고 전반적인 이론 및 코드 설명을 개선했다. 그리고 실무에서 많이 활용될 수 있는 연속적 액터-크리틱 알고리즘을 추가했다.

주요 내용

  • 강화학습의 기초 - SARSA 코드 및 한계

SARSA 알고리즘의 실제 구현 코드를 분석하고, SARSA가 가지는 한계점에 대해 알아보자. 이를 통해 다음 단계인 큐러닝의 필요성을 이해할 수 있다.


SARSAgent 클래스 구현

생성자 (init)

1
2
3
4
5
6
7
def __init__(self, actions):
    self.actions = actions
    self.step_size = 0.01
    self.discount_factor = 0.9
    self.epsilon = 0.1
    # 0을 초기값으로 가지는 큐함수 테이블 생성
    self.q_table = defaultdict(lambda: [0.0, 0.0, 0.0, 0.0])

주요 멤버 변수

  • actions: 에이전트가 할 수 있는 행동 (그리드월드에서는 [0, 1, 2, 3])
  • discount_factor: 할인율 0.9
  • epsilon: ε-탐욕 정책의 탐험 확률 0.1
  • step_size: 스텝사이즈 0.01
  • q_table: 큐함수를 저장하는 딕셔너리, self.q_table[상태][행동]으로 접근할 수 있다

큐 테이블의 특징

다이내믹 프로그래밍에서는 모든 상태의 가치함수를 벨만 방정식을 통해 한 번에 업데이트했지만, SARSA에서는 에이전트가 어떤 상태를 방문하면 그 상태의 큐함수만 업데이트한다.

이를 담을 자료구조가 q_table이다. defaultdict(lambda: [0.0, 0.0, 0.0, 0.0])는 새로운 키 값을 받을 때 람다 함수의 값으로 자동 초기화해준다.


SARSA 에이전트의 환경 상호작용

상호작용 과정

  1. 현재 상태에서 ε-탐욕 정책에 따라 행동을 선택한다
  2. 선택한 행동으로 환경에서 한 타임스텝을 진행한다
  3. 환경으로부터 보상과 다음 상태를 받는다
  4. 다음 상태에서 ε-탐욕 정책에 따라 다음 행동을 선택한다
  5. $(s, a, r, s^\prime, a^\prime)$을 통해 큐함수를 업데이트한다

행동 선택: get_action 메소드

1
2
3
4
5
6
7
8
9
10
11
# 입실론 탐욕 정책에 따라서 행동을 반환
def get_action(self, state):
    if np.random.rand() < self.epsilon:
        # 무작위 행동 반환
        action = np.random.choice(self.actions)
    else:
        # 큐함수에 따른 행동 반환
        state = str(state)
        q_list = self.q_table[state]
        action = arg_max(q_list)
    return action

메소드 설명

어떤 특정한 상태를 입력으로 넣었을 때 행동을 출력하는 함수다:

  • ε-탐욕 정책에 따라 행동을 선택한다
  • state = str(state)를 통해 string으로 변환해야 딕셔너리의 키 값으로 사용할 수 있다
  • arg_max()를 통해 최대의 큐함수를 가져온다

arg_max 함수

1
2
3
4
def arg_max(q_list):
    max_idx_list = np.argwhere(q_list == np.amax(q_list))
    max_idx_list = max_idx_list.flatten().tolist()
    return random.choice(max_idx_list)
  • np.argwhere(q_list == np.amax(q_list))는 q_list에서 가장 큰 값을 가지는 값의 모든 인덱스를 가져온다
  • 모든 인덱스 중에서 랜덤하게 반환한다

학습: learn 메소드

1
2
3
4
5
6
7
8
# <s, a, r, s', a'>의 샘플로부터 큐함수를 업데이트
def learn(self, state, action, reward, next_state, next_action):
    state, next_state = str(state), str(next_state)
    current_q = self.q_table[state][action]
    next_state_q = self.q_table[next_state][next_action]
    td = reward + self.discount_factor * next_state_q - current_q
    new_q = current_q + self.step_size * td
    self.q_table[state][action] = new_q

학습 과정

현재 상태와 다음 상태의 행동을 선택해서 샘플 $(s, a, r, s^\prime, a^\prime)$을 얻으면 에이전트는 학습을 진행한다.

\[Q(S_t,A_t) \leftarrow Q(S_t,A_t)+ \alpha(R_{t+1} + \gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t))\]

SARSA의 큐함수 업데이트 식이다:

  • new_q = current_q + self.step_size * (reward + self.discount_factor * next_state_q - current_q)
  • 다음 상태를 업데이트하는 것이 아닌 현재 상태를 업데이트하는 것임을 헷갈리지 말자

SARSA 실행 결과

살사의 실행 화면 살사의 실행 화면


SARSA의 한계

그리드월드의 SARSA에서 충분한 탐험을 위해 ε-탐욕 정책을 사용했다.

문제 상황 분석

살사의 학습 과정 중의 한 순간 살사의 학습 과정 중의 한 순간

$a$는 탐욕 정책에 따른 행동이고 $a^\prime$은 탐험에 따른 결과라고 가정하자.

온-폴리시의 딜레마

  1. 업데이트 문제
    • 현재 상태의 큐함수 $Q(s, a)$는 다음 상태의 큐함수인 $Q(s^\prime, a^\prime)$과 평균을 취하는 업데이트를 하게 된다
    • 문제는 $Q(s^\prime, a^\prime)$이 마이너스 보상을 주는 큐함수이기 때문에 $Q(s, a)$의 값이 낮아지는 결과가 나오게 된다
  2. 잘못된 학습
    • 업데이트 이후 다시 현재 상태에 에이전트가 오게 되면 오른쪽으로 가는 행동 $a$를 좋지 못하다고 판단한다
    • 왜냐하면 행동 $a$의 큐함수가 낮을 것이고 에이전트는 ε-탐욕 정책에 따라 움직이기 때문이다
    • 일종의 갇히는 현상이 발생하는 것이다
  3. 온-폴리시의 근본적 문제
    • SARSA는 온-폴리시 시간차 제어, 즉 자신이 행동하는 대로 학습하는 시간차 제어다
    • 탐험을 위해 선택한 ε-탐욕 정책 때문에 오히려 최적 정책을 학습하지 못하고 잘못된 정책을 학습하게 된다

탐험의 필요성과 딜레마

그럼에도 불구하고 강화학습에서 탐험은 절대적으로 필요한 부분이다. 충분한 탐험 없이는 최적 정책을 학습하지 못하기 때문이다.

이 딜레마를 해결하기 위한 것이 오프-폴리시 시간차 제어, 다른 말로 큐러닝(Q-Learning)이다.


SARSA의 특징 정리

장점

  • 환경 모델 없이 학습 가능
  • 실시간 업데이트 가능
  • 구현이 비교적 간단함

단점

  • 온-폴리시의 한계: 탐험 정책이 학습에 직접 영향을 미침
  • ε-탐욕 정책으로 인한 잘못된 학습 가능성
  • 탐험과 활용의 딜레마를 근본적으로 해결하지 못함

SARSA에서 큐러닝으로

SARSA의 이러한 한계를 극복하기 위해 등장한 것이 큐러닝이다. 큐러닝은 오프-폴리시 방법으로, 행동하는 정책과 학습하는 정책을 분리함으로써 SARSA의 근본적인 문제를 해결한다.

다음 포스트에서는 큐러닝 알고리즘에 대해 자세히 알아보자.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.