10. Actor-critic 알고리즘#

10.1. REINFORCE with baseline 복습#

이전 장에서는 상태가치함수를 베이스라인으로 사용하여 policy gradient을 분산을 줄여주었다.

(10.1)#\[\nabla_{\mathbf{\theta}} J(\mathbf{\theta}) \propto \sum_{s \in \mathcal{S}} d_{\pi_{\mathbf{\theta}}}(s) \sum_{a \in \mathcal{A}} \left( Q^{\pi_{\mathbf{\theta}}}(s,a) - V^{\pi_{\mathbf{\theta}}}(s) \right) \nabla_{\mathbf{\theta}} \pi_{\mathbf{\theta}}(a|s).\]

위에서 상태가치함수와 행동가치함수를 직접 구할 수 없기 때문에 행동가치함수를 대신하여 시뮬레이션을 통해 얻은 return \(G_t\)를 사용했고, 상태가치함수는 뉴럴 네트워크 \(V_\phi\)를 사용하여 근사시켰다. 그래서 우리는 다음과 같은 policy gradient의 추정치를 얻었다.

(10.2)#\[\nabla_{\theta} J(\theta) \approx \hat{g} := \frac{1}{T} \sum\limits_{t=0}^{T-1}\left( G_t - V_{\phi}(s_t)\right) \nabla_{\mathbf{\theta}} \log \pi_{\mathbf{\theta}}(a_t | s_t).\]


10.2. Online actor-critic 및 batch actor-critic 알고리즘#

Policy gradient theorem를 사용하는 방법론들 중 정책과 가치함수 모두를 뉴럴 네트워크로 모델링하는 방법론들을 Actor-critic 방법론이라고 부른다. 여기서 actor (배우)는 정책 네트워크를 의미하며 critic (비평가)는 actor의 행동을 평가하는 가치 네트워크를 말한다. 배우-비평가 방법론이라고 부르기에는 조금 오글거리기 때문에 앞으로 actor-critic 방법론으로 부를 것이다. 하지만 REINFORCE with baseline 알고리즘은 정책과 상태가치함수를 모두 뉴럴 네트워크로 근사시키지만 actor-critic 알고리즘이라고 부르지 않는다. 그 이유에 대해서는 다양한 의견이 있지만, 필자의 생각은 식 (10.1)에서 베이스라인 부분이 아닌 \(Q^{\pi_{\mathbf{\theta}}}(s,a)\)를 추정하기 위하여 가치 네트워크가 사용될 때만 actor-critic 알고리즘이라고 부르는 것 같다. REINFORCE with baseline은 \(Q^{\pi_{\mathbf{\theta}}}(s,a)\)의 추정치로 return \(G_t\)를 사용했고, 가치 네트워크 \(V_\phi\)는 베이스라인으로만 사용되었기 때문에 actor-critic 방법론으로 분류되지 않는다.


그럼 \(Q^{\pi_{\mathbf{\theta}}}(s,a)\)를 추정하기 위해 뉴럴 네트워크를 사용하면 actor-critic 방법론이 될 것이다. 하지만 베이스라인과 함께 사용한다고 하면 행동가치함수를 위한 네트워크 \(Q_{\psi}(s, a)\)와 상태가치함수를 위한 네트워크 \(V_{\phi}(s)\) 2개의 네트워크를 학습시켜야 하기 때문에 학습 안정성 측면에서 안 좋을 것이다. 그래서 우리는 다음과 같은 행동가치함수의 성질을 사용할 것이다. 아래 식은 실제 상태가치함수 및 행동가치함수에 대해서 성립한다. 증명은 식 (4.5)에서 찾아볼 수 있다.

\[Q^{\pi}(s, a)= r(s, a) + \gamma \mathbb{E}_{s' \sim p(\cdot|s,a)}\left[ V^{\pi}(s') \mid S_t = s, A_t=a \right] \; \text{ for all } \; s \in \mathcal{S}, a \in \mathcal{A}.\]

따라서 가치 네트워크 \(V_\phi\)를 사용해서 실제 행동가치함수를 추정할 수 있다.

\[Q^{\pi}(s, a) \approx r(s, a) + \gamma \mathbb{E}_{s' \sim p(\cdot|s,a)}\left[ V_{\theta}(s') \mid S_t = s, A_t=a \right].\]

물론 정확한 기댓값을 구하기 어렵기 때문에 하나의 샘플로 기댓값을 대체할 것이다. 환경과 상호작용하여 얻은 \(t\) 시점의 데이터 (transition) \((s_t, a_t, r_t, s_{t+1})\)를 사용하여 행동가치함수를 근사시킨다. \(s_{t+1}\)가 전이 확률 분포 \(p(\cdot|s_t, a_t)\)로부터 샘플링되었기 때문에 기댓값에 대한 점 추정치로 사용될 수 있는 것이다.

(10.3)#\[Q^{\pi}(s_t, a_t) \approx r_t + \gamma V_{\theta}(s_{t+1}).\]

이제 식 (10.2)에서 행동가치함수의 추정치로 사용된 \(G_t\) 대신 식 (10.3)을 대입해보자.

(10.4)#\[\nabla_{\theta} J(\theta) \approx \hat{g}^{\text{batch}} := \frac{1}{T} \sum\limits_{t=0}^{T-1}\Big( r_t + \gamma V_{\theta}(s_{t+1}) - V_{\phi}(s_t)\Big) \nabla_{\mathbf{\theta}} \log \pi_{\mathbf{\theta}}(a_t | s_t).\]

(10.4)의 그레디언트 추정치를 사용하는 것도 하나의 actor-critic 알고리즘으로 볼 수 있다. 하지만 식 (10.4)에는 REINFORCE 알고리즘의 잔재가 남아 있다. REINFORCE의 경우 return \(G_t\)을 계산하기 위하여 환경의 초기 상태부터 시작하여 상호작용이 종료될 때까지 trajectory \((s_0, a_0, r_0, s_1, a_1, r_1,\ldots, s_T)\)를 수집하고 네트워크 업데이트가 이뤄졌다. \(G_t\)를 계산할 때 \(t\)시점 이후로 받은 모든 보상을 더하기 때문이다. 현재 식 (10.4)\(T\)개의 데이터 \((s_t, a_t, r_t, s_{t+1})\)을 모아서 그레디언트 추정치의 평균을 사용한다. 데이터를 모아서 얻은 그레디언트 추정치라서 \(\hat{g}^{\text{batch}}\)란 표기를 사용했다.


하지만 가만히 생각해보면 환경이 종료될 때까지 기다릴 필요 없이 매 시점 \(t\)마다 환경과 상호작용하여 얻은 데이터 \((s_t, a_t, r_t, s_{t+1})\)만으로 바로 네트워크 업데이트가 가능하다. 즉, 매 스탭 \(t\)마다 policy gradient에 대한 추정치 하나를 계산하여 정책 네트워크를 업데이트할 수 있다.

\[ \nabla_{\theta} J(\theta) \approx \hat{g}^{\text{online}}_t := \Big( r_t + \gamma V_{\theta}(s_{t+1}) - V_{\phi}(s_t)\Big) \nabla_{\mathbf{\theta}} \log \pi_{\mathbf{\theta}}(a_t | s_t). \]

매 스탭 \(t\)마다 실시간으로 구할 수 있는 그레디언트 추정치이기 때문에 \(\hat{g}^{\text{online}}_t\)라고 적어주었다. 이제 매 스탭마다 정책 네트워크를 업데이트시킬 수 있다. 하지만 REINFORCE with baseline의 경우 가치 네트워크 \(V_{\phi}(s_t)\)도 학습시킬 때 return \(G_t\)를 레이블로 사용하기 때문에 환경과 상호작용이 종료되어야만 업데이트가 가능했다.

\[J^{\text{batch}}(\phi) = \frac{1}{T} \sum_{t=0}^{T-1} \left(G_t - V_{\phi}(s_t) \right)^2.\]

따라서 정책과 함께 매 스탭마다 가치 네트워크를 업데이트시키기 위해서는 레이블을 바꿔줘야만 한다. 이를 위해 다음의 상태가치함수의 재귀적 성질을 이용할 것이다.

\[V^{\pi}(s)= \mathbb{E}_{a \sim \pi(\cdot|s), s' \sim p(\cdot|s,a)} \left[ r(s, a) + \gamma V^{\pi}(s') \mid S_t = s\right] \; \text{ for all } \; s \in \mathcal{S}.\]

실제 상태가치함수 대신 뉴럴 네트워크 \(V_\phi\)를 사용하고 기댓값에 대한 추정치로 데이터 \((s_t, a_t, r_t, s_{t+1})\)를 사용하면 다음과 같은 실제 상태가치함수에 대한 추정치를 얻을 수 있다.

\[V^{\pi}(s_t) \approx r_t + \gamma V_{\phi}(s_{t+1}).\]

이제 \(G_t\)를 레이블로 사용하여 가치 네트워크 \(V_{\phi}(s_{t})\)를 학습시키는 대신 \(r_t + \gamma V_{\phi}(s_{t+1})\)을 레이블 \(y_t\)로 사용하여 \(V_{\phi}(s_{t})\)를 학습시킨다.

\[J^{\text{online}}_t(\phi) = \Big(r_t + \gamma V_{\phi}(s_{t+1}) - V_{\phi}(s_t) \Big)^2.\]

위 식을 코드로 구현할 때 주의할 점이 있다. 레이블로 사용되는 \(y_t=r_t + \gamma V_{\phi}(s_{t+1})\) 역시 파라미터 \(\phi\)를 포함하고 있다는 점이다. \(y_t\)는 레이블로만 사용되기 때문에 실제 구현에서는 파이토치의 detach() 메서드를 사용하여 \(y_t\)를 상수 취급하고 \(\phi\)에 대한 그레디언트를 계산하지 않아야 한다. 모든 내용을 종합하여 online actor-critic 알고리즘을 적어보면 다음과 같다. 사실 이제 trajectory \(\tau\)를 사용해서 네트워크를 업데이트하는 것이 아니기 때문에 밑첨자 \(t\)를 모두 제거해줬다.

Algorithm 10.1 (Online actor-critic)

  1. 정책 네트워크 \(\pi_{\theta}\)의 파라미터 \(\theta\) 초기화, 가치 네트워크 \(V_{\phi}\)의 파라미터 \(\phi\) 초기화

  2. \(s \sim d_0(s)\) \(\quad\) # 환경 초기화

  3. for \(\text{t}\) in range(\(\text{max_iterations}\)):

  4. \(\qquad\) \(a \sim \pi_\theta(\cdot|s)\) 행동 선택 및 보상과 다음 상태 \((r, s')\) 관측

  5. \(\qquad\) \(y = r + \gamma V_{\phi}(s')\) 계산

  6. \(\qquad\) \(\phi \leftarrow \phi - \eta_{\phi} \nabla_{\phi} \big(y - V_{\phi}(s) \big)^2\) \(\quad\) # 가치 네트워크 업데이트

  7. \(\qquad\) \(\hat{g}^{\text{online}} = \big(y - V_{\phi}(s)\big) \nabla_{\theta} \log \pi_{\theta} (a|s)\)

  8. \(\qquad\) \(\theta \leftarrow \theta + \eta_{\theta} \hat{g}^{\text{online}}\) \(\quad\) # Gradient ascent

  9. \(\qquad\) \(s \leftarrow s'\)

  10. \(\qquad\) if \(\text{terminated}\):

  11. \(\qquad \qquad\) \(s \sim d_0(s)\) \(\quad\) # 환경 종료시 환경 초기화


Online actor-critic의 경우 매 스탭마다 정책을 업데이트할 수 있다는 장점이 있다. 하지만 데이터 하나로 그레디언트의 추정치를 만들기 때문에 그레디언트 추정치의 분산이 매우 크기 때문에 학습이 불안정하다. 마치 샘플 하나마다 파라미터를 업데이트하는 stochastic gradient descent (SGD)로 뉴럴 네트워크를 학습시킬 때 학습 곡선의 변동성이 큰 것과 비슷한 이유이다. 실제로 online actor-critic을 Pendulum 환경에 적용해보면 가치 함수가 틈만 나면 발산을 하는 것을 관찰할 수 있다.


따라서 매 스탭마다 네트워크들을 업데이트하는 대신 에피소드가 종료된 후 \(T\)개의 데이터로 네트워크를 업데이트하거나 환경과 상호작용하며 데이터가 \(N\)개 모일 때마다 네트워크를 업데이트하는 batch actor-critic이 더욱 안정적으로 학습이 된다.

Algorithm 10.2 (Batch actor-critic)

  1. 정책 네트워크 \(\pi_{\theta}\)의 파라미터 \(\theta\) 초기화, 가치 네트워크 \(V_{\phi}\)의 파라미터 \(\phi\) 초기화, \(\mathcal{D}\) 빈 리스트

  2. \(s \sim d_0(s)\) \(\quad\) # 환경 초기화

  3. for \(\text{t}\) in range(\(\text{max_iterations}\)):

  4. \(\qquad\) \(a \sim \pi_\theta(\cdot|s)\) 행동 선택 및 보상과 다음 상태 \((r, s')\) 관측

  5. \(\qquad\) \(\mathcal{D} \leftarrow \mathcal{D} \cup \{ (s, a, r, s') \}\) \(\quad\) # 데이터 저장

  6. \(\qquad\) \(s \leftarrow s'\)

  7. \(\qquad\) if \(\text{len}(\mathcal{D}) == N\):

  8. \(\qquad\qquad\) \(y_i = r_i + \gamma V_{\phi}(s_{i+1})\) 계산 \(\forall (s_i, a_i, r_i, s_{i+1}) \in \mathcal{D}\)

  9. \(\qquad\qquad\) \(\phi \leftarrow \phi - \eta_{\phi} \nabla_{\phi} \frac{1}{N}\sum_{i=1}^{N}\big(y_i - V_{\phi}(s_i) \big)^2\) \(\quad\) # 가치 네트워크 업데이트

  10. \(\qquad\qquad\) \(\hat{g}^{\text{batch}} = \frac{1}{N}\sum_{i=1}^{N}\big(y_i - V_{\phi}(s_i)\big) \nabla_{\theta} \log \pi_{\theta} (a_i|s_i)\)

  11. \(\qquad\qquad\) \(\theta \leftarrow \theta + \eta_{\theta} \hat{g}^{\text{batch}}\) \(\quad\) # Gradient ascent

  12. \(\qquad\qquad\) \(\mathcal{D} \leftarrow \emptyset\) \(\quad\) # 리스트 초기화

  13. \(\qquad\) if \(\text{terminated}\):

  14. \(\qquad\qquad\) \(s \sim d_0(s)\) \(\quad\) # 환경 종료시 환경 초기화



10.3. REINFORCE와 actor-critic의 차이점#

네트워크를 업데이트할 때 타겟값으로 \(G_t\)를 사용하는 REINFORCE는 true policy gradient에 대한 추정량의 분산이 굉장히 크다. 동일한 상태 \(s_t\)부터 시작하여 정책 \(\pi_\theta\)를 실행시켰을 때, 환경과 정책의 무작위성에 의하여 \(G_t\)가 가질 수 있는 값이 굉장히 다양하기 때문일 것이다. 많은 책들에서 확률변수 \(G_t = R_{t} + \gamma R_{t+1} + \gamma^2 R_{t+2} + \cdots\)에 굉장히 많은 확률변수가 있고, 각 확률변수들이 가질 수 있는 값이 다양하기 때문에 \(G_t\)를 하나의 샘플로 추정한 single estimation의 분산이 크다고 말하고 있다. \(G_t\)를 사용한 policy gradient의 추정량은 분산이 크기 때문에 학습이 불안정할 수 있지만 true policy gradient에 대한 unbiased estimation이라는 장점이 있다.


반면 actor-critic이 사용하는 타겟값인 \(r_t + \gamma V_{\theta}(s_{t+1})\)의 경우 확률변수가 \(R_t\)\(S_{t+1}\) 밖에 없다. 따라서 single estimation이 갖는 값의 분산도 상대적으로 작을 것이다. \(r_t + \gamma V_{\theta}(s_{t+1})\)을 사용한 policy gradient의 추정량은 분산이 작아서 학습이 REINFORCE보다 안정적일 수 있지만, true policy gradient에 대한 biased estimation이라는 단점이 있다.


다음 장에서는 online actor-critic과 batch actor-critic을 구현해볼 것이다.