* [바닥부터 배우는 강화학습] 도서를 읽고 정리한 글입니다

 

1. 벨만 방정식 소개

주어진 상태의 밸류를 구하는 실제 방법에 벨만 방정식이 사용된다.

벨만 방정식은 시점 t 에서의 밸류와 시점 t+1 에서의 밸류 사이의 관계를 다루고 있으며

또 가치함수와 정책함수 사이의 관계도 다루고 있다.

 

벨만 방정식은 현재 시점 (t)와 다음 시점(t+1) 사이의 재귀적 관계를 이용해 정의된다.

 

벨만 방정식은 벨만 기대 방정식과 벨만 최적 방정식이 있다.

 

2. 벨만 기대 방정식

벨만 기대 방정식을 아래와 같이 편의상 세 단계로 나눠 볼 수 있다.

(1) 0단계

\( \nu_{\pi}(S_t)  = \mathbb{E}_{\pi} \left [ r_{t+1} + \gamma \nu_{\pi}(S_{t+1}) \right ] \) 증명 및 의미

위 풀이식을 해석을 해보면,

상태 \( s_t \)의 가치밸류는 상태 \( s_t \)에서 부터 미래에 받을 보상을 더해준 리턴의 기댓값인데, 풀어서 생각해보면 한 스텝 더 진행하여 보상을 받고, 그 다음 상태인 \( s_{t+1} \) 부터 미래에 받을 보상(리턴)을 더해줘도 같은 결과를 가져온다는 것이다.

더 연장해서 생각해보면 \( s_{t+1} \) 상태로 진행한 후 한스탭 더 진행해서 보상을 받고 그 다음상태인 \( s_{t+2} \) 부터 미래에 받을 보상(리턴)을  더해줘도 같은 결과를 가져온다

이것을 수식으로 표현해보면 아래와 같다.

$$ \nu_{\pi} (s_t) = \mathbb{E}_{\pi} \left [ r_{t+1} + \gamma r_{t+2} + \gamma^2 \nu_{\pi} (s_{t+2})  \right ] $$

같은 원리로 액션가치함수에 대해서도 적용할 수 있다.

$$ \mathbf{q}_{\pi}(s_t, a_t) = \mathbb{E}_{\pi} \left [ r_{t+1} + \gamma \mathbf{q}_{\pi}(s_{t+1}, a_{t+1}) \right ] $$

$$ \mathbf{q}_{\pi}(s_t, a_t) = \mathbb{E}_{\pi} \left [ r_{t+1} + \gamma r_{t+2} + \gamma^2 \mathbf{q}_{\pi}(s_{t+2}, a_{t+2}) \right ] $$

 

풀이식에서 하나 더 주목해야 할 부분은 기댓값에 대한 부분이다.

\( s_t \)에서 시작하여 \( s_{t+1} \)이 정해지기까지 두 번의 확률적인 과정을 거쳐야 한다.

쉽게 이야기하면 두번의 동전던지기 과정이 필요하다.

 

 

첫번째는 상태 \( s_t \)에서 액션 \( a_t \)를 선택하는 과정에서 필요하다

이때는 정책확률분포 ( \( \pi \) 에 따라 액션이 정해진다.

예를 들어 수식으로 표현하면,

$$ \pi (a_1 \vert s_t) = 0.6, \pi (a_2 \vert s_t ) = 0.4 $$

이 수식을 해석하면 상태 \( s_t \)에서 액션을 정할 때 \( a_1 (앞면) \)을 선택하게 될 확률 0.6, \( a_2 (뒷면) \)를 선택하게 될 확률 0.4 를 가지는 정책이라는 의미이다. 그리고 이 정책 확률분포에 따라 동전던지기를 실행한다는 것이다.

이 부분을 위 그림에서는 \( \pi \)의 동전던지기 라고 표현했다.

 

이 과정을 거쳐 액션이 선택되면 그 다음 과정은 환경이 전이확률에 따라 (동전을 던져) 다음 상태 \( s_{t+1} \) 를 정하게 된다.

 

상태 전이하는 과정에서 이렇게 확률분포에 따라 선택되어 지는 과정(동전던지기)를 수행해야 하기 때문에 매번 결과가 같게 나올 수 없으므로 이 부분을 수식으로 표현하기 위해 기댓값이 사용된 것이다.

 

(2) 1단계

벨만 방정식 1단계에는 액션 밸류 \( \mathbf{q}_{\pi}(s, a) \) 를 이용해 상태 밸류 \( \nu_{\pi}(s) \) 를 표현하는 식과 \( \nu_{\pi} (s) \)를 이용하여 \( \mathbf{q}_{\pi}(s, a) \)를 표현하는 식으로 구성되어 있다.

 

왜 1단계에서 이 둘의 관계를 정리하는 방정식이 등장했을까?

0단계에서 언급한 것처럼 상태 전이 과정에는 액션의 선택과정과 그것을 토대로 다음상태를 선택하는 2가지 과정이 내포되어 있다.

즉, 다음상태로 전이과정이 둘과의 관계가 정리되어야 전이과정의 풀이를 한쪽만의 공식으로 나타낼 수 있게 될 것이다.

 

1) \( \mathbf{q}_{\pi} \)를 이용해 \( \nu_{\pi} \)를 계산하기

 

다음은 위 식을 예를 들어 설명한다.

 

정책은 그림의 확률분포를 따른다고 가정하며, \( a_1 \) 선택시 액션밸류(액션가치)는 1, \( a_2 \)를 선택시 액션밸류(액션가치)는 2를 가지고 있다고 가정할 때 상태s 의 밸류 계산식은 다음과 같다.

2) \( \nu_{\pi} \)를 이용해 \( \mathbf{q}_{\pi} \) 계산하기

다음은 위 식을 예를 들어 설명한다.

위 식을 이용해 상태s 에서 액션 \( a_1 \) 선택시 밸류를 구하는 위해서는 아래의 전제조건이 필요하다.

a) \(a_1 \)선택시 받는 보상을 알아야 한다 (그림에서는 0.5)

b) 상태 s에서 액션 \(a_1 \) 선택시 다음 상태로의 전이확률 \( P_{ss^{'}}^a \) 을 알아야 한다.

    (그림에서는 \(s_1 \)으로 이동확률은 70%, \(s_2 \)로 이동확률은 30%이다)

c) 다음상태로 전이된 후 각 상태의 밸류를 알아야 한다.

 (그림에서는 \(s_1 \)의 상태밸류\( \nu_{\pi}(s_1) \)는 1.5 , \(s_2 \)의 상태밸류\( \nu_{\pi}(s_2) \)는 -1 이다)

 

(3) 2단계

1단계의 \( \mathbf{q}_{\pi} \)에 대한 식을 \( \nu_{\pi} \)에 대한 식에 대입하면 아래와 같은 결과 식이 나온다.

 

반대로 \( \nu_{\pi} \)에 대한 식을 \( \mathbf{q}_{\pi} \)에 대한 식에 대입하면 다음과 같은 결과식을 얻는다.

2단계의 공식은 0단계 공식의 실제 계산에 사용되는 공식이라고 보며 된다.

0단계와 2단계 수식을 같이 적어보면 아래와 같다.

0단계에서 기댓값 실제 계산을 2단계 공식을 사용한다고 보면 된다.

단, 이때 전제조건은 아래 2가지를 알고 있어야 한다.

- 보상함수 \( r_{s}^{a} \) : 각 상태에서 액션을 선택하면 얻는 보상

- 전이확률 \( P_{ss^{'}}^{a} \) : 각 상태에서 액션을 선택하면 다음 상태가 어디가 될지에 관한 확률분포

 

이 2가지는 환경의 일부이며 이 2가지에 대한 정보를 알 때 "MDP를 안다"고 표현한다.

 

하지만 실제 환경에서는 이 2가지를 모르는 경우도 많다.

즉, MDP에 대한 정보를 모르는 상태에서 학습하는 접근법을 "모델-프리" 접근법이라 한다.

반대로 이 2가지에 대한 정보를 알고 있는 경우 학습하는 접근법을 "모델 기반" 혹은 "플래닝" 접근법 이라고 한다.

 

MDP 모든 정보를 알 때는 벨만 기대 방정식 중 2단계 식을 이용하며,

MDP 정보를 모를 때에는 0단계 식을 이용한다.

 

2. 벨만 최적 방정식

(1) 최적밸류와 최적 정책

어떤 MDP가 주어졌을 때 그 MDP안에 존재하는 모든 \( \pi \)들 중에서 가장 좋은 \( \pi \)를( 즉 \( \nu_{\pi}(s) \) 의 값을 가장 높게 하는 정책) 선택하여 계산한 밸류가 최적 밸류 \( \nu_{*}(s) \)라는 뜻이다.

\( \mathbf{q}_{*}(s,a) \)도 마찬가지 의미이다.

 

만일 상태별로 가장 높은 밸류를 주는 정책이 다르면, 예컨대 \( s_0 \)의 밸류는 \( \pi_{238} \)를 따를 때 최고이고 \( s_1 \)의 밸류는 \( \pi_{345} \) 를 따를 때 최고인 경우, 이런 경우는 각 상태별로 최고인 정책을 따르는 새로운 정책\( \pi_{*} \)를 생각할 수 있다. 

해당 정책을 따르면 모든 상태에 대해 그 어떤 정책보다 높은 밸류를 얻게 되는 이러한 정책을 최적 정책 이라고 한다.

 

(2) 벨만 최적 방정식

1) 0단계 수식 설명

이 식은 밸만 기대 방정식 0단계 수식의 취지와 같은 취지의 수식이다.

"상태s에서 최적 밸류는 한 스탭만큼 진행해서 보상을 받고, 다음 상태인 \( s^{'} \)의 최적 밸류를 더해줘도 같다" 는 의미이다.

여기서 기댓값이 들어가 있는 이유는 액션a에서 다음상태로 전이될 때 사용되는 전이확률는 계속 사용되기 때문에 매번 전이된 상태가 다르며 그로 인해 기댓값이 사용되었다.

 

2) 1단계 수식 설명

 a) \( \mathbf{q}_{*} \)를 이용해 \( \nu_{*} \) 계산하기

$$ \nu_{*}(s) = \underset{a}{\max} \mathbf{q}_{*} (s,a) $$

위 수식의 의미는 다음과 같다.

"상태 s의 최적밸류는 s 상태에서 선택할 수 있는 모든 액션들 중에 가장 높은 액션밸류와 같다."

 

아래 그림과 같은 상황으로 위 식을 좀 더 설명한다

 

벨만 기대 방정식 1단계에서

$$ \nu_{\pi}(s) = \sum_{a \in A} \pi(a \vert s) \mathbf{q}_{\pi}(s, a) $$

\( \pi(a \vert s) \) 부분이 빠진 이유는 상태 s에서 액션 a를 선택하는 방법은 정책확률에 따라 선택했었으나

벨만 최적 방정식에서는 액션밸류가 최대가 되는 a를 선택하는 방식이기 때문에 확률적 접근을 하지 않게 된다. 따라서 확률정보를 가지고 있는 정책확률 \( \pi \)가 필요없게 되어 빠진 것이다.

 

b) \( \nu_{*} \)를 이용해 \( \mathbf{q}_{*} \)계산하기

$$ \mathbf{q}_{*}(s, a) = r_{s}^{a} +\gamma \sum_{s^{'} \in S} P_{ss^{'}}^{a} \nu_{*}(s^{'}) $$

이 식은 벨만 기대방정식 1단계 \( \mathbf{q}_{\pi}(s, a) \)와 거의 같다. \( \pi \)가 * 로 변경되었다고 보면 된다.

이 식의 의미는 다음과 같다.

상태 s에서 액션a 의 액션밸류의 최대값은 그 상태에서 a액션 선택했을 때 받는 보상과 , 전이확률에 의해 다음 상태로 이동했을 때 이동한 상태에서의 최적의 상태밸류들의 합산 값을 감마 만큼 감쇠한 값을 합산한 것이다.

 

3) 2단계 수식 설명

1단계 수식 2개를 조합하여 2단계 수식을 구성할 수 있다.

 

2단계 수식을 사용하여 최적밸류를 계산하기 위해서는 기대방정식에서와 같이 보상과 전이확률을 알고 있어야 한다.

즉, MDP를 알고 있을 때 사용할 수 있는 수식이다.

 

정리차원에서 위에서 나온 벨만 기대 방정식과 최적 방정식을 같이 나열해본다.

 

1. 벨만 기대 방정식

2. 벨만 최적 방정식

벨만 방정식을 큰 틀에서 정리해보면,

MDP 상에서 정책 \( \pi \) 가 주어지고 해당 정책을 평가해야 하는 경우 벨만 기대방정식을 사용하여 계산한다.

최적의 밸류를 찾아야 할 경우는 벨만 최적방정식을 사용한다.

 

 

이후 과정에서 벨만 방정식에 대해 더 세부적으로 다룰 것이다.

 

 

* [바닥부터 배우는 강화학습] 도서를 읽고 정리한 글입니다

 

앞으로 이야기는 어떤 문제의 상황이 주어졌을 때 MDP의 형태로 만들어서 MDP를 풀어 문제를 해결해 나가는 방법을 논의할 것이다.

여기서 MDP를 푼다는 것은 MDP 형태 (S, A, P, R, \( \gamma \) )가 주어졌을 때 아래 2가지 문제를 해결하는 것을 의미한다.

(1) Prediction : 에이전트가 액션을 선택하는 방법에 대한 정책함수 \( \pi \) 가 주어졌을 때 각 상태의 밸류를 평가하는 문제

(2) Control : 최적 정책 \( \pi^{*} \)를 찾는 문제

 

좀 더 자세히 살펴보기 위해 그리드 월드 예시를 살펴본다.

- 먼저 그리드 월드상에서 Prediction을 설명한다.

Prediction을 하려면 당연히 에이전트가 액션을 취하는 방법인 정책 \( \pi \)가 주어져야 한다.

처음에는 간단하게 모든 상태에서 4방향으로 랜덤하게 움직이는 정책으로 정한다.

수식으로 표현하면 아래와 같다

$$ A= \left [ 동쪽으로 이동, 서쪽으로 이동, 남쪽으로 이동, 북쪽으로 이동 \right ] $$

$$ \pi(동 \vert s) = 0.25, \pi(서 \vert s) = 0.25 , \pi(남 \vert s) = 0.25, \pi(북 \vert s) = 0.25 $$

 

이런 MDP 모델에서 \( s_{11} \)의 상태 가치 \( \nu_{\pi} (s_{11}) \)의 값은 얼마일까?

이것이 Prediction 문제이고 해당 상태의 밸류(상태가치함수)를 예측(계산)하는 것이 목적이다.

 

수식으로 표현하면 앞에서 언급된 상태가치함수이다.

$$ \nu_{\pi} (s_{11}) = \mathbb{E} \left [ G_t \vert S_t = s_{11} \right ] $$

 

\( s_{11} \)에서 취할 수 있는 액션이 4가지 이므로 그에 따라 이동경로도 여러 경우가 나온다.

예를 들면, 

각각의 이동경로는 에피소드 라고 하며 

상태가치함수를 계산하기 위해서는 위의 에피소드의 각각의 경우에 대해 발생확률과 리턴값을 얻어내어 확률과 리턴값을 곱하여 기댓값을 계산해야 한다.

하지만 복잡한 환경에서는 모든 에피소드를 찾아내는 것이 불가능하므로 실제로 계산시에는 언급한 것처럼 계산하지는 않는다.

실제 계산방식은 뒤에서 설명이 이어진다. 여기서는 개념만 이해하고 넘어가도록 한다.

 

정리하면, Prediction 문제는 주어진 상태에서의 상태가치함수 계산을 통해 상태의 가치를 계산해 내는 문제이다.

 

- Control 문제

Control의 목적은 최적의 정책 \( \pi^{*} \)를 찾는 것이다.

복잡한 MDP 모델 상에서 최적의 정책을 찾는 것은 매우 어려운 일이며 이를 위해서 강화학습을 진행하게 된다.

 

최적의 정책 \( \pi^{*} \)를 따를 때의 가치 함수를 최적가치함수 라고 하며 \( \nu^{*} \)라고 표기한다.

 

만일, 최적의 정책 \( \pi^{*} \) 와 최적가치함수 \( \nu^{*} \)를 찾았다면 주어진 MDP를 풀었다고 한다.

 

다시 언급하면, 이후에는 Prediction 과 Control에 대한 내용을 중심으로 다루게 될 것이다.

 

* [바닥부터 배우는 강화학습] 도서를 읽고 정리한 글입니다

1. MDP의 정의

MRP에 에이전트 요소가 추가되어 각 상황마다 에이전트가 액션을 취하고 그것에 의해 다음 상태로 이동하며 환경으로부터 보상을 받게 되는 프로세스이다.

 

수식으로 정의하면 아래와 같다.

$$ MDP \equiv ( S, A, P, R, \gamma ) $$

 

- 상태의 집합 S

  해당 프로세스에서 가능한 모든 상태의 집합이다.

 

- 액션의 집합 A

해당 프로세스에서 취할 수 있는 모든 액션을 모아놓은 집합이다.

예를 들면, 포트폴리오를 운영하는 펀드매니저를 모델링한다면 펀드매니저가 취할 수 있는 모든 행동은 "매수하기", "매도하기", "관망하기" 이렇게 3가지로 정리할 수 있으며 따라서 액션 집합 A는 

 

                                              A={ 매수하기, 매도하기, 관망하기 }

 

에이전트는 스텝마다 위 액션의 집합 중 하나를 선택하여 액션을 취하며 그에 따라 다음 상태가 달라진다.

 

- 전이확률행렬P

$$ P_{ss^{'}}^a $$

위 식의 의미 : 현재상태가 s 에서 에이전트가 액션 a를 선택했을 때 다음상태가 \( s^{'} \) 이 될 확률

즉, 에이전트가 같은 행동을 하더라도 그 결과로 매번 같은 상태로 변하지 않으며 다음상태 변화는 정해놓은 확률 분포를 따른다는 의미이다.

전이확률의 엄밀한 정의는 다음과 같다

$$ P_{ss^{'}}^a = P[S_{t+1} = s^{'} \vert S_t = s, A_t = a ] $$

 

- 보상함수 R

MRP 에서는 상태 s 에서 바로 보상이 정해졌지만 MDP에서는 상태 s에서 에이전트가 액션 a를 선택해야 보상을 정할 수 있게 된다. 물론 여기서 보상도 확률적으로 접근되어 액션 a 를 선택해도 매번 보상은 달라지므로 보상의 기댓값을 사용해야 한다

MDP 에서 보상함수 R은 다음과 같다

$$ R_{s}^a = \mathbb{E}[R_{t+1} \vert S_t=s, A_t = a] $$

 

- 감쇠인자 \( \gamma \)

MRP에서의 \( \gamma \) 와 동일한 개념이다.

 

- MDP에서의 핵심은 보상의 합을 최대화하기 위해서 에이전트는 각 스텝에서 어떤 액션을 선택해야 할까를 정하는 것이다.

이 룰을 정책 (Policy) 이라고 한다. 좀 더 세부적으로 정책에 대해 알아보기로 한다.

 

2. 정책함수와 2가지 가치함수

 

- 정책함수

정책함수는 전체 보상의 합이 최대가 되기 위해서 각 상태에서 어떤 액션을 선택할 지 정해주는 함수이다.

정책함수 수식은 아래와 같다.

$$ \pi (a \vert s) = \mathbb{P} \left [  A_t = a \vert S_t = s \right ] => 상태 s에서 액션 a를 선택할 확률 $$

 

예를 들어, MDP 상의 상태 \( s_0 \) 에서 선택할 수 있는 액션이 \( a_0, a_1, a_2 \) 3가지 라고 할 때

정책함수는 \( s_0 \) 상태에서 에이전트가 \( a_0 \) 액션을 선택할 확률, \( a_1 \) 액션을 선택할 확률, \( a_2 \) 액션을 선택할 확률을 결정한다.

예를 들어, 수식으로 표현하면 아래와 같다

 

$$ \pi ( a_0 \vert s_0 ) = 0.2 $$

$$ \pi ( a_1 \vert s_0 ) = 0.5 $$

$$ \pi ( a_2 \vert s_0 ) = 0.3 $$

 

\( s_0 \)에서 취할 수 있는 모든 액션의 확률을 더하면 1.0 이 되어야 한다.

중요한 점은 정책 또는 정책함수는 에이전트가 가지고 있는 중요 기능이다. 

또한 강화학습을 통해 에이전트는 이 정책함수를 계속 고쳐나가야 한다.

 

- 상태가치함수

MRP 에서 가치함수는 상태가 주어지면 리턴의 기댓값으로 가치를 계산할 수 있었다.

하지만 MDP에서는 임의의 상태에서 에이전트의 액션이 결정이 되어야 그 액션에 따른 상태와 보상이 결정되며 그에 따른 리턴이 계산될 수 있게 된다.

다시 정리하면, 상태 S에서 정책함수 \( \pi \)가 결정되어야 리턴이 계산되어 가치함수의 결과를 도출할 수 있다.

수식으로 정리하면 다음과 같다

$$ \nu_{\pi}(S) = \mathbb{E}_{\pi}[r_{t+1}+\gamma r_{t+2}+\gamma^{2} r_{t+3} + ...\vert S_t=s] $$

리턴부분을 G 기호로 변환하면 아래와 같다

$$ \nu_{\pi}(S) = \mathbb{E}_{\pi}[G_{t} \vert S_t=s] $$

이 식의 의미는 상태 S부터 에피소드 끝까지 정책함수\( \pi \)를 따라서 움직일 때 얻는 리턴의 기댓값 이다.

중요한 것은 MDP 에서 상태가치함수는 정책함수에 의존적이다 라는 것이다.

 

- 액션가치함수

"각 상태에서 액션의 가치도 평가할 수 없을까?"

임의의 상태에서 취할 수 있는 액션의 가치를 모두 평가해본 후 그 중 가장 가치가 높은 액션을 선택하면 성능이 좋은 에이전트가 될 것이다.

이런 이유로 "상태-액션가치함수" 라는 개념이 나온다. 축약해서 "액션가치함수" 라고 한다.

 

"상태-액션 가치함수"의 정의를 수식으로 표현하면 아래와 같다

 

$$ \mathbf{q}_{\pi} (s,a) = \mathbb{E}_{\pi} \left [ G_t \vert S_t = s, A_t = a \right ] $$

(  s에서 a를 선택하고, 그 이후에는 \( \pi \)를 따라서 움직일 때 얻는 리턴의 기댓값 )

 

인풋 인자로 상태s 와 액션 a가 페어로 들어가는 것과 조건부식에 액션이 포함되는 것만 다르고 나머지는 상태가치함수와 같다.

상태-액션가치함수 인풋 인자로 상태 s 가 들어있는 이유는 무엇일까?

액션(a)의 가치를 평가할 때 항상 함께 고려해야 할 것이 상태(s)이다.

먼저 상태(s)가 정해지고 해당 상태에서 액션(a)을 취할 때 가치를 평가하는 것이 의미가 있다.

상태없이 액션만을 평가하는 것은 의미가 없고 틀린 결과를 도출해 낼 것이다.

예를 들면, \( S_0 \)  상태에서 액션 \( a_1 \)을 취해서 변경되는 다음상태와 보상은,  \( S_2 \)  상태에서 액션 \( a_1 \)을 취해서 변경되는 다음상태와 보상하고 서로 다르기 때문에 상태 s 에 대한 정보 없이 액션 a 만을 가지고는 정확하게 액션의 가치를 평가할 수 없다.

 

상태가치함수 \( \nu_{\pi}(s) \)와 상태-액션가치함수 \( \mathbf{q}_{\pi}(s,a) \) 는 주어진 상태 s 에서 어떤 액션을 취하는가 하는 부분에 차이가 있다.

상태가치함수 \( \nu_{\pi}(s) \)는 상태 s 에서 정책 \( \pi \)에 따르는 확률 분포에 의해 액션 a가 선택되어 지는 것을 고려한 함수이고, 

상태-액션가치함수 \( \mathbf{q}_{\pi}(s,a) \) 는 주어진 상태 s 에서 특정 액션 a로 선택된 것을 감안한 함수이다.

상태 s에서 액션 a가 선택된 이후에는 2가지 가치함수 모두 정책 \( \pi \) 에 따라 에피소드가 진행되는 점을 고려한다.

 

 

 

 

 

 

* [바닥부터 배우는 강화학습] 도서를 읽고 정리한 글입니다

2. 마르코프 리워드 프로세스 (Markov Reward Process)

마르코프 프로세스에 보상의 개념이 추가된 프로세스이다.

 

위 그림은 아이가 잠이 드는 과정을 마르코프 프로세스로 모델링하여 표현한 것이다.

아이가 특정 상태에 들어오면 그에 따른 보상을 받게 되어 있다.

 

MRP를 정의하기 위해서는

보상함수 \( R \)과 감쇠인자 \( \gamma \) (감마) 가 추가로 필요하다

$$ MRP \equiv ( S, P, R, \gamma ) $$

 

- 보상함수 R

R은 어떤 상태 s에 도착할 때 받는 보상을 의미한다

$$ R = \mathbb{E} \left [ R_t \vert S_t = s \right ] $$

 

기댓값이 나온 이유는 특정 상태에 도달했을 때 받는 보상이 매번 조금씩 다를 수 있기 때문이다.

예를 들어, 어떤 상태에 도달하면 보상을 줄 때 동전을 던져 앞면이 나오면 500원, 뒷면이 나오면 받지 못한다고 하면 실제 보상은 매번 달라질 것이다. 이런 경우 기댓값을 적용하면 보상은 250원이 된다. 

 

기댓값의 이런 성격을 이용하여 어떤 상태에 도달했을 때 보상을 일반화해서 표현을 할 때 기댓값이 사용되는 것이다.

 

거꾸로 생각해보면 어떤 값을 표현할 때 기댓값을 사용했다는 의미는 그 값이 항상 나오는 고정된 값이 아니라는 의미를 내포하고 있는 것이다.

 

- 감쇠인자 \( \gamma \) 

\( gamma \) 는 강화학습에서 미래 얻을 보상에 비해 당장 얻을 보상을 얼마나 더 중요하게 여길 것인지 나타내는 파라미터이다. ( 0 에서 1 사이의 숫자 )

 

더 구체적인 설명을 위해 우선 리턴 이라는 개념을 이해해야 한다.

 

- 감쇠된 보상의 합, 리턴

MRP 모델에서는 상태가 바뀔때마다 보상을 받는다.

상태 \( S_0 \) 에서 시작하여 보상 \( R_0 \)를 받고 이어서 다음 상태로 전환되면서 보상을 받는 프로세스로 진행되다가 마지막 상태 \( S_T \) 에서 \( R_T \) 보상을 받고 종료된다.

 

이와 같이 시작상태에서 마지막 상태까지 이동하는 과정을 에피소드 라고 한다.

에피소드를 기호로 표시하면 아래와 같다.

$$ S_0, R_0, S_1, R_1, ... , S_T, R_T $$

 

리턴 ( \( G_t \) )이란 t 시점 이후 상태 \( S_{t+1} \)에서부터 에피소드가 종료할 때까지의 미래에 받을 감쇠된 보상의 합이다

$$ G_t = R_{t+1} + \gamma R_{t+2} + \gamma^{2} R_{t+3} + ... $$

\( \gamma \)의 값이 0에서 1 사이 값이므로 먼 미래 시점 항은 \( \gamma \)를 여러 번 곱해지면서 계산값은 작아져 0에 가까워진다.

결국 t 시점의 리턴값은 먼 미래에 받을 보상의 영향은 줄이고 가까운 미래에 받을 보상의 영향을 크게 하는 방식으로 계산된다.

 

엄밀히 말하면 강화학습은 리턴값이 최대화되도록 학습하는 방식이라고 할 수 있다.

리턴은 과거의 보상값은 포함시키지 않는다. 과거는 중요치 않다는 것이다.

 

\( \gamma \)는 왜 필요한가?

\( \gamma \)를 1에 가까운 값을 사용하게 되면 미래 보상값이 리턴에 거의 그대로 영향을 주게되며 이것은 먼 미래도 중요시 생각하는 장기적인 시야를 갖도록 하는 모델이 되도록 할 것이다.

반대로 \( \gamma \)를 0에 가까운 값을 사용하게 되면 먼 미래 보상값은 0에 가깝게 작아지게 되어 근시안적인 모델이 되도록 할 것이다.

 1) 수학적 편리성 때문에

\( \gamma \)를 1보다 작게 해줌으로 리턴 \( G_t \) 가 무한의 값을 가지는 것을 방지할 수 있다.

따라서 다양한 수학연산에 리턴값을 활용할 수 있게 된다.

 

 2) 사람의 선호 반영

사람은 먼 미래에 보상보다 가까운 미래에 보상을 더 선호한다.

 

3) 미래에 대한 불확실성 반영

먼 미래 상태는 확률적으로 더 불확실 하므로 그에 대한 보상 역시 불확실성을 반영하여 감쇠시킨다

 

- MRP에서 각 상태의 밸류 평가하기

어떤 상태의 가치를 평가할 때 과거보다 미래를 고려하여 평가하게 된다.

MRP에서도 특정 시점의 상태에 대한 가치 밸류를 계산하려면 해당 시점 기준으로 미래에 받을 보상들의 합이 높으면 그 상태 밸류가 높다고 생각할 수 있다.

여기서 이야기한 미래에 받을 보상의 합이 바로 리턴값 ( \( G_t \) ) 이다.

 

문제는 리턴값이 매번 바뀐다는 점이다.

확률적 요소에 의해 다음 상태가 정해지므로  t 시점 기준으로 다음 도달 상태들이 매번 달라질 수 있다. 결국 그에 대한 보상이 달라지므로 보상의 합인 리턴값이 매번 바뀐다는 것이다.

이때 사용되는 개념이 기댓값 이다.

 

상태가치함수(State Value Function)

상태가치함수는 임의의 상태 S를 인풋으로 넣으면 그 상태의 밸류를 아웃풋으로 출력하는 함수이다.

$$ \mathcal{V}(S) =  \mathbb{E} \left [ G_t \vert S_t = s \right ] $$

조건부로 붙는 \( S_t = s \)의 의미는 시점 t에서 상태 s부터 시작하여 에피소드가 끝날 때까지의 리턴을 계산하라는 뜻

같은 상태에서 출발하여도 주어진 확률분포때문에 매번 실행할 때마다 에피소드가 달라지면서 리턴값이 달라지므로 

상태가치함수의 인풋으로 동일한 S를 입력하여도 결과 리턴값이 다르게 나오게 된다.

이런 경우 위에서 언급한 기댓값 성질을 이용한다.

 

여기서 \( S_t \) 상태의 가치를 계산하는 방법으로 리턴의 기댓값을 사용한다는 의미는 무엇일까?

\( S_t \) 상태부터 종료상태까지 해당 프로세스를 상당히 여러번 실행시켜 다양한 에피소드 샘플들을 얻어 각 샘플 에피소드의 리턴값을 합산 후 평균을 냄으로 기댓값으로 활용할 수 있다는 의미이다.

 

정리하면, MRP에서는 상태별 보상을 줌으로 현재 상태에 대한 리턴 이라는 개념을 추가하게 되었으며 이 리턴이 결국 상태가치함수 값이 된다.

 

다음은 MDP에 대한 설명으로 넘어간다

 

* 바닥부터 배우는 강화학습 도서를 읽고 정리한 글입니다

1. 마르코프 프로세스(Markov Process)

(1) 정의

미리 정의된 어떤 확률 분포를 따라서 정해진 시간 간격으로 상태와 상태 사이를 이동해 다니는 과정(Process)

 => 어떤 상태에 도착하면 다음상태가 어디가 될지 정의된 확률에 따라 정해지게 된다

하나의 상태에서 다음 상태로 이동을 가리키는 화살표는 확률에 따라 여러 개가 나타날 수 있으며 각 화살표로 이동확률의 합은 100% 이다

 

- 마르코프 프로세스 정의 표현식

$$ MP \equiv (S, P) $$

 

- 상태의 집합 S

마르코프 프로세스 전 과정에서 가능한 상태를 모두 모아놓은 집합 => S

 

- 전이확률 행렬 P

$$ P_{ss^{'}} $$

상태 \( S \) 에서 다음상태 \( S^{'} \)  로 이동할 확률을 의미한다

 

전이확률을 조건부 확률식으로 풀어서 표현하면 다음과 같다

$$ P_{ss^{'}} = \mathbb{P} \left [ S_{t+1} = s^{'} \vert S_t = s \right ] $$

 

전이확률행렬 이라고 표현하는 이유는 \( P_{ss^{'}} \) 값을 각 상태 \( s \) 와 \( s^{'} \)에 대해 행렬의 형태로 표현할 수 있기 때문이다.

 

만일 특정 마르코프 프로세스에서 모든 상태의 갯수가 5개라면 총 25개 확률값으로 구성된 전이확률 행렬을 구성할 수 있다.

 

위의 전이확률행렬을 이용하여 마르코프 프로세스를 그리면 아래와 같다

 

(2) 마르코프 성질

마르코프 성질은 다음과 같다

"미래는 오직 현재에 의해 결정된다"

$$ \mathbb{P} \left [  S_{t+1} \vert S_t  \right ] = \mathbb{P} \left [ S_{t+1} \vert S_1 , S_2 , ... , S_t \right ] $$

 

마르코프한 성질의 프로세스 예시

예를 들면, 체스 게임 - 다음 둘 수를 판단할 때 현재 체스 판의 상태만 분석하면 다음 둘 수를 (다음 상태) 결정할 수 있다.  즉 체스 게임은 마르코프 성질을 따르는 프로세스라고 할 수 있다.

 

마르코프한 상태인지 판단하는 한 가지 방법은 과거이력 정보가 없는 현재상태만 캡쳐한 정보를 가지고 최선의 다음 상태를 고려할 수 있나, 아니면 과거이력정보를 알면 더 좋은 다음 상태 선택이 가능한 가를 질의해 보는 것이다.

만일 현재상태 정보만 가지고 최선의 다음상태 선택이 가능하다면 마르코프한 성질을 따르는 프로세스라고 할 수 있다.

 

- 마르코프한 성질을 가지지 않는 프로세스 예시

예를 들면, 운전 - 현재 자동자 주변 상황을 사진으로 찍어놓고 지금 상태에서 다음에 브레이크를 밟아야 할지 엑셀을 밟아야 할지 판단할 수 없다

 

따라서 단순히 이런 방식으로 고려한다면 운전은 마르코프 성질을 따르지 않는 프로세스 라고 할 수 있다.

하지만, 만일 1초 마다 자동자 주변상황을 찍어서 과거 사진 10장을 (즉 10초 전 상황) 하나의 상태로 묶어서 제공된다면 다음 상황을 고려할 수 있게 된다.

(영국 딥마인드사에서는 비디오 게임 학습시킬 때, 시점 t 에서의 이미지와 함께 t-1, t-2, t-3 의 과거 이미지를 엮어서 하나의 상태로 제공하였다. 이렇게 함으로 해당 프로세스를 조금이라도 더 마르코프 성질을 따르도록 하기 위함이다)

 

어떤 현상을 마르코프 프로세스로 모델링 하려면 상태가 마르코프 해야 하며, 단일 상태 정보만으로도 정보가 충분하도록 상태를 잘 구성해야 한다

 

 

 

 

 

 

 

 

 

* 바닥부터 배우는 강화학습 도서를 읽고 정리한 글입니다

 

1. 강화학습이란 ?

"순차적인 의사결정 문제에서 누적 보상을 최대화하기 위해 시행착오를 통해 행동을 교정하는 학습과정"

 

예를 들면, 어린이 혼자 두발 자전거를 타면서 배워나가는 과정

 

2. 순차적 의사결정 문제

 - 순차적 의사결정 문제란 

  행위자가 목적을 정한 후 시간 순서대로 주어진 상황에서 목적을 이루기 위해 해당상황을 근거로 목적에 부합한 행동을 하고 그 행동으로 인해 상황이 변화되면 변화된 상황을 근거로 목적에 맞게 행동을 한다. 또 그 행동으로 인해 상황이 변하면 그 변화된 상황을 근거로 목적에 맞게 행동을 하는 순차적인 일련의 문제처리 과정

 

 - 순차적 의사결정 문제의 예

행위자가 아침에 기상해서 학교까지 등교하는 과정을 예를 들 수 있다.

(의사결정)세면 => (의사결정)아침식사 => (의사결정)교복으로 환복 => (의사결정)학교가는 길을 차례로 거쳐 도보로 이동 => 학교 교실 도착

 

이 과정 중에서 등교 과정 시간을 단축하기 위해서는 어떻게 하는 것이 좋을까? 라는 과제가 주어진다면

의사결정 행동에 조금씩 변화를 주면서 시도해보고 시간이 더 걸리는 행동을 피하고 시간을 단축시켰던 행동을 선택하여 전체적으로 등교 과정 시간을 단축시키게 될 것이다.

 

또 다른 예,

주식투자에서 포트폴리오 관리, 운전과정, 게임

 

 - 강화학습은 위의 예와 유사한 방식으로 순차적 의사결정 문제를 잘 처리해나가기 위한 머신러닝 방법이다

 

3. 보상

 - 보상이란 목적에 부합하여 의사결정을 잘 했을 때 그 부분을 의사결정 행위자가 인지할 수 있도록 알려주는 신호이다.

 - 강화학습 목적은 순차적 의사결정 과정에서 받은 보상의 누적합이 최대가 되도록 하는 것이다.

 - 보상의 특징 3가지

   1) 어떻게 X, 얼마나 O

    보상은 "어떻게"에 대한 정보를 가지고 있지 않다. 

    보상은 조금 못하고 있는지, 그저 그렇게 하고 있는지, 잘 하고 있는지, 매우 잘하고 있는지에 대한 정보를 담고 있다.

 

    2) 스칼라

    보상은 스칼라값으로 정해진다(벡터형식이 아니다) => 오직 하나의 목적만을 가지고 있는 값이어야 한다는 의미. 

    보상을 스칼라값 형태로 정할 수 없다면 강화학습 적용이 어렵다.

    최적의 보상을 결정하는 것이 중요하다!!

    보상의 예, 

       - 자산 포트폴리오 배분에서의 이득

       - 자전거 타기에서 넘어지지 않고 나아간 거리

       - 게임에서의 승리

 

   3) 희소하고 지연된 보상

    - 보상이 희소 할 수 있으며, 지연될 수 있다.

    - 행동과 보상이 일대일 대응되면 강화학습은 쉬워진다.

      하지만 대부분의 경우는 어떤 특정행동이 목적에 부합하게 된 것인지 판단을 지나고 나서야 알 수 있다.

      따라서 보상은 여러가지 행동을 한 이후에 주어질 수 있다. 결국 보상은 지연되어 제공될 수 있다는 의미가 된다.

 

4. 에이전트와 환경

위 그림은 순차적 의사결정 문제를 도식화 한 것

에이전트가 액션을 하고 그에 따라 상황이 변하는 것을 하나의 루프라고 한다면 이 루프가 반복되는 것을 순차적 의사결정 문제라 할 수 있다.

 

(1) 에이전트란

 - 강화학습의 주인공

 - 학습하는 대상

 - 운전하는 환경에서는 운전자가 에이전트가 되며, 게임 플레이하는 환경에서는 게임 플레이어가 에이전트

 - 어떤 액션을 할지 정하는 것이 가장 주된 역할

 - 에이전트 입장에서 위 그림의 루프는 3단계로 구성되어 있다

  1) 현재상황 St에서 특정 액션을 결정

  2) 결정된 액션을 환경으로 보냄

  3) 환경으로부터 그에 따른 보상과 다음 상태의 정보를 받음

 

(2) 환경

 - 에이전트를 제외한 모든 요소를 환경이라 한다.

 - 환경의 요소들을 숫자로 표현하여 기록해 놓으면 그것을 "상태" 라고 한다.

   따라서 상태는 여러 숫자들로 구성된 벡터로 볼 수 있다.

 - 환경은 상태변화를 일으키는 역할을 담당한다.

 - 환경 입장에서 위 그림의 루프는 4단계로 구성된다

   1) 에이전트로부터 받은 액션을 통해서 상태 변화 일으킨다

   2) 그 결과 상태가  St => St+1 로 바뀐다

   3) 에이전트에게 줄 보상 Rt+1 도 함께 계산된다

   4) 변경된 상태 St+1,  보상 Rt+1을 에이전트에게 전달

 

순차적 의사결정 문제에서 한 루프를 틱 혹은 타임스텝 이라고 한다.

 

5. 강화 학습의 위력

 (1) 병렬성

   (2) 자가학습

     지도학습처럼 정답을 알려주지 않아도 목적에 부합하도록 스스로 행동을 개선해나가는 능력

 

아나콘다를 이용해 파이썬 설치 후 파이썬 버전 확인방법

 - cmd 창에서 python --version 입력하면 파이썬 버전 출력된다.

 

1.3.1 산술연산

파이썬 3.X 버전에서는 정수 / 정수 의 결과 자료형은 실수(부동소수점)  (파이썬 2.X 에서는 결과 정수)

 

1.3.2 자료형

type() 함수로 변수나 값의 자료형을 알 수 있다.

예를 들면,

  type(10) => <class 'int'>

  type(2.7) => <class 'float'>

  type("hello") => <class 'str'>

결과출력에서 class는 자료형과 같은 의미로 사용

 

1.3.3 변수

파이썬은 동적언어이다 (변수의 자료형이 상황에 맞게 자동결정)

예, 

  a = 10

  type(a) => <class 'int'>

  a = 1.5

  type(a) => <class 'float'>

 

1.3.4 리스트

여러데이터를 리스트로 저장할 수 있다.

예,

 >> a = [1,2,3,4,5] #리스트 생성

 >> print(a) 

 [1,2,3,4,5]

 >> len(a)

 5

 >> a[0] #리스트의 시작 인덱스는 0부터 시작한다

 1

 >> a[4]

 5

 >> a[4] = 99

 >> print(a)

 [1,2,3,4, 99]

 >> b = a[0:2] #0번부터 2개를 얻어 b변수에 새로운 리스트 구성

 >> print(b)

 [1,2]

 >> b = a[0:10] #0번부터 10개를 얻어 b변수에 리스트 구성하라는 명령이지만 a리스트에 10개 원소가 없으므로 a가 소유하고 있는 5개를 이용해서 b 변수 리스트 구성

 >> print(b)

 [1,2,3,4,99]

 >> a[1:] #1번부터 끝까지

 >> a[:3] #0번부터 3개를 얻는다 (따라서 3번 항목은 포함하지 않는다)

 

 

 

 

 

 

 

1. pandas는 파이썬 언어로 그리드 성격의 데이터를 다룰 때 주로 사용된다

  - pandas의 dataframe을 주로 제어한다

2. dataframe의 3요소 : 컬럼, 데이터(로우), 인덱스

3. dataframe 만들기

import pandas as pd

- DataFrame 생성자를 이용해 만들기

dftest = pd.DataFrame([('bird', 389.0), ('bird', 24.0), ('mammal', 80.5), ('mammal', np.nan)], index=['falcon', 'parrot', 'lion', 'monkey'], columns=('class', 'max_speed'))

print(dftest)

출력:

             class    max_speed

falcon      bird            389.0

parrot      bird              24.0

lion       mammal          80.5

monkey mammal         NaN

 

- 넘파이 행렬을 이용해서 만들기

my_2darray = np.array([[123], [456]])

print(pd.DataFrame(my_2darray))

 

- dictionary를 이용해서 만들기

my_dict = {"a": ['1''3'], "b": ['1''2'], "c": ['2''4']}

print(pd.DataFrame(my_dict))

 

- DataFrame을 이용해서 새로운 DataFrame을 만들기

my_df = pd.DataFrame(data=[4,5,6,7], index=range(0,4), columns=['A'])

print(pd.DataFrame(my_df))

 

- 시리즈를 이용해서 만들기

my_series = pd.Series({"United Kingdom":"London""India":"New Delhi""United States":"Washington""Belgium":"Brussels"})

print(pd.DataFrame(my_series))

 

- csv 파일로드하여 만들기

data = pd.read_csv('dataset\\005930.KS_5y.csv')

 

4. DataFrame shape 알아보기

df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6]]))

 

- shape를 통해 column과 row 길이를 알 수 있다

print(df.shape)

 

- row의 개수를 알 수 있다.

print(len(df.index))

- column 타이틀명을 리스트타입으로 얻어낸다

print(list(df.columns))

 출력:[ 0, 1, 2]

 

dict = {"a": ['1''3'], "b": ['1''2'], "c": ['2''4']}

dict1 = pd.DataFrame(dict)

print(list(dict1.columns))

출력:['a', 'b', 'c']

 

5. DataFrame의 특정컬럼이나 로우(인덱스) 선택하기

-특정컬럼을 얻어낼 때:

c = df['column']

r = df.ix[index]

예제:

df = pd.DataFrame({"A":[1,4,7], "B":[2,5,8], "C":[3,6,9]})

a = df['A']

print(df)

출력:

   A  B  C
0  1  2  3
1  4  5  6
2  7  8  9

 

print(a)

출력:

0    1
1    4
2    7

 

b = df.loc[:, 'A']

print(b)

출력:

0    1
1    4
2    7

 

c = df.ix[0]['B']

print(c)

출력:

2

 

d = df.ix[1]

print(d)

출력:

A    4
B    5
C    6

 

e = df.loc[1]

print(e)

출력:

A    4
B    5
C    6

 

f = df.iloc[1]

print(f)

출력:

A    4 
B    5 
C    6

 

6. 로우 추가하기

ix의 경우 df.ix[2]인 경우 index=2인 로우를 찾아 그 로우에 데이터를 교체한다. 이때 index=2인 row가 없으면 로우를 새로 추가한다

예제:

df = pd.DataFrame(data=np.array([[10,11],[20,21],[30,31],[40,41]]),index=[3,4,5,2])

print(df)

    0   1
3  10  11
4  20  21
5  30  31
2  40  41

 

df.ix[2] = [0, 0]

print(df)

    0   1
3  10  11
4  20  21
5  30  31
2   0   0   ===>index=2인 로우를 찾아 데이터 교체

 

df.ix[1] = [1,1]

print(df)

    0   1
3  10  11
4  20  21
5  30  31
2   0   0
1   1   1  ==> index=1인 로우가 없어 마지막 줄 추가

 

7. append 이용해 row 추가

df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))

print(df)

   A  B

0  1  2

1  3  4

 

df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))

print(df2)

   A  B

0  5  6

1  7  8

 

df.append(df2)

print(df)

    A  B

 0  1  2

 1  3  4

 0  5  6  ==>df2의 index 그대로 셋팅

 1  7  8  ==>df2의 index 그대로 셋팅

 

df.append(df2, ignore_index=True)

print(df)

    A  B

 0  1  2

 1  3  4

 2  5  6  ==>index=2로 자동셋팅

 3  7  8  ==>index=3로 자동셋팅

 

8. 컬럼추가

df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])

df.loc[:, 'D'] = pd.Series(['5', '6', '7'], index=df.index)

print(df)

   A  B  C  D
0  1  2  3  5
1  4  5  6  6
2  7  8  9  7


9. 컬럼삭제

df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])

df = df.drop('A', axis=1)

print(df)

   B  C 
0  2  3  
1  5  6  
2  8  9 

 

df.drop('A', axis=1, inplace=True)

print(df)

   B  C 
0  2  3  
1  5  6  
2  8  9 

 

10. 로우 삭제

- 특정 index 번째 로우를 삭제 (0부터 카운트됨)

df = pd.DataFrame(data=np.array([[123], [456], [789]]), columns=['A''B''C'], index=[3,4,5])

df = df.drop(df.index[1])

print(df)

   A  B  C
3  1  2  3  
5  7  8  9

 

 

+ Recent posts