RL ch 2. MDP, Bellman Equation

|

2장 - 강화학습 기초 1: MDP와 벨만 방정식

MDP

  • 순차적 행동 결정 문제를 수학적으로 정의
  • 다음 6가지로 구성
    • state
      • agent가 관찰 가능한 상태의 집합(S)
      • $S ={(x_1,y_1),(x_2, y_2),…}$
    • action
      • agent가 할 수 있는 가능한 행동의 집합(A)
      • $A_t = a$ : t-step에 a라는 action을 취함
    • reward
      • 환경이 agent에게 주는 정보
      • $R_s^a = E[R_{t+1} \vert S_t=s,A_t=a]$
        • t-step에 상태가 s, 행동이 a일 때, 환경이 주는 보상의 기대값
        • 환경에 대해서 sampling
    • state transition probability
      • 같은 action을 취해도, 다음 state는 다를 수 있다.
      • $P_{ss’}^a = P[S_{t+1}=s’ \vert S_t=s,A_t=a]$
    • discount factor
      • 먼 미래의 보상을 현재의 가치로 따질 때 필요
    • policy
      • 어떤 state에서 agent가 할 action
      • $\pi(a \vert s) = P[A_t=a \vert S_t=s]$

MDP_grid.png

학습방법

  • agent는 환경으로부터, 상태($s_t$)와 보상($r_t$)를 받고, 자신의 policy($\pi$)에 따라 행동($a_t$)을 함
  • 환경은 행동($a_t$)에 대해 새로운 상태와 보상을 주고, agent는 보상을 최대화하는 방향으로 학습

IMAGE 사진 출처


Value function(가치함수)

  • Value function은 다음 두 가지가 존재 (보통 앞의 것을 value func라 하지만..)
    • State-value function - 상태의 가치
    • Action-value function(Q-function) - 상태 + 행동의 가치

State-value function

  • 먼저 return을 정의하자
    • $G_t = R_{t+1}+\gamma R_{t+2}+\gamma^2 R_{t+3}…$
    • 에피소드가 끝난 이후 보상들을 정산할 때 필요
  • 이제 value function을 정의하면
    • $v(s)=E[G_t \vert S_t=s]$
    • 어떤 상태에 있을 때의 앞으로 보상을 얼마나 받을 수 있을까
  • recursive하게 정의하면
    • $v(s) = E[R_{t+1}+\gamma v(S_{t+1}) \vert S_t=s]$
  • 사실 MDP에서 action을 취해야 다음 state로 가기 때문에, policy가 빠질 수 없다.
    • $v_\pi(s) = E_\pi[R_{t+1}+\gamma v_\pi(S_{t+1}) \vert S_t=s]$
    • 요게 Bellman Expectation Equation!! 뒤에 나옴

Action-value function (Q-function)

  • 상태 + 행동에 대한 가치를 매김
  • $q_\pi(s,a) = E_\pi[R_{t+1} + \gamma q_\pi(S_{t+1},A_{t+1}) \vert S_t=s, A_t=a]$

위 두 함수의 관계: $v_\pi(s) = \sum_{a\in A} \pi(a \vert s) q_\pi(s,a)$


Bellman Equation

  • Dynamic programming으로 문제를 풀기 전에 Bellman Equation을 정리해보자!
  • Bellman Expectation Equation
    • $v_\pi(s) = E_\pi[R_{t+1}+\gamma v_\pi(S_{t+1}) \vert S_t=s]$
    • $v_\pi(s) = \underset{a \in A}{\Sigma}\pi(a\vert s)[R_{t+1} + \gamma \underset{s’ \in S}{\Sigma}P_{ss’}^av_\pi(s’)]$
      • 별거 아니고, policy와 STP를 고려해서 계산한 것
    • 이 걸 찾는다는 것 -> policy $\pi$에 대해 state $s$의 value-function을 찾은 것!
  • Bellman Optimality Equation
    • optimal value-function
      • $v^*(s) = \underset{\pi}{max}[v_\pi(s)]$
      • $v_\pi(s)$중 현재 state의 가치를 최대화하는 policy를 찾아내는 것!
    • optimal Q-function
      • $q^*(s,a)=\underset{\pi}{max}[q_\pi(s, a)]$
    • 여기까지 구했으면 최적 정책을 만드는 것은 쉽다.

결론

Bellman Expectation Equation

Bellman Optimality equation

Q-function의 Bellman Optimality equation

list에 관해서 궁금증 해결

|

python list를 어떻게 효율적으로 쓸까 고민하다가 list에 대해서 공부를 좀 했다.

궁금증은 다음 두 가지였다.

  • python list의 구조는 어떻게 생겼는지… item 갯수를 알 때 효율적으로 넣는 방법(preallocation)
  • python list의 처음 alloc size와 append의 동작 방식

python list 구조와 preallocation

사실 처음에 preallocation을 하려면 어떻게 할까 찾아봤는데, 답변들이 [None] * size를 쓰면 된다고 했다. 이러면 size가 다른 객체들을 어떻게 넣지? 의문이 생겼고, 그래서 생긴 꼴을 찾아봤다.

참조 1 - PyListObject 구조를 보면 다음처럼 생겼다.

typedef struct {
    PyObject_VAR_HEAD
    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

대충 봐도 pointer로 item들을 가지고 있겠거니… 생각이 들며 다음 코드를 보면 확실해진다.

참조 2 - python list setitem

PyList_SetItem(PyObject *op, Py_ssize_t i,
               PyObject *newitem)
{
    PyObject **p;
    if (!PyList_Check(op)) {
        Py_XDECREF(newitem);
        PyErr_BadInternalCall();
        return -1;
    }
    if (i < 0 || i >= Py_SIZE(op)) {
        Py_XDECREF(newitem);
        PyErr_SetString(PyExc_IndexError,
                        "list assignment index out of range");
        return -1;
    }
    p = ((PyListObject *)op) -> ob_item + i
    Py_XSETREF(*p, newitem);
    return 0;
}

마지막 세 줄을 보면

  1. pointer를 옮기고
  2. item을 포인팅하고
  3. return

이다.

따라서 [None] * size는 포인터 배열을 한번에 alloc하는 정도로, append 시 포인터 배열 realloc에 대한 overhead만 줄여준다.

python list의 처음 alloc size와 append의 동작 방식

그러고보면 처음에 얼마나 메모리를 잡고있으며, append를 하면 어떻게 메모리를 할당하나 궁금해졌다.

결론은

  • 처음에는 한칸도 alloc하지 않는다.
  • 하나라도 append를 하면 4개를 alloc한다.
  • 그 뒤로 4개 이상 들어오면 8개로 realloc하며, 이를 반복!

요런 식으로 동작한다.

알아본 방법은 코드로 대체한다.

Python 3.5.3 (default, Jan 17 2018, 16:36:00)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]
>>> sys.getsizeof(l)
144
>>> sys.getsizeof(None)
16
>>> a = []
>>> sys.getsizeof(a)
64
>>> b = [None] * 100
>>> sys.getsizeof(b)
864
>>> a = [1]
>>> sys.getsizeof(a)
72
>>> a = []
>>> a.append(1)
>>> sys.getsizeof(a)
96

Deterministic Non-Autoregressive Neural Sequence Modeling by Iterative Refinement

|
  • 저자
    • Jason Lee, Elman Mansimov, Kyunghyun Cho

2. Non-Autoregressive Sequence Modeling


standard sequence modeling

  • 먼저 sequence를 modeling하는 방법 중 Autoregressive model에 대해서 설명한다.
  • sequence $Y = (y_1,…,y_t)$에 대해서,
    • $log\ {p(y_t \vert y_{<t})} = f_\theta(y_{<t})$
  • 요런 식으로 디자인하고, $f_\theta$는 RNN 종류를 쓰는 것이 standard LM이다.
    • 즉, 이전 step 들에 conditional하게 디자인을 한다!
  • 만약 번역과 같이 extra conditioning variable(X)이 들어가면
    • $log\ {p(Y \vert X)}$ 꼴로 변하게 될 것이다.

limitation

  • 위처럼 autoregressive한 모델은 디코딩할 때 문제가 된다.
    • $\hat{Y} = {argmax}_Y log\ p(Y \vert X)$ 를 뽑으려면,
    • condition이 자기 앞 step에 붙기 때문에,
      • decoding.png
      • vocab이 a, b만 있을 경우, 3-step까지 확률을 구하기 위한 그림

    • 모든 경우의 수를 봐야하며, 이는 vocab-size의 non-polynomial 시간이 걸린다.
    • 이래서 어느정도 polynomial한 시간에 풀기 위해
      • Greedy search: 매 스텝에 가장 확률이 높은것을 바로 뽑음
      • Beam search: pool size(width)를 정해서, 그만큼만 풀을 유지하며, 뽑아내는 방식.
    • 으로 근사시켜서 풀어버린다. -> Decoding Gap

Non-autoregressive model 소개

  • 최근에 나온 Non-autoregressive model은 step들이 모두 independent하다고 보고 풀어버린다.
  • $P(Y \vert X) = \Pi_t^Tp(y_t\ \vert\ X)$
  • 요렇게하면, conditionally independent니까, 한번에 뽑는 것이 가능하며, 근사시킬 필요도 없다!

Modeling Gap V.S. Decoding Gap

  • 근데, target variable들간의 잠재적 dependency가 network에 잘 반영되어야하는 문제가 있다.
  • 이 것을 논문에서는 potential modeling gap으로 정의함.
  • 그래서 NA는 A보다 modeling gap이 큰 대신, decoding은 아까 말한대로 polynomial에 optimal solution을 찾으며, 따라서 gap이 존재하지 않는다.
  • gg.png

3. Iterative Refinement for Deterministic Non-Autoregressive Sequence Modeling

3.1 Latent variable model


Modeling 및 lower bound 찾기

  • 위에서 target variable들 간의 potential dependency를 잘 잡는 것이 핵심이라 했기 때문에, 요걸 잘 잡는 것을 목표로 구현했겠지…
  • gtg.png
  • L개의 R.V.를 만들어서 marginalize를 하도록 한다.
  • 근데, 당연히 위의 식은 intractable하다!
  • 요럴 때, 우리가 자주 쓰는 트릭… Lower bound를 구해서 높이기…
    • L=1이라고 가정하면 요런 식으로 된다..
      • 1.png
      • 2.png
  • 최종적으로 lower bound는 다음처럼 된다.
  • 3.png

RV 잡기

  • L개의 RV를 마음대로 잡을 수 있었지만, 뉴럴 네트워크를 공유해서 쓰고싶었고, 그래서 output Y와 같은 타입으로 한정지음
  • 그러면 $p(Y^l \vert \hat{Y}^{l-1}, X)$를 한 decoding step으로 만들 수 있다.
  • 또한 parameter를 sharing하는 것을 통해 adaptive refienment step 결정이 가능했다고한다.

Training

  • trainig pair: $(X, Y^*)$ 에 대해
  • (3)번 식을 계산한다.
    • 4.png
  • 그리고 다음 식을 minimize한다.
    • 5.png

3.2 Denoising Autoencoder

  • 여기서 만든 모델이 Conditional denoising autoencoder의 학습과정으로 볼 수 있다고 한다.
  • Corruption process: $C(Y \vert Y^*)$
    • 정확한 output $Y^*$에 noise를 섞음
  • $\tilde{Y} \sim C(Y \vert Y^*)$를 sample함.
    • 각 $\tilde{Y}$는 (2)번 EQ의 input으로 할 수 있음.
  • 6.png
  • 위의 식을 minimize 하는 것이 목적!
  • 이 논문에 나온 대로 Corruption Process를 진행했다네…
    • $Y^=(y_1^, … , y_T^*)$의 각각의 element에 대해서,
    • $\beta \in [0, 1]$의 확률로 corruption을 결정
    • $y_{t}^*$를 corruption하기로 하면
      • $y_{t+1}^* \leftarrow y_t^*$로 대체하고
      • $y_t^*$를 vocab에서 uniform random으로 교체 하거나
      • $y_{t+1}^* \leftrightarrow y_t^*$로 swap
    • 위와같은 프로세스를 sequentially 진행한다.

3.3 Training

  • 실제 트레이닝은 앞에서 본 $J_{LVM}$과 $J_{DAE}$를 같이 섞어서 썼다.
  • 7.png
  • $\alpha_l \sim p_{DAE} \in [0,1]$: bernoulli distribution $p_{DAE}$에서 sample한 값.
    • $p_{DAE}$는 hyperparameter이다.
    • $\alpha_0=1$이다.(당연히… Y로부터 받는 input이 없으니까..)

Distillation


Length Prediction

  • $p(T \vert X)$가 필요함.
  • 그냥 training data의 target sequence length를 쓰도록 함

3.4 Inference

  • Inference는 한번에 모든 스텝을 뽑고, 이를 iteration 돌리는 작업..
  • 1.png
  • 그러면 언제 Iteration을 멈출까?
    • 사전에 정의한 criterion을 만족하면..
      • target sequence가 얼마나 바뀌는지,
      • conditional log-prob이 얼마나 바뀌는지,
      • 계산할 시간에 따라…
  • 맨 처음께 제일 그럴싸한 방법이라고 한다. 실험에 나온다고…

4, Related Work

  • 이거는 그냥 넘어가자..
  • Parallel Wavenet - IAF를 썼는데, 이는 요 논문의 방법이랑 비슷하다고 하네..
    • 근데 이거는 continuous space에서만 가능하다고 깐다..
  • Deliberation networks: Sequence generation beyond one-pass decoding
    • 요건 2step 짜리고, 2개의 autoregressive decoder를 가지고있다.

5. Network Architecture

  • ff.png
  • Encoder는 Original transformer와 같다.
  • Decoder 1은 $log\ p(Y^0 \vert X)$
  • Decoder 2는 $log\ p(Y^l \vert \hat{Y}^{l-1}, X)$
  • 을 모델링한 것!
  • Decoder 2는 iterative refinement step에 계속 공유가 된다.
  • Decoder에는 additional positional embedding이 들어간다.

6. Experimental Settings

  • NMT와 Image Caption Generation에 대한 실험을 해봤음
  • Target length prediction
    • NA network training시에는 안쓰이고, 따로 training했으며, decoding시에만 사용
  • Training and Inference
    • L = 3으로 트레이닝하고, Adam썼음
    • $p_{DAE} = 0.5$
    • 다음 output이 이전과 똑같을 때까지 iteration돌리는 방법 - adaptive

7. Results and Analysis


7.1 Quantitative Analysis

  • 2.png
  • 학습 시, iteration 4까지로 제한했는데도, decoding 시, iteration을 늘리면 결과가 더 좋음
    • conditional DAE로 가정한 것을 뒷받침해준다.
    • 3.png
  • quality <-> speed trade- off
  • WMT-15 EN-DE에서 퀄리티가 떨어짐
    • 다른 셋에 비해 length가 길다
    • 자세한 설명은 없고 나중에 조사한다네..
  • Image caption은 잘된다고 한다.

Decoding Latency

  • 4.png
  • log scale인 그림이다. 헷갈리지 말자
  • AR은 sentence length에 따라 증가하는 반면,
  • Non-AR은 모두 시간이 같다.
  • Adaptive의 경우는 물론 증가하지만 AR보다는 적게 증가한다.

7.2 Ablation Study

  • t2.png
  • model의 각 요소들이 얼마나 성능에 영향을 끼치는지 조사.
  • distillation이 엄청 중요했다고 한다.
  • inference시
    • postprocessing으로 연속하는 반복된 symbol들을 제거하면 성능이 많이 좋아졌다.
    • 역시 논문에 자주 쓰이는 나중에 조사해보겠다...

7.3 Qualitative Analysis

  • NMT
    • 5.png
    • iteration마다 단조증가로 좋아지지는 않지만 좋아진다..
  • Image Caption
    • 6.png
    • 점점 묘사가 좋아진다고 함.

8. Conclusion

  • 앞에 한 얘기 또 나오는 것은 정리하지 말자
  • deterministic lower bound를 더 tight하게 구하면 좋을 것이다.
  • corruption process를 좀 더 잘 만들면 좋을 것이다.

__repr__, __dict__

|

Obeject의 속성값을 알고싶은데…

Obeject의 속성값을 알고싶은데 print()로 찍어보면 <__main__.OrigClass object at 0x10bedd0b8>이런 식으로만 나온다.

이럴 경우, __repr__을 통해 알 수 있도록 만들 수 있다.

물론 __repr__eval함수에 넘겼을 때, 정확히 똑같은 object가 만들어지는 string representation을 만들도록 권장한다. __dict__함수를 사용해서 속성을 볼 수도 있다!

코드

class OrigClass(object):
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y


class RepresentativeClass(OrigClass):
    def __repr__(self):
        return "RepresentativeClass({}, {})".format(self.x, self.y)

if __name__ == '__main__':
    o = OrigClass(10, 20)
    r = RepresentativeClass(10, 20)
    
    print(o)  # 그냥 돌리니까 메모리 주소만 나오겠지...
    print(r)  # 요 경우 RepresentativeClass(10, 20)가 나오겠다..
    r2 = eval(repr(r))  # 이걸 다시 eval에 넘기면
    print(r2)  # 같은 attr을 갖는 객체를 만들 수 있다!
    print(o.__dict__)  # 속성값만 알고싶을 때..

결과값

<__main__.OrigClass object at 0x106f1e0b8>
RepresentativeClass(10, 20)
RepresentativeClass(10, 20)
{'y': 20, 'x': 10}

Object Detection & Localization 요약

|

History

IMAGE

R-CNN류

R-CNN

IMAGE

  1. CNN fine-tuning (3번에 쓰일 Classifier)
  2. Selective search로 ROI 계산
  3. ROI들을 warp해서 (2)CNN에 넣고 feature extract를 수행한다.
  4. 분석된 Feature들을 softmax classifier나 SVM에 붙여서 각 proposal의 score를 매긴다.
  5. Non-Maximum Suppression(NMS)을 이용하여 bounding box를 구한다.

    NMS 예제 IMAGE

  • 문제점
    • CNN, SVM, BB regressor등을 훈련해야함.
    • 비슷한 박스들을 CNN돌리니까 느려…

Fast R-CNN

IMAGE

  • CNN network를 전체 이미지에 대해서 한번에 하고 ROI를 즐 뽑아내면 CNN 돌리는 시간이 줄어듬
  • SVM, BBR을 하나의 network로 트레이닝함

Faster R-CNN

Selective Search가 Bottleneck이다. 이를 뒤에있는 CNN의 weight를 이용해서 구현하면 훨씬 빠르고 쉬워진다! -> Region proposal network(RPN)

단점

Selective search를 하든, RPN을 쓰든 어쨌든 느리다. 그래서 사실 논문을 제대로 안보고 스킵스킵…


Single Shot Detector류

speed.png Single Shot Detection으로 오면서 7fps가 45fps로 껑충 뛰게된다.참조 슬라이드

YOLO (You only look once)

IMAGE

  • 이미지를 grid로 나눠서, 해당 grid안에 center가 있는 boundingbox들의 위치와 confidence를 학습시킴
  • 처음에는 VGG를 가져다쓰고, 이를 CNN Layer 여러개를 거치고, FC를 하면 7x7x30의 feature가 나온다. IMAGE
  • 여기서 하나의 그리드에 30이 나오는데
    • [2개의 bounding box(각각 5개 x,y,w,h,c) + 20개의 class에 대한 conditional class prob.]를 의미한다.
    • yolo.png
    • c는 해당 BB의 confidence 즉,p(object). 설명 안하고 넘어갔는데, 사실 bounding box의 확률은, object가 존재하는지와, 해당 object가 어떤 class인지 두가지로 나뉘어져있다.

  • 요걸 가지고 비슷한 box에 대해서 Non-maximum suppression을 하면 완성!

loss

  • loss.png
    • object가 존재할 때, center 차이의 제곱
    • object가 존재할 때, width, height의 root의 차이의 제곱
    • object가 존재할 때, Confidence score 계산(Ci가 1)
    • object가 존재하지 않을 때, Confidence score 계산(Ci가 0)
    • object가 존재할 때, 각 class의 확률 차이의 제곱

Limitation of YOLO

베껴옴

  • 각각의 grid cell이 하나의 클래스만을 예측할 수 있으므로, 작은 object 여러개가 다닥다닥 붙으면 제대로 예측하지 못한다.
  • bounding box의 형태가 training data를 통해서만 학습되므로, 새로운/독특한 형태의 bouding box의 경우 정확히 예측하지 못한다.
  • 몇 단계의 layer를 거쳐서 나온 feature map을 대상으로 bouding box를 예측하므로 localization이 다소 부정확해지는 경우가 있다.

SSD(Single Shot multibox Detector)

  • Yolo와 거의 비슷하나, Convolution layer의 중간중간에서 모두 feature를 뽑는 점이 크게 다르다.
    • IMAGE
    • 위의 그림에서 Detections에 들어가는 화살표가 convolution layer 사이사이에 존재함.
  • 또한 각 grid에서는 location관련정보 4개[∆(cx, cy, w, h)]와 각 class의 confidence로 이루어진다.
  • ssd1.png
  • 좀 더 자세히 알고싶으면 여기…

loss 계산

  • confidence와 location error를 loss로 씀
    • 1.png
  • location error
    • 2.png
  • confidence error
    • 3.png

      smooth-L1 loss는 0 근처에서 quadratic인 l1 loss의 변형이다.