본문 바로가기

Python

Policy Gradient Algorithms

원래는 아래 링크가 한글로 번역된 것을 찾을 수가 없어서 번역을 작성하고 공부하며 코드를 작성하려고 하였습니다. 그런데 어쩌다 보니 번역이 되어있는 페이지를 찾게되어 번역은 더이상 하지 않아도 되었습니다. 해당 링크를 공유하도록 하겠습니다. 그러나 실제로 한글로 구현하는 과정이 잘 설명되어 있는 곳도 없는 것 같고, 이미 관련 학과를 수료하신 전문적인 분들이 이론적으로 다루는 것이 대부분입니다.

 

저도 나름대로 국내 최고 전문가인 분들께 배우긴 했는데, 생각해보니 배경지식이 미흡한데 강화학습의 기반이 되는 이론을 배운 것이라 이해하기 힘들었습니다. 그래도 관련 업무를 해야하기에 관심은 많아 공부를 하려고 책이나 구현된 코드등을 검색해도 알고리즘 그 자체를 설명하면서 구현한 사람은 없어 보입니다. 

 

저는 솔직히 증명하는 과정을 이해하려고 하는건 아니고 강화학습의 알고리즘을 실제 코드로 전환하면 충분히 숙달된 수준이라고 생각합니다. 가급적이면 제가 이해한 내용과 최소의 구현을 통해 저를 포함한 다른분들께도 도움이 되면 좋겠다는 생각으로 이 글을 작성하니 좋은 참고가 되셨으면 좋겠습니다.

 

원문 : Policy Gradient Algorithms (lilianweng.github.io)

국내 번역 : [RL] Policy Gradient Algorithms (tistory.com)

 

========================================================

Policy Gradient

 

강화학습은 Agent가 최고의 Reward를 얻을 수 있는 최적의 전략을 찾는 것이 목표입니다. 일반적인 Deep Learing의 경우 예측하고자 하는 값과 실제값의 오차가 가장 작은 것을 찾는데 중점을 둡니다. 그래서 두 값의 오차가 작은 것을 찾을 수 있는 loss 함수를 사용합니다. (예 두 값의 차의 제곱이 0으로 수렴하는 함수 - Mean Squere Error) 하지만 강화학습의 경우 보통 잘하면 +점수 못하면 -점수로 설계를 하여 값이 최대로 커지는 방법을 사용합니다. 그래서 두 loss 함수의 방향이 달라집니다.

 

Gradient Descent는 일반적인 Deep Learning, Gradient Ascent는 강화학습에 사용한다고 생각하면 됩니다. MSE의 경우 앞에 -1을 곱한다고 상상해보겠습니다. 예측값이 10이고 실제값이 8라고 합니다. MSE 연산을 거치게되면 4가 됩니다. 여기에 -1을 곱하면 -4가 되겠죠. 이게 작아지는 방향이라고 하면 더 낮은 수 -5 이하의 숫자가 되게끔 학습하는 방식을 취하게 될겁니다. 이런 내용을 근거로 대부분의 강화학습의 loss 함수에는 -1을 곱하게 됩니다.

 

Policy Gradient Algorithms

 

상단에 공유된 링크에서 해당 Section부터 실제 알고리즘을 설명합니다. 저는 가급적이면 논문이나 알고리즘 그대로의 알고리즘을 구현하면서 공부하고 싶은데, 대부분의 경우 더 나은 수치를 위한 개선 사항들이 포함되어 있습니다. 저는 가급적 그대로 구현하고자 하였습니다. (예를 들면 Actor-Critic을 알고자 검색하면 A2C가 나옵니다.)

 

강화학습은 기본적으로 어떠한 시스템의 시뮬레이션이 필요하며, 시뮬레이션의 입력값은 Discrete 방식과 Continuous 방식이 있습니다. 강화학습을 공부하는데 유명한 시뮬레이션인 CatPole은 Discrete 방식입니다. 선택하는 문제뿐만 아니라 실수 입력할 경우를 대비한 강화학습도 필요합니다. 이를 위해 Pendulum을 사용하며 Continuous 방식입니다. 

  CartPole-v0 Pendulum-v1
입력 값 종류 Descrete Continuous
입력 범위 (action) 0 또는 1 $-2 \leq x \leq 2$
상태값 (state) 4개의 변수 3개의 변수
보상값 (reward) 0 또는 1 실수값 (음수)
한 게임 최대 횟수 200 200

 

강화학습은 Reward 설계가 매우 중요합니다. Actor-Critic을 구현해보면서 학습이 생각보다 너무 안되어 다방면으로 연구한결과 Reward를 수정하니까 유의미한 학습률을 기록했습니다. Hyper Parameter를 수정하는 형태 등으로 더 나은 값을 얻을 수는 있지만, 이는 모델을 최적화하는 과정이므로 따로 더 노력하진 않았습니다. 

 

CartPole의 경우 한개의 에피소드에 200 Stage까지 갈 수 있습니다. Reward에 아무런 튜닝을 하지 않았을 때 20 Stage까지 가면 20점 17 Stage까지 가면 17점 입니다. 생각해보면 두 개의 점수차이는 큰 차이가 나지 않는 것으로 보입니다. 특히 알고리즘에 따라 평균을 구하게 되면 더욱 차이가 발생하지 않습니다. 그래서 목표에 도달하지 않았을 때의 패널티가 굉장히 중요합니다. 그래서 저는 기본적으로 CartPole의 Reward를 다음과 같이 설계하였습니다.

 

# 목표에 도달하지 못하면 -1점, 일반적으로 동작할 땐 0.1점
reward = 0.1 if not done or i_iter >= 199 else -1

 

강화학습을 공부하려고 시작하면 대표적으로 REINFORCE, Actor-Critic를 처음 접하게 됩니다. 그래서 아래에 바로 언급되는 REINFORCE, Actor-Critic, A2C (A3C는 A2C를 확장한 형태이므로 제외) 3개의 알고리즘은 구현상에 큰 차이를 없게 만들 수 있습니다. 뭐 Off-Policy니 On-Policy니 하지만 실제로 구현하는데 있어서 큰 차이를 느끼긴 쉽지 않습니다.

 

하지만 이 문서에서 설명하는 REINFORCE, Actor-Critic는 On-Policy 형태이며 글의 의도상 게임 한판을 다 하면 (한 에피소드를 완료하면) 그간 모았던 State, Action, Reward, Next State 를 기록하여 한꺼번에 모델을 업데이트 합니다. 그런 내용을 담고 있는 수식이 바로 아래의 수식입니다.

 

$$\nabla_\theta J(\theta)=\mathbb{E}_\pi[Q^\pi(s,a)\nabla_\theta\ln\pi_\theta(a|s)]$$

 

물론 이 수식에서 $Q^\pi(s,a)$ 대신에 누적된 Reward를 표현하는 $Gt$를 사용해야합니다. 그러면 아래 REINFORCE에서 표현되는 알고리즘과 동일하게 작성을 할 수 있습니다. 그런데 제가 유심히 쳐다본 부분은 $\mathbb{E}_\pi$라는 Expectation, 즉 평균값입니다. 실제 구현을 하면 한번에 연산하는 형태를 취해야합니다.

 

이제 실제로 관심 가져야할 Actor-Critic 알고리즘은 구현상에 여러가지 애로사항이 있었습니다. 아무리 자료를 찾아봐도  Actor-Critic 알고리즘이 구현되지 않고 A2C 알고리즘이 구현되어 있습니다. 향후 찾아보시는 분들께 도움되었으면 좋겠습니다. 일단, REINFORCE, Actor-Critic, A2C의 loss 함수는 동일한 형태입니다. (Actor-Critic, A2C의 경우는 Actor 부분)

 

$$\begin{aligned}\nabla_\theta J(\theta)&=\mathbb{E}_{\pi_\theta }[\nabla_\theta\log\pi_\theta(s,a)Gt]\quad\text{REINFORCE}\\&=\mathbb{E}_{\pi_\theta }[\nabla_\theta\log\pi_\theta(s,a)Q^w(s,a)]\quad\text{Q Actor-Critic}\\&=\mathbb{E}_{\pi_\theta }[\nabla_\theta\log\pi_\theta(s,a)A^w(s,a)]\quad\text{Advanced Actor-Critic(A2C)}\\&=\mathbb{E}_{\pi_\theta }[\nabla_\theta\log\pi_\theta(s,a)\delta]\quad\text{TD Actor-Critic}\\\end{aligned}$$

 

뒷 부분만 변경이 되는데, Actor-Critic 알고리즘을 파해쳐기위해 $Q^w(s,a)$가 무엇인지 알 필요가 있습니다. Bellman optimality equation을 작성하면 다음과 같습니다.

 

$$Q_*(s,a)=R_s^a+\gamma\sum_{s^\prime \in S}P_{ss^\prime}^a V_*(s^\prime)$$

 

Actor는 정책이고 Critic은 정책값입니다. 위 수식을 조금 자세히 설명하면 각 Notation은 다음과 같은 의미입니다.

 

  • $R_s^a$ : 현재 State에서 Action을 취할 때 얻는 Reward
  • $P_{ss^\prime}^a$ : 현재 State에서 Action을 취해서 다음 State 갈 확률
  • $V_*(s^\prime)$ : 현재 State의 가치 혹은 현재 State에서 얻을 수 있는 Reward 값

우리는 Deep Learning으로 정책(Policy, $\pi$)을 설정하고 그 정책에서 정책값을 계산할 것이므로 이 수식을 아래와 같이 다시 작성할 수 있습니다. 

 

$$Q^{\pi^\theta}(s,a)=R_t+\gamma V^{\pi^\theta}(s^\prime)$$

 

정책을 담당하는 Actor에서 계산해야하는 정책값을 Critic에서 추정하게 끔 변형합니다. (원래 정책에서 정책값을 계산하는 것 자체가 어려워서 Critic에서 Actor의 정책값을 학습하는 Actor-Critic 알고리즘을 쓰는 겁니다.) 그래서 $\pi^\theta=w$로 치환하면 다음과 같이 수식을 작성할 수 있습니다.

 

$$Q^w(s,a)=R_t+\gamma V^w(s^\prime)$$

 

여기까지가 Actor-Critic 알고리즘의 설명입니다. Advanced Actor-Critic은 Baseline을 사용하는 건데 해당 내용은 상단에 설명되어있습니다. 그러므로 Baseline에 대한 설명은 넘기고 수식만 가져오면 $A(s,a)=Q(s,a)-V(s)$ 입니다. 우리는 어차피 $V(s)$ 값은 Critic으로 쉽게 알 수 있으므로 계산을 바로 할 수 있습니다.

 

마지막으로 TD Actor-Critic인데, 이는 다음 State의 값과 현재 State의 값의 차이를 계산해야합니다. 한가지 알아두어야할 수식은 $V(s_t) = R_{t+1}+\gamma V(s_{t+1})$ 입니다. 아주 이상적이라면 해당 수식은 성립해야합니다. 하지만 학습해야한다는 점을 고려하면 두 값은 같지 않습니다. 그래서 저 두 값의 차이를 TD error, $\delta$라 언급할 수 있습니다. 수식으로 다음과 같이 작성할 수 있습니다.

 

$$\delta=R_{t+1}+\gamma V(s_{t+1})-V(s_t)$$

 

사실 이렇게 되면 A2C와 TD Actor-Critic은 같은 알고리즘이라고 할 수 있습니다. 여기서 얻을 수 있는 중요한 것은 Critic 함수를 어떻게 업데이터 할 것인가를 알 수 있다는 것입니다. 위에 언급한 loss 함수는 전부 Actor의 loss 함수입니다. Actor-Critic에서 Critic은 어떻게 업데이트 해야할지 명확하진 않습니다. (사실 아래 Actor-Critic 알고리즘 구현할 때 많이 헤맸습니다.) 요약하면 바로 전에 언급한 TD error를 줄이는 방향으로 업데이트하면 됩니다.

 

즉 저 $\delta$가 0으로 수렴하는 방향으로 업데이트 하면되는데, Deep Learning 알고리즘 기준으로 l1, mse 등 아무거나 0으로 수렴하게 만드는 함수를 쓰면 됩니다. 

 

Advanced 함수를 만드는 것이랑 모양은 같지만, loss 함수를 만들때 유의해야할 점이 있습니다. 이러니 저러니 해도 결국 Gradient Descent 방식으로 Deep Learning 모델의 Parameter $\theta$를 업데이트 하는데, 이는 무언가의 변수를 편미분한다는 것을 뜻합니다. 편미분을 할 타겟을 명확히해아합니다.

 

  • Actor의 loss 함수에서 편미분의 대상은 $\nabla_\theta\log\pi_\theta(s,a)$입니다.
  • Critic의 loss 함수에서 편미분의 대상은 $V(s,a)$입니다.

저 둘을 제외한 나머지 값들은 미분이 되지 않도록 고정시켜야합니다.

 

(향후 소개할 알고리즘의 Notation과 다소 다를 수 있으나, 가급적 맞추려고 노력하였습니다.)

(아래 수식에도 따로 작성해 놓은 고찰이 있으니 참고해주세요.)

 

REINFORCE

REINFORCE (tistory.com)

 

REINFORCE

Policy Gradient Algorithms (tistory.com) Policy Gradient Algorithms 이 글은 아래 링크에 있는 페이지의 내용을 공부를 위해 한글로 번역(의역)한 것임을 알립니다. 나름의 이해를 돕기위해 첨언은 파란색으로..

altheacom.tistory.com

 

 

Actor-Critic

 

본문에 표기된 알고리즘은 다음과 같습니다.

 

  1. $s, \theta, w$를 랜덤으로 초기화합니다. 그리고 $\pi_\theta(a|s)$에서 $a$를 추출합니다.($a \sim \pi_\theta(a|s)$ :  $\pi_\theta(a|s)$ 규칙을 따르는 $a$, 혹은 $\pi_\theta(a|s)$ 에서 얻을 수 있는 $a$ 라는 의미입니다.)
  2. For $t=1\cdots T$
    1. Reward $r_t \sim R(s,a)$와 Next State $s^\prime \sim P(s^\prime|s,a)$를 추출합니다.
    2. Next Action $a^\prime \sim \pi_\theta(a^\prime|s^\prime)$을 추출합니다. (위에서 $s^\prime$을 추출했기 때문에 가능합니다.)
    3. Policy 파라미터를 업데이트 합니다. $\theta=\theta+\alpha_\theta Q_w(s,a)\nabla_\theta\ln\pi_\theta(a|s)$
    4. t시간에서 TD(Temporal Difference) 에러를 보정합니다. $\delta_t=r_t+\gamma Q_w(s^\prime,a^\prime)-Q_w(s,a)$ 그리고 계산한 $\delta_t$를 사용하여 파마리터를 업데이트 합니다. $w \leftarrow w+\alpha_w\delta_t\nabla_wQ_w(s,a)$
    5. $a$와 $s$를 다음값으로 갱신합니다. $a\leftarrow a^\prime$, $s\leftarrow s^\prime$

인터넷에서 관련 내용을 학습하고자 굉장히 많이 검색을 하여도 대부분 A2C 알고리즘을 구현한 내용들을 기술합니다. 제가 무수히 많이 검색해본 결과 나름대로 충격적인 결론을 얻었습니다.

 

Actor Critic 알고리즘은 A2C라고 불리기도 한다.

 

이 내용은 강화학습 원서에 기술되어 있다고 합니다. 그런데 제가 교육 받을 때 위와 같은 말은 들어본 기억은 없습니다. 그리고 Advantage Function에 대한 기술이 설명되어 있는데 그 부분은 이해를 했지만, 결론은 그대로 구현해보고 싶었으나 참고할만한 내용을 찾았고 그에 따른 정리를 내용을 작성하겠습니다.

 

그 전에 한가지 전제 조건이 필요합니다. Deep Learning을 배우는 것이 목적이라는 것입니다. Actor도 어떠한 모델의 하나이며 Critic도 어떠한 모델의 하나인데, 이 둘을 전부 Neural Network 구조의 학습 모델이라는 전제를 해야 아래 내용을 받아드릴 수 있습니다. (원래 Actor-Critic 알고리즘은 Q-Table이 있습니다.) 전제조건을 받아들이면 기술된 Actor-Critic 알고리즘은 Critic 함수로 어떤 Value를 추정해야한 다는 것을 알 수 있습니다. 이때 Critic 함수로 추정해야하는 값은 Action Value 또는 Action Q-Value 입니다. 

 

그런데 이번에 기술되는 Actor-Critic 알고리즘은 On-Policy로써 한 에피소드가 끝난 결과를 모두 모아서 한꺼번에 학습하는 형태를 띄어야합니다. 하지만 해당 글에서 작성된 알고리즘은 Off-Policy 형태입니다. 또한 Critic이 바로 Q-Value를 구하는 형태를 띈 것을 알 수 있습니다. 

 

## 알고리즘 그대로 구현 소스 공유 예정##

 

알고리즘 그대로 구현하게 되면 비교적 학습이 잘 되진 않습니다. 이를 좀 더 빠르게 구현하기 위해서 원래 알고리즘의 2-4를 이해해야합니다.

수식 1 : $\delta_t=r_t+\gamma Q_w(s^\prime,a^\prime)-Q_w(s,a)$

수식 2: $w \leftarrow w+\alpha_w\delta_t\nabla_wQ_w(s,a)$

수식 2가 Critic의 loss 함수지만, 사실 결과적으로 delta를 0으로 만드는 것이랑 같은 것이라는 것을 알 수 있습니다. 결과적으로 $r_t+\gamma Q_w(s^\prime,a^\prime)$와 $Q_w(s,a)$의 차이를 0으로 만드는 건데, 이는 mes_loss 등의 방법으로 0으로 수렴하는 loss 함수를 설계할 수 있습니다.

 

## mse 구현 소스 공유 예정 ##

 

그런데 Critic으로 Q-Value를 추정하는 방식이면 필연적으로 Advantage 함수를 사용할 수 없습니다. $A(s,a)=Q(s,a)-V(s)$ 수식에서 V값을 구할 수 없기 때문입니다. 해당 딜레마는 Critic으로 Value를 추정하는 방식으로 구현하고 알고리즘을 조금 변형하여 해결할 수 있습니다. (제가 위에 따로 자세하게 기술한 사항을 참조해주시기 바랍니다.) 

 

$$Q^w(s,a)=R_t+\gamma V^w(s^\prime)$$

 

위 수식과 같이 Q-Value를 Value 함수에서 구하는 방식을 취한다면 $A(s,a)=Q(s,a)-V(s)$ 수식을 구할 수 있습니다. 또한 Q-Value를 직접 추정하는 것보다 변수가 줄어드는 것이니 좀 더 안정적이며 빠르게 학습된다고 생각할 수 있습니다. 

 

## advantage를 사용하지 않은 방식으로 구현한 방법 ##

 

## advantage를 사용한 벙법 ## 

 

마지막에 구현한 advantage를 사용하여 구현한 코드는 향후 A2C에서 활용이 가능합니다.

 

Off-Policy Policy Gradient

 

구현에 있어서 강화학습에서 On-Policy와 Off-Policy는 큰 차이는 없지만, Off-Policy의 경우 Buffer를 만들어서 과거 데이터도 학습한다는 점이 주요하게 다른점입니다. 이를 구체화 하면 다음과 같습니다.

 

  1. Off-Policy는 모든 경로를 알지 않아도 됩니다. 또한 과거의 episode를 재활용하여 더욱 효율적입니다. (expericenc replay)
  2. 학습하려는 Policy가 아닌 다른 Policy에서 Sample을 수집합니다. 이는 더 나은 탐험(exploration)을 하는데 도움이 됩니다.

 

 

 

 

A3C

 

본문에 표기된 알고리즘은 다음과 같습니다.

 

  1. 우리는 Global Parameter $\theta$와 $w$와, Thread에 $\theta^\prime$과 $w^\prime$를 준비합니다.
  2. Parameter들을 시간 $t=1$에 초기화 합니다.
  3. While $T<T_{\max}$
    1. Gradient를 초기화 합니다. $d\theta=0$, $dw=0$
    2. Thread Parameter와 Global Parameter를 동기화합니다. ($\theta^\prime=\theta$과 $w^\prime=w$)
    3. $t_\text{start}=t$로 설정하고 시작 state $s_t$에 맞게 Sample을 처리합니다.
    4. While ($s_t$ != TERMINAL) & $t-t_\text{start}\leq t_\max$
      1. $A_t \sim \pi_{\theta^\prime}(A_t|S_t)$ 일때 Action을 하나 취하고 새로운 Reward $R_t$와 새로운 State $s_{t+1}$을 받습니다.
      2. $t=t+1$, $T=T+1$로 갱신합니다.
    5. 변수들을 초기화하고 Retrun값 측정을 멈춥니다. $$\begin{cases}\begin{aligned}&0 &\text{if } s_t \text{ is TERMINAL}\\&V_{w^\prime}(s_t) &\text{otherwise}\end{aligned}\end{cases}$$
    6. For $i=t-1,\cdots,t_\text{start}$
      1. $R \leftarrow \gamma R + R_i$; $R$은 $G_i$의 MC 측정입니다.
      2. $\theta^\prime:d\theta\leftarrow d\theta+\nabla_{\theta^\prime}\log\pi_{\theta^\prime}(a_i|s_i)(R-V_{w^\prime}(s_i))$을 누적연산하며, $w^\prime:dw\leftarrow dw+2(R-V_{w^\prime}(s_i))\nabla_{w^\prime}(R-V_{w^\prime}(s_i))$을 누적연산합니다.
    7. $d\theta$를 활용하여 $\theta$를 $dw$를 활용하여 $w$를 비동기적으로 갱신합니다.

A2C를 Thread 방식으로 구현한 알고리즘입니다. 학습하는 학생의 입장에서 사실 그래픽 카드 하나 갖추는 것 조차 쉽지 않습니다. 2개 이상의 모델의 Parameter 들을 학습하는데 cuda를 사용하고자 한다면 필연적으로 모델 수 만큼 그래픽 코어가 있어야합니다. 그래서 개인적으로 실효성은 좀 떨어진다고 생각합니다.

 

A2C

 

아쉽게도 본문에 따로 알고리즘이 소개되어있진 않습니다만, 논문을 찾을 수 없어도 납득할만한 알고리즘이 작성되어 있는 곳을 찾아 기입합니다. link : Deep Reinforcement Learning (julien-vitay.net)

 

  1. 1. Initialize the actor πθ and the critic Vφ with random weights.  
  2. Observe the initial state $s_\theta$. 
  3. for $t \in [0,T_\text{total}]$: 
    1. Initialize empty episode minibatch.
    2. for $k \in [0,n]$: # Sample episode
      1. Select a action $a_k$ using the actor $\pi_\theta$.
      2. Perform the action $a_k$ and observe the next state $s_{k+1}$ and the reward $r_{k+1}$. 
      3. Store ($s_k$,$a_k$,$r_{k+1}$) in the episode minibatch. 
    3. if $s_n$ is not terminal: set $R=V\varphi(s_n)$ with the critic, else $R=0$.
    4. Reset gradient $d\theta$ and $d\varphi$ to 0.
    5. for $k\in[n−1,0]$: # Backwards iteration over the episode
      1. Update the discounted sum of rewards $R=r_k+\gamma R$
      2. Accumulate the policy gradient using the critic:$$d\theta\leftarrow d\theta+\nabla_\theta\log\pi\theta(s_k,a_k)(R−V\varphi(s_k))$$ 
      3. Accumulate the critic gradient:$$d\varphi\leftarrow d\varphi+\nabla\varphi(R−Vφ(s_k))^2$$
    6. Update the actor and the critic with the accumulated gradients using gradient descent or similar:$$\theta\leftarrow\theta++\eta d\theta \qquad \varphi\leftarrowφ+\eta d\varphi$$

상단부에서 기록한 알고리즘과 큰 차이는 없지만 Off-Policy를 적용하기 위해 minibatch 기능을 활용한 것을 알 수 있습니다.

 

 

 

 

 

DPG

 

DPG를 구현하는데 Off-Policy에 수식을 고려하면 어렵지 않게 코드를 작성할 수는 있습니다. 그렇다면 기존의 Actor-Critic의 기본적인 형태와 DPG는 Action을 구할 때 다소 다릅니다. Actor-Critic은 확률을 구해서 그 값의 확률에 Action을 선택한다면, DPG는 데이터를 가지고 바로 결정하여 사용합니다. 

 

다소 헷갈릴 수 있으므로 예제를 들어 설명을 해보겠습니다. CartPole의 Aciton은 0과 1로 나눌 수 있습니다. 그런데 Actor-Critic은 0이 될 확률과 1이 될 확률을 구하여 비율에 맞게 Action을 선택합니다. 가상의 확률 [0.4, 0.6] 이렇게 주어진다면 0.4가 작지만 40%의 확률로 0.4를 선택할 수 있습니다. (이렇게 탐험을 합니다.)

 

하지만 DPG는 확률 개념 없이 그냥 큰 값을 선택합니다. 즉, 가상의 확률 [0.4, 0.6]가 주어진다면 무조건 0.6을 고르는 것입니다. 이는 탐색의 이점이 전혀 없기 때문에 Noise를 첨가하는데, 수많은 구현체에서 Ornstein Uhlenbeck이라는 Noise를 만들어 사용합니다. 단, DPG 논문이 아닌 DDPG 논문에서 언급됩니다. 

 

실제 코드 구현에 앞서 세가지를 정리하고자 합니다.

 

1. Ornstein Uhlenbeck 이 무엇인지?

더보기

브라운 운동을 기반으로한 랜덤화 기법입니다. 예를 들어 0~100까지 랜덤한 숫자를 하나 뽑아서 현재 70이 나왔다고 하면, 다음번에 랜덤은 20~120 사이에서 숫자를 랜덤하게 뽑는다고 생각하면 비슷합니다. 즉, 현재값을 고려하여 랜덤을 뽑는 것이라고 생각하면 됩니다.

2. Ornstein Uhlenbeck 을 구현하는 방법은 무엇인지?

더보기

위키피디아에서 Ornstein–Uhlenbeck process를 검색하면 Definition 부분에 다음과 같은 수식을 얻을 수 있습니다. link

 

$$dx_t=\theta(\mu-x_t)dt+\sigma dW_t$$

 

위 수식을 오해없게 작성하면 다음과 같이 작성할 수 있습니다. (d가 변수가 아니고 delta이기 때문에 저같은 경우는 오해를 조금 했습니다.)

 

$$\Delta x_t=\theta(\mu-x_t)\Delta t+\sigma \Delta W_t$$

 

해당 수식은 차분을 구하는 것이기 때문에 점화식으로 변형하면 다음과 같습니다.

 

$$x_{t+1}= x_t + \theta(\mu-x_t)\Delta t+\sigma \Delta W_t$$

 

여기서 $\Delta W_t$의 경우 $W$는 Wiener process를 뜻합니다. 이 또한 위키를 찾아보면 Characterisations of the Wiener process 부분에서 우리에게 필요한 정의를 얻을 수 있습니다. link

 

$W_{t+u}-W_t$는 평균이 0이고 분산이 $u$인 정규분포를 따른다. $W_{t+u}-W_t \sim N(0,u)$

 

위 정의에 따라 $\Delta W_t$ 부분은 $N(0,u)$로 변경하고 $N(0,u)$는 $\sqrt{u} \times N(0,1)$로 변경할 수 있습니다. 또한 여기서 $u=\Delta t$임을 감안하여 수식에 적용하면 다음과 같은 최종 수식을 얻을 수 있습니다.

 

$$x_{t+1}= x_t + \theta(\mu-x_t)\Delta t+\sigma \sqrt{\Delta t}N(0,1)$$

 

여기서 변수는 $\mu$, $\sigma$이며 하이퍼 파라미터는 $\theta$이고 임의의 $\Delta t$를 선정해야합니다. 초기값 $x_0$도 선정해야함을 알 수 있습니다.

3. 일반적인 Noise와 Ornstein Uhlenbeck Noise의 차이는 어떤지?

더보기

다음과 같은 표로 차이를 알 수 있습니다.

1000번의 랜덤을 동작시켰을 때 얻을 수 있는 값입니다.

 

실제 적용한 코드는 다음과 같습니다.

 

## 그냥 Noise 없는 DPG의 경우 코드 ##

## Normal Noise DPG의 경우 코드 ##

## OU Noise DPG의 경우 코드 ##

 

여기서 CartPole의 경우 이 알고리즘에 적용이 불가능한지 좀 더 연구해보았습니다. DPG 구현체를 살펴보시면 Critic 모델의 입력값은 State와 Actor 모델의 결과값인 것을 알 수 있습니다. 이를 바로 적용해보면 다음과 같이 코드를 작성할 수 있습니다.

 

## 코드 ##

 

 

 

 

 

DDPG

 

 

알고리즘상에 설명은 되어있지 않지만, 일반적으로 Weight를 완전히 복사하는 것을 Hard Update, 비율을 넣어서 복사하는 것을 Soft Update라고 합니다. Soft Update 할때 그 비율을 $\tau$라고 하는데, 이 비율이 실제 Target Model을 업데이트 하는데 굉장히 중요한 파마미터입니다. 이 숫자가 크면 클수록 업데이트는 빠르지만 분산이 커지며, 반대로 너무 작으면 업데이트가 느립니다. 잘 정해야합니다.

 

Replay Buffer의 경우 버퍼를 무한정 늘리면서 사용할 수는 없으므로 적당한 수준의 버퍼를 설정해야합니다. 또한 Minibatch를 무작위로 추출할 때도 몇개를 추출할 건지 설정해야합니다. 두 개의 파라미터를 잘 선정하셔야합니다. 하이퍼 파라미터가 A2C 알고리즘에 비해 3개나 더 많기 때문에 적절한 학습을 시키는데 다양한 시도가 필요하게 됩니다.

 

코드 짜다보면 Replay Buffer에서 추출한 Minibatch가 학습의 대상인데, 내가 짠 코드가 너무 느리면 해당부분을 확인하는 것이 좋습니다. 조금만 실수해도 엄청 느려집니다.

 

 

 

DDPG는 Continuous한 Action을 학습하는 알고리즘입니다. 하지만 Descrete한 Action을 학습하는 알고리즘으로도 구현이 가능합니다.

 

 

 

 

 

 

 

 


.. 작성중..