2017년 10월 19일 목요일

DQN

DQN(Deep Q-Network)은 딥 신경망(DNN)을 이용하는 강화학습(Reinforcement Learning)의 일종이다.

환경 $env$를 제어하는 강화학습에서 action $a$에 대한 확률을 결정하는 Q(Quality) 함수는 $Q(s,a)$로 주어진다. 상태 $s$에 대해 적절한 행동 $a$를 결정하는 정책이 들어 있다.

적절하다는 것은 주어진 환경 $env$의 현재 상태 $s$에서 action $a$를 선택했을 때 다음 단계에서 끝 단계 작업(episode) 종결 시까지 얻을 수 있는 보상 합의 최대값을 줄 수 있다는 것이다. 이런 Q함수는 이상적이지만 실제로 존재할 수 없는 일종의 매직 함수이다.

DNN은 $Q(s,a)$ 함수를 근사한다. Q는 주어진 상태 $s$를 입력 받아 여러 액션 중 하나의 $a$를 줄 수 있어야 한다. Q를 근사하는 DNN은 입력 $s$를 취해 여러 $a$에 대한 확률값 출력을 제공 한다.



매직 함수인 Q를 실제 계산하기 위해서는 현 상태 s에서 작업 종결 끝까지 반복 수행하면서 단계별 보상을 더해서 구한다. 그러나 이는 불가능하므로, 근사적으로 구하는 방법을 취한다.

이 과정은 다음과 같다.
현 상태 $s$에서 제어 대상 환경 $env$에 어떤 action을 가하고, 어떤 reward가 발생하는지 본다. 이 reward를 이용하여 Q를 갱신하고, 변경된 상태를 다시 갱신된 Q에 넣어 추출한 $a$를 $env$에 가하고 어떤 reward가 발생하는지를 살펴보고 Q를 또 갱신한다. 이러한 과정을 수없이 반복하다보면 초기에는 매직 Q와 멀었던 Q 함수가 점점 이상적인 Q에 가까와 지게 된다.

정리를 해보면 DQN의 요소에는

1. $Q(s,a)$를 표현하는 DNN이 있고
2. 액션 $a$를 가해 상태를 $s$에서 $s'$로 바꿀 환경 $env$가 존재한다.

환경 $env$는 현재 상태 $s$에서 액션 $a$를 가할 경우, 상태를 $s'$로 바꾸고, 보상 값을 리턴한다.

$s', r, d = env.step(a)$

의 형태인데, $a$를 입력으로 받아 $s$는 $s'$가 되고, 보상 $r$과 현재 episode 종결여부 $d$를 리턴한다.




통상 DNN의 학습을 위해서는 predict와 label이 필요하며 두 값의 차이가 loss이고 DNN은 loss를 최소화 하도록 내부 파라메터들을 갱신하게 된다.

predict와 label을 정의하기 위해 $env$에 가해지는 한 단계만의 액션을 생각해 보자.
현 단계 $Q(s,a)$를 표현하는 DNN이 있다. 먼저 $env$를 한 단계 전진 시키기 위해서는 $env$에 가할 $a$가 필요하다.

(1) $a$를 구하기 위해 현 상태 $s$를 DNN에 입력하여 DNN이 주는 최적의 $a$를 택한다. 이 $a$는 갱신전 DNN(즉, Q)이 주는 $a$이다.
(2) $a$를 $env$에 가해 $s', r, d$를 얻는다. 이 때, 새로 생성된 $s'$를 이용한다. DNN에 넣어 새로운 $Q(s', :)$를 만들어 낼 수 있다.

벨만 방정식 (Bellman equation)은 갱신된 Q값이 근사적으로 다음과 같음을 보여준다.

$Q(s,a) = r + max Q(s', :)$

갱신된 Q값은 $env$에 $a$를 가해 얻은 보상 $r$에다 새 상태 $s'$에 대한 Q값 중 최대값의 합으로 주어진다.

여기까지 계산하면 이전의 Q와 갱신된 Q가 얻어진다.

predict는 현재 Q(즉 현재의 DNN)에서 $s$를 넣어 나오는 $a$를 취하고, label은 Bellman식을 통해 계산된 값을 취한다.
그런데, Bellman식은 초기 Q에 $a$를 가해 만든 새로운 Q값이므로 해당되는 그 $a$의 값에 대해서만 갱신된 값이다.

즉, $a$의 액션 공간이 0~2까지로 3개라고 하면 초기 $Q(s)=DNN(s)=a[0:3]$이고, $env$에 가해준 $a$가 $a[1]$이었다면,
label역할을 하는 갱신 $a$는 3개 값 중, $a[0], a[2]$는 같고, $a[1]$만 달라진,
{ $a[0],\ r+maxQ(s', :),\ a[2]$ }이다.

따라서

predict = {$a[0], a[1], a[2]$}
label = {$a[0], r+maxQ(s', :), a[2]$}

이다.