본문으로 바로가기
  • 2019.05.21 해석 자연스럽게 수정

Proximal Policy Optimization

배경지식 (Background)

PPO는 현재 가지고 있는 데이터로 성능을 떨어뜨리지 않으면서 정책을 개선시키는 step을 가능한 멀리 밟도록하려면 어떻게 해야하는 지에 대해 고민했다는 점에서 TRPO와 같습니다. TRPO는 복잡한 2차 근사(second-order) 방법으로 해결했다면, PPO는 이전 정책과 새로운 정책이 가깝게 유지하도록 약간 트릭을 사용한 선형 근사(first-order) 방법으로 구현이 더 간단하면서도, 최소한 TRPO만큼의 성능을 보이는 것 같습니다.

PPO는 PPO-penalty와 PPO-Clip 두 가지 방식이 있습니다.

PPO-Penalty는 TRPO처럼 KL-constrained 업데이트로 근사해서 풀지만, 제한하는 것 대신 목적 함수에서 KL-divergence에 패널티를 주는 방식을 택했고 이를 위한 패널티 계수를 학습하면서 자동으로 크기를 조정합니다.

PPO-Clip은 KL-divergence가 목적함수에도, constraint에도 전혀 없습니다. 대신 목적 함수에 특별한 clipping으로 새로운 정책이 이전 정책에서 멀어지지 않도록 합니다.

여기서는 PPO-Clip만 집중해서 다루겠습니다.(OpenAI이 사용하는 방법)

빠르게 알고갈 사실 (Quick Facts)

  • PPO는 on-policy 알고리즘입니다.
  • PPO는 discrete하거나 continuous한 action space를 가진 환경에서 사용할 수 있습니다.
  • Spinning UP 구현에서는 MPI를 이용한 병렬화(parallelization)를 지원합니다.

주요 방정식 (Key Equations)

PPO-clip은 다음을 통해 정책을 업데이트 합니다.

θk+1=argmaxθEs,aπθk[L(s,a,θk,θ)]

보통 미니배치를 사용해 SGD으로 여러 학습하여 목적함수를 최대화하도록 합니다. 여기서 L은 다음과 같습니다.

L(s,a,θk,θ)=min(πθ(a|s)πθk(a|s)Aπθk(s,a),clip(πθ(a|s)πθk(a|s),1ϵ,1+ϵ)Aπθk(s,a))

ϵ은 이전 정책보다 새로운 정책이 얼마나 더 많이 변해도 될지 정해주는 (작은 값의) 하이퍼파라미터(hyperparameter) 정도로 볼 수 있습니다.

꽤 복잡해 보이고 처음 보기엔 뭐가 어떻게 돌아가는지, 새로운 정책이 이전 정책과 어떻게 가깝게 유지하도록 해주는 건지 잘 모를 수 있습니다. 찾아보면 이보다 더 다루기 쉽게 상당히 단순화된 형태가 있습니다. (OpenAI code에서도 이와 같이 구현되어 있습니다.)

L(s,a,θk,θ)=min(πθ(a|s)πθk(a|s)Aπθk(s,a),g(ϵ,Aπθk(s,a)))

이 때 g는 다음과 같습니다.

g(ϵ,A)={(1+ϵ)A,A0(1ϵ)A,A<0

이에 담겨있는 직관을 얻기 위해 어떤 한 상태-행동 쌍(s,a) 이 있다고 생각해봅시다. (그래서 어떤 Advantage 값이 나왔다고 해봅시다.)

Advantage가 양수인 경우: Advantage가 양수인 경우 다음과 같이 목적함수를 줄일 수 있습니다.

L(s,a,θk,θ)=min(πθ(a|s)πθk(a|s),(1+ϵ))Aπθk(s,a)

advantage가 양수이기 때문에, 행동을 더 자주한다면, 즉 πθ(a|s)가 증가한다면 목적함수도 증가할겁니다. 하지만 min 항이 이러한 목적함수의 증가를 제한하고 있습니다. πθ(a|s)>(1+ϵ)πθk(a|s) 라면, min은 (1+ϵ)Aπθk(s,a)라는 값을 갖도록 할겁니다. 결국, 새로운 정책은 이전 정책보다 멀리 가도 더 특별한 이득이 없게 됩니다.

Advantage가 음수인 경우 Advantage가 음수인 경우 다음과 같이 목적함수를 줄일 수 있습니다.

L(s,a,θk,θ)=max(πθ(a|s)πθk(a|s),(1ϵ))Aπθk(s,a)

advantage가 음수이기 때문에, 행동을 덜 하게 된다면, 즉 πθ(a|s)가 감소한다면 목적함수는 증가할겁니다. 하지만 max 항이 이러한 목적함수의 증가를 제한하고 있습니다. πθ(a|s)<(1+ϵ)πθk(a|s) 라면, max은 (1ϵ)Aπθk(s,a)라는 값을 갖도록 할겁니다. 결국, 새로운 정책은 이전 정책보다 멀리 가도 더 특별한 이득이 없게 됩니다.

** 이해를 위한 논문 그림 **

지금까지 본 것은 정책이 갑자기 변하지 않도록 regularizer로써 clipping을 사용는 것과 성능이 증가하면서 새로운 정책이 이전 정책보다 얼마나 더 멀어져도 되는지 결정해주는 hyperparameter ϵ입니다.

이러한 clipping은 장기적으로 의미있는 정책 업데이트를 할 수 있도록 해주지만, 새로운 정책이 이전 정책보다 과하게 멀리 떨어질 가능성은 여전히 있습니다. 그래서 이를 피하기 위한 다른 PPO 구현 트릭들이 많이 사용되고 있습니다. 여기 구현에서는 특히 간단한 방법을 사용하는데, 바로 early stopping입니다. 이전 정책과 새로운 정책의 KL-divergence가 일정 기준치(threshold)를 넘어가게 되면, 학습을 멈추는 방법이죠.

기본 수학이나 구현에 익숙해졌다면 다른 곳에서는 이러한 문제를 어떻게 푸는지 보는 것도 좋습니다.

탐험 vs 활용 (Exploration vs. Exploitation)

PPO는 on-policy 방법으로 확률적인 정책(stochastic policy)을 학습합니다. 근데 이 말은 곧 가장 최근의 정책을 통해 행동을 샘플링하여 탐험(explore)를 한다는 뜻입니다. 초기 조건과 학습 과정이 어떻냐에 따라 행동 선택이 결정됩니다. 학습하는 동안, 이미 받았던 보상에 대해서만 계속 활용(exploit)하도록 업데이트가 되다보니, 정책은 보통 점점 랜덤하게 선택하지 않게 됩니다. 결국 local optima에 빠지게 될 수도 있습니다.

의사 코드 (Pseudo code)