ai theory

강화학습 기초 (13) - Policy를 직접 미분한다는 것

Junyoung Park · 2024-06-07 · 5 min

들어가며...

DQN은 각 Action의 Q값을 예측하고 가장 큰 Action을 선택했다.

a=argmaxaQ(s,a)a = \arg\max_{a'}Q(s,a')

즉, Policy는 Value function 뒤에 숨어 있었다. Q값을 잘 배우면 Policy가 따라 나오는 구조다.

Policy Gradient는 순서를 바꾼다. Parameter θ\boldsymbol\theta를 가진 Policy 자체를 만들고, 좋은 Return을 만든 Action의 확률이 높아지는 방향으로 θ\boldsymbol\theta를 움직인다.

πθ(as)\pi_\theta(a\mid s)

처음 보면 “환경은 미분할 수 없는데 Action 확률을 어떻게 미분하지?”라는 의문이 생긴다. 이번 글에서는 이 문제를 풀어주는 Log-derivative trick과 가장 기본적인 Policy Gradient Algorithm인 REINFORCE를 살펴본다.

Policy를 직접 표현하는 이유

Discrete action에서는 Softmax policy를 사용할 수 있다.

πθ(as)=exphθ(s,a)bexphθ(s,b)\pi_\theta(a\mid s) = \frac{ \exp h_\theta(s,a) }{ \sum_b\exp h_\theta(s,b) }

hθ(s,a)h_\theta(s,a)는 Action의 선호도를 나타내는 Score다.

Continuous action에서는 평균과 표준편차를 출력하는 Gaussian policy를 사용할 수 있다.

AtN(μθ(St),σθ(St)2)A_t \sim \mathcal N \left( \mu_\theta(S_t), \sigma_\theta(S_t)^2 \right)

이 경우 모든 Action의 Q값을 나열하거나 argmax\arg\max를 계산할 필요 없이 Policy가 연속값 Action을 직접 Sample한다.

Policy를 직접 학습하면 다음 장점이 있다.

  • Continuous action을 자연스럽게 다룬다.
  • Stochastic policy가 필요한 문제를 표현할 수 있다.
  • Action 확률을 부드럽게 바꿀 수 있다.

반면 Value-based method보다 Gradient의 Variance가 클 수 있고, 한 번 모은 On-policy 경험을 오래 재사용하기 어렵다는 단점이 있다.

무엇을 최대화할까?

Policy의 목표를 기대 Return으로 둔다.

J(θ)=Eτπθ[G0]J(\theta) = \mathbb E_{\tau\sim\pi_\theta} \left[ G_0 \right]

τ\tau는 Policy가 만든 Trajectory다.

τ=(S0,A0,R1,S1,A1,)\tau = (S_0,A_0,R_1,S_1,A_1,\ldots)

우리가 원하는 것은 J(θ)J(\theta)가 커지는 방향,

θJ(θ)\nabla_\theta J(\theta)

이다.

좋은 결과를 만든 Action을 더 자주

REINFORCE의 Update는 다음과 같다.

θθ+αGtθlogπθ(AtSt)\theta \leftarrow \theta + \alpha G_t \nabla_\theta \log\pi_\theta(A_t\mid S_t)

식은 문장처럼 읽을 수 있다.

  • Gt>0G_t>0이면 실제로 선택한 AtA_t의 Log probability를 높인다.
  • Gt<0G_t<0이면 그 Action의 Log probability를 낮춘다.
  • Gt|G_t|가 클수록 Update를 크게 한다.
좋은 Return을 만든 Action의 확률은 올리고, 나쁜 Return을 만든 Action의 확률은 내린다.

Action이 LEFT, RIGHT 두 개이고 현재,

πθ(RIGHTs)=0.6\pi_\theta(\text{RIGHT}\mid s)=0.6

이라고 하자. RIGHT를 Sample해 좋은 Return을 얻었다면 logπθ(RIGHTs)\log\pi_\theta(\text{RIGHT}\mid s)가 커지는 방향으로 움직인다. 확률 합은 11이어야 하므로 RIGHT의 확률이 올라가면 LEFT의 확률은 내려간다.

여기서 중요한 점은 “가장 큰 확률의 Action”만 학습하는 것이 아니라 실제로 Sample한 Action을 그 결과에 따라 평가한다는 것이다.

왜 Log를 사용할까?

확률 pθ(x)p_\theta(x)에 대한 기대값을 생각해보자.

J(θ)=xpθ(x)R(x)J(\theta) = \sum_x p_\theta(x)R(x)

미분하면,

θJ(θ)=xθpθ(x)R(x)\nabla_\theta J(\theta) = \sum_x \nabla_\theta p_\theta(x)R(x)

이다. 다음 항등식을 사용한다.

θpθ(x)=pθ(x)θlogpθ(x)\nabla_\theta p_\theta(x) = p_\theta(x) \nabla_\theta\log p_\theta(x)

왜냐하면,

θlogpθ(x)=θpθ(x)pθ(x)\nabla_\theta\log p_\theta(x) = \frac{ \nabla_\theta p_\theta(x) }{ p_\theta(x) }

이기 때문이다.

이를 대입하면,

θJ(θ)=xpθ(x)θlogpθ(x)R(x)\nabla_\theta J(\theta) = \sum_x p_\theta(x) \nabla_\theta\log p_\theta(x) R(x)

이고 기대값으로 쓰면,

θJ(θ)=Expθ[R(x)θlogpθ(x)]\nabla_\theta J(\theta) = \mathbb E_{x\sim p_\theta} \left[ R(x)\nabla_\theta\log p_\theta(x) \right]

가 된다.

전체 가능한 결과를 합하지 않아도 현재 Policy에서 Sample한 xx와 관찰한 R(x)R(x)만으로 Gradient를 추정할 수 있다.

Log-derivative trick은 확률 분포에서 뽑은 Sample과 그 Return으로 기대값의 Gradient를 추정하게 해준다.

환경을 미분하지 않아도 되는 이유

Action을 고른 뒤 환경이 어떻게 움직이는지는 미분할 수 없을 수 있다. 충돌, Game rule, 사람의 반응처럼 불연속적인 과정도 많다.

Policy Gradient는 환경을 통과해 Gradient를 역전파하지 않는다. 환경에서 받은 Return을 Weight로 사용하고, 미분 가능한 Policy의 Log probability만 미분한다.

Gtenvironment feedback×θlogπθ(AtSt)policy gradient\underbrace{G_t}_{\text{environment feedback}} \times \underbrace{ \nabla_\theta\log\pi_\theta(A_t\mid S_t) }_{\text{policy gradient}}

환경은 결과를 알려주고, Policy는 그 결과를 만든 선택의 확률을 바꾼다.

Policy Gradient Theorem

State를 여러 번 거치는 MDP에서는 Policy Gradient Theorem이 다음 형태를 준다.

θJ(θ)Eπθ[Qπθ(St,At)θlogπθ(AtSt)]\nabla_\theta J(\theta) \propto \mathbb E_{\pi_\theta} \left[ Q^{\pi_\theta}(S_t,A_t) \nabla_\theta \log\pi_\theta(A_t\mid S_t) \right]

State 방문 확률을 직접 미분하지 않고도 현재 Policy의 Trajectory Sample로 Gradient를 구할 수 있다는 것이 핵심이다.

REINFORCE는 알 수 없는 Qπ(St,At)Q^\pi(S_t,A_t) 대신 실제 Return GtG_t를 사용한다.

Qπ(St,At)GtQ^\pi(S_t,A_t) \approx G_t

왜 Episode 전체 Return 대신 GtG_t를 쓸까?

시간 tt의 Action은 이미 지나간 Reward에 영향을 줄 수 없다. 따라서 AtA_t를 평가할 때는 그 시점 이후의 Return만 사용한다.

Gt=Rt+1+γRt+2+γ2Rt+3+G_t = R_{t+1} + \gamma R_{t+2} + \gamma^2R_{t+3} +\cdots

AtA_t 이전에 받은 Reward까지 곱하면 Action과 무관한 Noise를 더하는 셈이다. 이 Causality를 반영하면 Gradient의 Variance를 줄일 수 있다.

REINFORCE 전체 과정

  1. 현재 Policy πθ\pi_\theta로 Episode 하나를 생성한다.
  2. 각 시간 tt에서 Return GtG_t를 계산한다.
  3. Gtθlogπθ(AtSt)G_t\nabla_\theta\log\pi_\theta(A_t\mid S_t)를 더한다.
  4. Episode가 끝난 뒤 Parameter를 Update한다.
θθ+αt=0T1Gtθlogπθ(AtSt)\theta \leftarrow \theta + \alpha \sum_{t=0}^{T-1} G_t \nabla_\theta\log\pi_\theta(A_t\mid S_t)

구현은 단순하지만 Episode Return이 크게 흔들리면 Gradient도 크게 흔들린다.

REINFORCE의 높은 Variance

같은 State에서 같은 Action을 골라도 환경의 Randomness와 이후 Action에 따라 GtG_t가 달라질 수 있다. 한 번은 +10+10, 다음에는 3-3이 나올 수 있다.

REINFORCE는 이 Return을 그대로 곱하므로 Update의 Variance가 크다. 많은 Trajectory를 평균내야 안정적인 방향이 보일 수 있다.

다음 글에서는 “평소 이 State에서 기대하던 값”을 Baseline으로 빼고, 그 Baseline을 학습하는 Critic을 추가한다. 이것이 Actor-Critic의 출발점이다.

이번 글에서 기억할 것

Policy Gradient는 좋은 Return을 만든 Action의 Log probability를 높이는 방향으로 Policy Parameter를 직접 Update한다.

  1. Policy πθ(as)\pi_\theta(a\mid s)는 Action의 확률 분포를 직접 표현한다.
  2. Log-derivative trick 덕분에 환경을 미분하지 않고 Sample로 Gradient를 추정한다.
  3. REINFORCE는 Gtlogπθ(AtSt)G_t\nabla\log\pi_\theta(A_t\mid S_t)를 사용한다.
  4. GtG_t의 부호는 확률을 올릴지 내릴지, 크기는 Update 강도를 정한다.
  5. 단순하지만 Monte Carlo Return 때문에 Variance가 크다.

참고 자료