2017년 12월 18일 월요일

RL Summary

RL 학습할 net(RNN or DNN)이 있다고 가정하자. net 출력은 $prob$ (부류별) 값으로, action 부류별 분포가 혼합된 multi-nomial $prob$이다. Monte Carlo 샘플링으로 부류정보와 $prob$ 얻고, 부류 정보(action)는 제어 대상 system에 가해서 reward 얻는다.

reward 값으로부터 학습할 net loss를 구성하면,

$loss = -\sum( \log{p_i} * (r_i-baseline) )$

이다. $r$은 최신값에 가중된(그리고 정규화된) 보상 값이다. 또,

$baseline = \begin{cases}
                0, reinforce(정규화\ 시^{각주1})\\
                Moving\ average\ of\ r_i, reinforce(정규화\ 않을\ 시)\\
                V, Actor\ Critic(V는\ 가치망\ 출력)\\
                \end{cases}$

이다. RL이 적용된 사례를 보면 다음과 같다.

(예 1) Cartpole 문제 상태 입력은 state 요소간 상관성 없음 (요소간 독립적). 따라서 RL net은 rnn대신 dnn 사용
(예 2) NAS 경우, RL net 출력을 이용하여 구성하는 reward 시스템(DNN Archtecture)은 전후 상관성(Layer 연결로 이전 값이 다음 값에 영향 줌) 존재. RL net은 RNN을 사용하며, LSTMCell 출력을 다음 셀 입력으로 넣는 과정으로 구성.

(예 3) ENAS 경우
RNN 출력값 샘플링 -> 샘플링 다수(여러 DNN 사례 생성) -> 여러 DNN 구성 -> 최적 오차 net 선택 -> 선택  net 오래 학습 -> reward -> RNN 학습.

ENAS 출력은 2255/3355/4455/5555/6655이다.
2255는 2,2,5,5개 출력을 가지는 LSTMCell 4개: 2(DNN Micro-Cell 두 개 입력 중 어디 선택할지 onehot vec 표현), 5(연산자 5개 중 어떤 선택할지).
LSTMCell 출력은 [(None,32),(None,32),(None,32)] 3개 요소, 첫번째는 reshape((None,1,32)으로) 해서 다음 LSTMCell 입력으로 사용하고 상단부 dense넷 입력으로도 사용.
나머지 2개는 다음 LSTMCell 용 state 입력으로 사용(cell, hidden).
2255 네 개 중 마지막 출력은 3355 네 개 셀 첫 입력으로 사용.

3355는 3,3,5,5개 출력을 가지는 LSTM셀 4개: 3(세개 입력중 어디 선택할지), 5( " )
...



(각주1) 정규화는 저장된 보상값 $r$ 리스트 평균을 구해 빼고 분산을 나눈다.

2017년 11월 2일 목요일

Actor-Critic

상태 $s$를 받아 action $a$를 출력하는 신경망(deep neural network, 인자 $\theta$로 표현)이 하나 있다.

$p(a|s; \theta)$

여기서 $p$는 파라메터 $\theta$로 표현되는 망의 출력 값이고, 상태 $s$를 입력받아 계산된 action 확률값이다.
만일 action 라벨이 있다면 교사학습이 되고 cross-entropy식은

$loss = -\log {p(a|s)*y}$

이다. $loss$를 줄이도록 학습을 진행하면 된다. 이 때 $p$는 prediction값이고 $y$는 교사값이다.


그런데 강화학습(RL)에서는 입력 $s$에 대해 어떤 action이 유리한지를 표현하는 $y$가 직접 주어지지 않는다.

강화학습에서 망의 학습 방법을 살펴 보자.
$p(a|s; \theta)$에 임의 상태 $s$를 입력하여 얻은 action 중에서 하나($a_s$라 하자)를 택한다.
이 값을 제어 대상인 환경 $env$에 작용시켜 응답을 얻는다. 이 응답을 미래보상의 근사치 계산을 위해 이용한다.

($p(a|s)$는 정책(policy)이라 부른다. 주어진 상태에서 어떤 행동을 택할지에 대해 각각 행동에 분배한 확률이다.)


환경 $env$에 $a_s$를 가하면,

$s', r, d, = env.step(a_s)$

이고 출력은 다음상태 $s'$, 즉각보상 $r$ 등이다.

만일 우리가 큐함수 $Q(s,a)^{각주1}$를 가지고 있다면 현재 상태 $s$에 대해 어떤 action이 좋은지 Q값에서 직접 얻을 수 있다. 그러나 $Q(s,a)$는 최적 미래 보상을 나타내는 일종의 매직함수이므로 직접 구하기 어렵다.
Q를 구하기 어렵기 때문에 근사화 하기 위해 가치망 $V$를 이용한다. $V(s)$로 각 스텝(state)에서 얼마나 행동이 좋은지 판단한다.

따라서 최적 미래 보상(reward)인 교사치 $y$는

$y = Q(s,a) = r + V(s')$

이고, 이 식이 Bellman 방정식이다.
(DQN에서는 $V(s')$ 대신에 max $Q(s',:)$를 이용했었고 $r$+max $Q(s',:)$를 best action으로 사용하였다.)

이상에서 $p(a|s; \theta)$는 정책망(policy net)이고 $V(s)$는 가치망(value net)이다.


정리하면, 정책 근사는 정책망 $p(a|s; \theta)$로 하였고, Q함수를 표현하기 위해 망이 하나 더 필요한데 이를 위해 가치망이 사용된다. 가치망은 정책 근사망인 $p$를 평가한다.
따라서, 이를 actor-critic이라고 부른다. actor는 정책 발전의 역할, critic은 정책 평가의 역할을 맡는다. 2개 망 동시 학습이 필요하다. 정책망의 경우 교사치

$loss = -\log {p(a_s|s; \theta)*[y-V(s)]}$

를 gradient descent로 학습하면 된다. 수렴은 policy gradient에 기반하며 다음을 참고한다. $y$에서 $V(s)$를 뻼은 학습 시 variance를 줄인다.
여기서 $p(a_s|s)$는 정책망 $\theta$에 $s$를 입력하여 출력으로 나온 여러 action 중에서 $a_s$에 대응하는 확률 값이다.

가치망의 학습은

$loss=(y-V(s))^2$

을 직접 줄이도록 진행된다.


참고 문헌
[1] Naver D2
[2] DennyBritz github


(각주 1) $Q(s,a)$ 함수는 Quality 함수라 하고, 상태 $s$에 대해 어떤 action $a$를 선택할지를 미리 Lookup table로써 만들어 놓은 것이다. $s$나 $a$ 공간을 이산화 했을 때, 개수가 몇 개 안되면 생성 가능 하지만 상태공간이 커지면 만들기 어려워 진다.



2017년 10월 19일 목요일

DQN

DQN(Deep Q-Network)은 딥 신경망(DNN)을 이용하는 강화학습(Reinforcement Learning)의 일종이다.

환경 $env$를 제어하는 강화학습에서 action $a$에 대한 확률을 결정하는 Q(Quality) 함수는 $Q(s,a)$로 주어진다. 상태 $s$에 대해 적절한 행동 $a$를 결정하는 정책이 들어 있다.

적절하다는 것은 주어진 환경 $env$의 현재 상태 $s$에서 action $a$를 선택했을 때 다음 단계에서 끝 단계 작업(episode) 종결 시까지 얻을 수 있는 보상 합의 최대값을 줄 수 있다는 것이다. 이런 Q함수는 이상적이지만 실제로 존재할 수 없는 일종의 매직 함수이다.

DNN은 $Q(s,a)$ 함수를 근사한다. Q는 주어진 상태 $s$를 입력 받아 여러 액션 중 하나의 $a$를 줄 수 있어야 한다. Q를 근사하는 DNN은 입력 $s$를 취해 여러 $a$에 대한 확률값 출력을 제공 한다.



매직 함수인 Q를 실제 계산하기 위해서는 현 상태 s에서 작업 종결 끝까지 반복 수행하면서 단계별 보상을 더해서 구한다. 그러나 이는 불가능하므로, 근사적으로 구하는 방법을 취한다.

이 과정은 다음과 같다.
현 상태 $s$에서 제어 대상 환경 $env$에 어떤 action을 가하고, 어떤 reward가 발생하는지 본다. 이 reward를 이용하여 Q를 갱신하고, 변경된 상태를 다시 갱신된 Q에 넣어 추출한 $a$를 $env$에 가하고 어떤 reward가 발생하는지를 살펴보고 Q를 또 갱신한다. 이러한 과정을 수없이 반복하다보면 초기에는 매직 Q와 멀었던 Q 함수가 점점 이상적인 Q에 가까와 지게 된다.

정리를 해보면 DQN의 요소에는

1. $Q(s,a)$를 표현하는 DNN이 있고
2. 액션 $a$를 가해 상태를 $s$에서 $s'$로 바꿀 환경 $env$가 존재한다.

환경 $env$는 현재 상태 $s$에서 액션 $a$를 가할 경우, 상태를 $s'$로 바꾸고, 보상 값을 리턴한다.

$s', r, d = env.step(a)$

의 형태인데, $a$를 입력으로 받아 $s$는 $s'$가 되고, 보상 $r$과 현재 episode 종결여부 $d$를 리턴한다.




통상 DNN의 학습을 위해서는 predict와 label이 필요하며 두 값의 차이가 loss이고 DNN은 loss를 최소화 하도록 내부 파라메터들을 갱신하게 된다.

predict와 label을 정의하기 위해 $env$에 가해지는 한 단계만의 액션을 생각해 보자.
현 단계 $Q(s,a)$를 표현하는 DNN이 있다. 먼저 $env$를 한 단계 전진 시키기 위해서는 $env$에 가할 $a$가 필요하다.

(1) $a$를 구하기 위해 현 상태 $s$를 DNN에 입력하여 DNN이 주는 최적의 $a$를 택한다. 이 $a$는 갱신전 DNN(즉, Q)이 주는 $a$이다.
(2) $a$를 $env$에 가해 $s', r, d$를 얻는다. 이 때, 새로 생성된 $s'$를 이용한다. DNN에 넣어 새로운 $Q(s', :)$를 만들어 낼 수 있다.

벨만 방정식 (Bellman equation)은 갱신된 Q값이 근사적으로 다음과 같음을 보여준다.

$Q(s,a) = r + max Q(s', :)$

갱신된 Q값은 $env$에 $a$를 가해 얻은 보상 $r$에다 새 상태 $s'$에 대한 Q값 중 최대값의 합으로 주어진다.

여기까지 계산하면 이전의 Q와 갱신된 Q가 얻어진다.

predict는 현재 Q(즉 현재의 DNN)에서 $s$를 넣어 나오는 $a$를 취하고, label은 Bellman식을 통해 계산된 값을 취한다.
그런데, Bellman식은 초기 Q에 $a$를 가해 만든 새로운 Q값이므로 해당되는 그 $a$의 값에 대해서만 갱신된 값이다.

즉, $a$의 액션 공간이 0~2까지로 3개라고 하면 초기 $Q(s)=DNN(s)=a[0:3]$이고, $env$에 가해준 $a$가 $a[1]$이었다면,
label역할을 하는 갱신 $a$는 3개 값 중, $a[0], a[2]$는 같고, $a[1]$만 달라진,
{ $a[0],\ r+maxQ(s', :),\ a[2]$ }이다.

따라서

predict = {$a[0], a[1], a[2]$}
label = {$a[0], r+maxQ(s', :), a[2]$}

이다.



2017년 1월 24일 화요일

분류 오차에 Cross entropy를 사용하는 이유

신경망 분류 오차를 줄이기 위한 최적화는 Net 출력 결과와 사용자 Label 정보 차이를 Error 정의한 후, 값을 줄이도록 Net 파라메터를 바꾸어 나가는 것이다

오차로는 분류 오차(classification error) 평균제곱 오차(MSE: mean square error) 일반적으로 생각할 있는 것들이다.
하지만 이들 보다 평균 Cross Entropy 오차(ACE: Averaged cross entropy error)를 빈번하게 사용하며 이유가 있다


적절히 학습된 Net 2개 있다고 하자. 부류(class) A, B, C 3개라고 했   두 넷이 주는 결과는 아래와 같다고 가정한다.


첫번째 넷이 주는 계산 결과:
계산결과         | 라벨(A/B/C)           | correct?
-----------------------------------------------
0.3  0.3  0.4  | 0  0  1 (A)          | yes
0.3  0.4  0.3  | 0  1  0 (B)          | yes
0.1  0.2  0.7  | 1  0  0 (C)          | no
분류 오차(classification error)를 계산해 보면 사용된 3개 샘플 중에 1개가 라벨과 일치하지 않으므로 1/3=0.33이다. 또한 분류 정확도(classification accuracy)는 2/3=0.67이다. 계산 결과를 보면 첫 샘플 2개는 겨우 맞추었고 세번째 샘플은 완전히 틀렸다.




두번째 넷이 주는 계산 결과:

계산결과         | 라벨(A/B/C)           | correct?
-----------------------------------------------
0.1  0.2  0.7  | 0  0  1 (A)          | yes
0.1  0.7  0.2  | 0  1  0 (B)          | yes
0.3  0.4  0.3  | 1  0  0 (C)          | no
첫번째 Net과 마찬가지로 분류 오차는 0.33이고, 분류 정확도는 0.67이다. 그러나 첫 두 샘플은 위 Net 보다 좀 더 확실히 맞추었고 세번째 샘플은 아깝게 틀렸다. 


위 두 Net을 비교하면서 분류 오차를 살펴 보면, 단순 분류 오차 계산은 틀린 개수에 대한 결과만 줄 뿐 라벨과 비교하여 얼마나 많이 틀렸는지, 얼마나 정확하게 맞았는지 그 정도에 대한 값을 제공하지 않는다. 



이와 비교하여 Cross entropy 오차를 계산해 보자. Cross entropy error의 정의

$-\sum_{i} y_i log(y_i^\prime)$

와 같다. $y_i$는 라벨값으로 one-hot vector로 주어지고, $y_i^\prime$는 넷 계산결과이다. 
첫번째 넷, 첫번째 샘플에 대해 계산해 보면 다음과 같다. 


-( (ln(0.3)*0) + (ln(0.3)*0) + (ln(0.4)*1) ) = -ln(0.4)


나머지 두 샘플 모두에 대해 계산하고 평균하면       


-(ln(0.4) + ln(0.4) + ln(0.1)) / 3 = 1.38

이다. 두번쨰 넷에 대해 평균 cross entropy를 계산하면


-(ln(0.7) + ln(0.7) + ln(0.3)) / 3 = 0.64

가 된다. 두 넷의 결과를 비교해 보면 두번째 넷이 오차가 더 작음을 알 수 있다. 즉, 넷이 주는 분류 오차에 정확도가 고려되어 최적화 관점에서 어떤 넷이 더 잘 학습되었는지를 알 수 있다. 수식에서 $log$ 연산자가 그 역할을 한다. 



다음으로 평균 제곱오차에 대해 살펴 보자. 
첫번째 넷, 첫번째 샘플에 대해 제곱오차를 살펴보면


(0.3 - 0)^2 + (0.3 - 0)^2 + (0.4 - 1)^2 = 0.09 + 0.09 + 0.36 = 0.54


이고 나머지 두개의 샘플에 대해 계산하고 평균한 제곱오차를 계산하면 다음과 같다. 
(0.54 + 0.54 + 1.34) / 3 = 0.81

첫 두 샘플은 맞은 것이고 세번째는 틀린 것이다. 제곱오차 크기는 세번째가 가장 크다.


두번쨰 넷에 대해서도 유사하게 계산하면
(0.14 + 0.14 + 0.74) / 3 = 0.34
이다. 


두 넷에 대한 계산 결과에서 보듯이 MSE는 틀린 샘플에 대해 더 집중하는 특성을 가진다. 맞은 것과 틀린 것에 똑같이 집중해야 하는데 그렇지 않아 오차 정의로는 적절하지 않다.



학습 과정 동안 나타나는 평균 제곱 오차(MSE)와 교차 엔트로피 오차(ACE)를 비교해 보자.
역 전파 학습 중에 목표 값(label)에 따라 출력 노드 값을 1.0 또는 0.0으로 설정하려고 한다.

이 때, MSE를 사용하면 가중치 계산에서 기울기 값에 (output) * (1 - output)이라는 조정 요소가 포함된다. 계산 된 출력이 0.0 또는 1.0에 가깝거나 가까워짐에 따라 (output) * (1 - output)의 값은 점점 작아진다.
예를 들어 output = 0.6이라면 (output) * (1 - output) = 0.24이지만 출력이 0.95이면 (output) * (1 - output) = 0.0475이다. 조정 요소가 점점 작아지면서 가중치 변화도 점점 작아지고 학습 진행이 멈출 수 있다.

그러나 ACE를 사용하면 (output) * (1 - output) 항이 사라진다. 따라서 가중치 변화는 점점 작아지거나 하지 않으므로 학습이 멈추거나 하지 않는다.
(위 경우는 노드 Activation을 softmax로 했을 경우이다.)



참고 문헌
[1] J. M. McCaffrey의 블로그