for Robot Artificial Inteligence

30. Standard Template library(STL) - List, Stack & Queues, Complex Data

|

List

  • 리스트(list) 의 경우 양방향 연결 구조를 가진 자료형이라 볼 수 있습니다.
  • 따라서 vector 와는 달리 임의의 위치에 있는 원소에 접근을 바로 할 수 없습니다.
  • list 컨테이너 자체에서는 시작 원소와 마지막 원소의 위치만을 기억하기 때문에, 임의의 위치에 있는 원소에 접근하기 위해서는 하나씩 링크를 따라가야 합니다.
  • 그래서 리스트에는 아예 [] 나 at 함수가 아예 정의되어 있지 않습니다.
  • vector 의 경우 맨 뒤를 제외하고는 임의의 위치에 원소를 추가하거나 제거하는 작업이 O(n)O(n) 이였지만 리스트의 경우 O(1)O(1) 으로 매우 빠르게 수행될 수 있습니다.
  • 왜냐하면 원하는 위치 앞과 뒤에 있는 링크값만 바꿔주면 되기 때문입니다.

예제

#include <iostream>
#include <list>

int main() {
  std::list<int> lst;

  lst.push_back(10);
  lst.push_back(20);
  lst.push_back(30);
  lst.push_back(40);

  for (std::list<int>::iterator itr = lst.begin(); itr != lst.end(); ++itr) {
    std::cout << *itr << std::endl;
  }
}

결과

10
20
30
40
  • 주의할 점은 리스트의 반복자의 경우 다음과 같은 연산 밖에 수행 할 수 없습니다.
itr++    // itr ++

itr--  // --itr 도 됩니다.

itr + 5 //불가능
  • 임의의 위치에 있는 원소를 가리킬 수 없다는 것입니다.
  • 반복자는 오직 한 칸 씩 밖에 움직일 수 없습니다.
  • 즉, 메모리 상에서 원소들이 연속적으로 존재하지 않을 수 있다는 뜻입니다.
  • 반면에 벡터의 경우 메모리 상에서 연속적으로 존재하기 때문에 쉽게 임의의 위치에 있는 원소를 참조할 수 있습니다.
  • erase 함수를 이용하여 원하는 위치에 있는 원소를 지울 수 도 있습니다.
  • 리스트의 경우는 벡터와는 다르게, 원소를 지워도 반복자가 무효화 되지 않습니다.
  • 왜냐하면, 각 원소들의 주소값들은 바뀌지 않기 때문입니다.

Example

  • 1번째 배열에 100이 추가가 된다.
#include <iostream>
#include <list>

template <typename T>
void print_list(std::list<T>& lst) {
  std::cout << "[ ";
  // 전체 리스트를 출력하기 (이 역시 범위 기반 for 문을 쓸 수 있습니다)
  for (const auto& elem : lst) {
    std::cout << elem << " ";
  }
  std::cout << "]" << std::endl;
}
int main() {
  std::list<int> lst;

  lst.push_back(10);
  lst.push_back(20);
  lst.push_back(30);
  lst.push_back(40);

  std::cout << "처음 리스트의 상태 " << std::endl;
  print_list(lst);

  for (std::list<int>::iterator itr = lst.begin(); itr != lst.end(); ++itr) {
    // 만일 현재 원소가 20 이라면
    // 그 앞에 50 을 집어넣는다.
    if (*itr == 20) {
      lst.insert(itr, 50);
    }
  }

  std::cout << "값이 20 인 원소 앞에 50 을 추가 " << std::endl;
  print_list(lst);

  for (std::list<int>::iterator itr = lst.begin(); itr != lst.end(); ++itr) {
    // 값이 30 인 원소를 삭제한다.
    if (*itr == 30) {
      lst.erase(itr);
      break;
    }
  }

  std::cout << "값이 30 인 원소를 제거한다" << std::endl;
  print_list(lst);
}

Result

처음 리스트의 상태
[ 10 20 30 40 ]
값이 20 인 원소 앞에 50 을 추가
[ 10 50 20 30 40 ]
값이 30 인 원소를 제거한다
[ 10 50 20 40 ]

Stack & Queues

  • queue : 리스트 한쪽 끝에서만 삽입과 삭제가 일어나는 스택과 달리 리스트의 한쪽 끝에서는 원소들이 삭제되고 반대쪽 끝에서는 삽입만 가능하게 하는 순서화된 리스트 이다. 선입선출 리스트
  • explicit Test(string name) : name(name)
    • ex) float number = number1; <- 묵시적 형변환
    • ex) float number = (int)number1; <- 명시적 형변환
#include <iostream>
#include <string>
#include <stack>
#include <queue>
using namespace std;

class Test
{
	string name;

	public:

    explicit Test(string name) : name(name)
	//묵시적인 타입변환을 하지 않고 명시적으로 타입변환을 하였을 경우에만 사용하겠다라는 뜻.
	//ex) float number = number1; <- 묵시적 형변환
	//ex) float number = (int)number1; <- 명시적 형변환
	{

	}

	~Test()
	{

	}

	void print() const
	{
		cout << name << endl;
	}
};
int main(int argc, char const *argv[])
{
	//LIFO(last in first out)
	stack<Test> testStack;

	testStack.push(Test("Mike"));
	testStack.push(Test("John"));
	testStack.push(Test("Sue"));

	cout << endl;

	/* this is invalid code ! objected destroyed.
	Test &test1 = testStack.top();
	testStock.pop();
	test1.print(); // Reference refers to destroyed objects
	*/

	Test &test1 = testStack.top();
	// reference.
	test1.print();
	// but original gone but test still have value
	// this is last one


    // .pop is the return the original.
    // pop is object destroyed.(top 에 있는 원소를 삭제)
	testStack.pop();
	Test &test2 = testStack.top();
	test2.print();
	// the result is john.





	//FIFO(first in first out) stack 이랑 반대라 생각하면 된다.
	queue<Test> testQueue;

	testQueue.push(Test("Mike"));
	testQueue.push(Test("John"));
	testQueue.push(Test("Sue"));
	//여기서는 슈가 마지막에 나온다. 즉 먼저 입력된것이 탑이 된다.

	cout << endl;

	testQueue.back().print();
	//back : return a reference to the last element in vector
	//제일 마지막것이 나온다.
	while(testQueue.size() > 0)
	{
		Test &test = testQueue.front();
		test.print();
		testQueue.pop();
	}


	return 0;

}

Result

Complex Data

#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;

/**************************************************
*
* Note, some compilers are OK with angle brackets
* used in connection with template types
* being next to each other with no spaces, like
* this: map<string, vector<int>> scores;
* Others require spaces, like this:
* map<string, vector<int> > scores;
* It's safer to put in spaces.
*
**************************************************/

int main() {

	map<string, vector<int> > scores;

	scores["Mike"].push_back(10);
	scores["Mike"].push_back(20);
	scores["Vicky"].push_back(15);

	for(map<string, vector<int> >::iterator it = scores.begin(); it!= scores.end(); it++)
	{
		string name = it->first;
		vector<int> scoreList = it->second;

		cout << name << ": " << flush;

		for(int i = 0; i < scoreList.size(); i++)
		{
			cout << scoreList[i] << " " << flush;

			//flush 버퍼 저장하지 않고 바로바로 디스플레이한다/
		}

		cout << endl;
	}
	return 0;
}

Result

REFERENCE

모두의코드

Comment  Read more

14. Approximation Methods

|

Approximation Methods

  • Major Disadvantage of methods we’ve learned
  • V - Need to estimate ISI values
  • Q - Need to estimate ISI x IAI values
  • ISI and IAI can be very large
  • solution : Approximation
  • Recall: neural networks are universal function approximator
  • First, we do feature extraction: convert state s to feature vector x
  • we want a function, parameterized by theta, that accurately approximates V

1. Linear Approximation

  • Function approximation methods requires us to use models that are differentiable
  • Can’t use something like decision tree or k-nearest neighbour
  • in sequal(查询语言) to this section, we will use deep learning methods, which are differentiable
  • Neural networks don’t require us to engineer features beforehand, but it can help
  • FOr Approximation methods, we will need linear regression and gradient descent

2. Section outline

  • MC prediction
  • TD(0) prediction
  • SARSA

3. Sanity(明智) Checking

  • we can always sanity check our work by comparing to non-approximated versions
  • we expect approximation to be close, but perhaps not exactly equal
  • Obstacle we may encounter: our code is implemented perfectly, but our model is bad
  • Linear models are not very expressive
  • if we extract a poor set of features, model won’t learn value function well
  • will need to put in manual work to do feature engineering

4. Linear Model

  • Supervised learning aka,Function Approximation
  • The function we are trying to approximate is V(s) or Q(s,a)
  • Rewards are real numbers
  • So returns, which are sums of rewards are real number
  • 2 Supervised learning techniques
    • Classification
    • regression
  • we are doing regression

5. Error

  • Supervised Learning methods have cost Functions
  • Regression means squared error is the appropriate choice
  • Squared difference between V and estimate of V
  • Replace V with its definition
  • But we don’t know this expected value
  • as we learned from MC(Monte Carlo), we can replace the expected value with its sample means
  • Alternatively, we can treat each G_(i,s) as a training sample
  • And try to minimize all the individual squared differences simultaneously(just like linear regression)

6. stochastic Gradient Descent

  • we can now do stochastic(随机的) gradient decent
  • Move in direction of gradient of error wrt only one sample at a time

Gradient Descent 설명

  • Neural Network의 loss function의 현 weight의 기울기(gradient)를 구하고 Loss를 줄이는 방향으로 업데이트 나가는 방법
  • Loss function (ERROR) 는 현재 가중치(weight)에서 틀린 정도를 알려주는 함수이다.
  • 즉, 현재 네트워크의 weight에서 내가 가진 데이터를 집어 넣으면 에러가 생길 것이다. 거기에 미분을 하면 에러를 줄이는 방향을 알 수 있다.
  • 그 방향으로 정해진 Learning rate를 통해서 weight를 이동시킨다. 이것을 반복해서 학습하는 것이다.
  • 즉 Gradient Descent는 현재 네트워크의 Weight에 어떤 데이터를 넣을 떄 에러값을 미분해서 에러의 방향(Gradient)을 알애체고 그 방향으로 정해진 Learning rate를 통해서 weight을 이동시킨다(Descent).
  • Gradient Descent의 단점은 가진 데이터를 다 넣으면 전체 에러가 계산이 될 것이다.
  • 그렇기 때문에 최적값을 찾아 나가기 위해서 한칸 전진할 때마다 모든 데이터 셋을 넣어주어야 해야하기 때문에 학습이 굉장히 오래 걸리는 문제가 발생하게 된다.
  • 그럼 Gradient Descent 말고 더 빠른 Optimizer 는 없을까? 그것이 바로 stochastic Gradient Descent 이다.

Stochastic Gradient Descent

  • Stochastic Gradient Descent(SGD)는 조금만 흝어보고(Mini Batch)빠르게 학습 하는 것이다.
  • 최적값을 찾아 과정은 이와 같다
  • GD의 경우 항상 전체 데이터 셋을 가지고 Learning rate로 최적의 값을 찾아가는 모습을 불 수 있다.
  • SGD 같은 경우 Mini-batch 사이즈 만큼 조금씩 돌려서 최적의 값으로 찾아나간다.

7. Gradient Descent

  • we would work for all models, not just linear models

Gradient Descent for Linear Models

8. Relationship to Montel Carlo

  • Recall when we did not parameterized V(s) - as if V(s) itself was a parameter
  • this is the exact same equation we had before for Mote Carlo
  • therefore, what we were doing was an instance of gradient descent

9. Feature Engineering

  • Recall: neural networks can in some sense find good nonlinear transformations / features of the raw data
  • since we only study linear methods in the past section, we need to find features manually
  • Feature Engineering 머신러닝 알고리즘을 작동하기 위해 데이터에 대한 도메인 지식을 활용하여 특징(Feature)을 만들어 내는 것
  • 머신러닝 모델을 위한 데이터 테이블의 column(특징)을 생성하거나 선택하는 작업을 의미
  • 즉 모델의 성능을 높이기 위해 초기 주어진 데이터로부터 특징을 가공하고 생성하는 전체 과정
  • Feature Engineering 모델 성능에 미치는 영향이 크기 때문에 머신러닝 응용에 있어서 굉장히 중요한 단계
  • Feature Engineering 아래와 같은 단계에 구성되어 있다.
    1. Project scoping(Define Problem)
    2. Data Collection
    3. EDA
    4. Data Preprocessing
    5. Feature Engineering
    6. Modeling
    7. Evaluation
    8. Project Delivery / Insights
  • Feature Eingeering은 모델에 입력하기 전 단계에 데이터의 특성을 잘 반영하고 성능을 높일 수 있도록 특징을 생성하고 가공하는 단계이다.
  • Feature Engineering에 구성은 아래와 같다.

방법적인 측면

  1. Feature Selection(특징 선택)
    • 특징 랭킹(Feature Ranking) 또는 특징 중요도 (Feature Importance)라고도 불린다.
    • 불류 모델 중 Decision Tree 같은 경우 트리의 상단에 있을 수록 중요도가 높으므로 이를 반영하여 특징 별로 중요도를 매긴다.
    • 회귀 모델의 경우 Forward Selection 과 Backward Elimination 같은 알고리즘을 통해 특징을 선택한다.
  2. Dimension Reduction(차원 감소)
    • Dimension Reduction은 Feature extraction(특징 추출)이라는 말로도 불린다.
    • 차원 축소는 데이터의 압축이나 잡음을 제거하는 효과도 있지만, 관측 데이터를 잘 설명할 수 있는 잠재 공간(Latent space)을 찾는 것이다.
    • 가장 대표적인 알고리즘은 PCA(Principle Component Analysis)
    • PCA는 각 Feature(변수)를 하나의 축으로 투영시켰을 때 분산이 가장 큰 축을 첫번째 주성분으로 선택하고 그다음 큰 축을 두번째 주성분으로 선택하고 데이터를 선형 변환하여 다차원을 축소하는 방법이다.

      Domain(분야) 전문성 측면

  3. Feature Generation(특징 생성) or Feature Construction(특징 구축)
    • 이 방법을 주로 Feature Engineering 이라고 말한다.
    • 초기에 주어진 데이터로 부터 모델링 성능을 높이는 새로운 특징을 만드는 과정이다.
    • 이때 데이터에 대한 Domain(분야) 전문성을 바탕으로 데이터를 합치거나 쪼개는 등을 거쳐 Feature을 만들게 된다.
    • 간단한 예로 시간 데이터를 AM/PM으로 나누는 것이다.
    • 이 작업은 한번 해서 끝나는 것이 아니라 끊임 없이 모델링 성능을 높이는 목적으로 반복해서 작업할 수 있는 부분이기 때문에 전문성과 경험에 따라 비용과 시간을 줄일 수 있는 부분이다.

Mapping s -> x

  • states can be thought of as categorical variable
    • (0,0) -> category 1
    • (0,1) -> category 2
    • etc
  • how do we treat categorical variable? One-Hot encoding
  • what if we do one-hot encoding?
  • s=(0,0) -> x=[1,0,0,..]
  • s=(0,1) -> x=[0,1,0,..]
  • D is the cardinality(基数) of S
    • 집합의 cardinality는 집합의 원소의 개수를 말한다.
    • 두 집합 A,B가 cardinal number가 같다고 함은 일대일 대응 f: A–> B가 존재하는 것이다.
    • 따라서 두 집합 A,B cardinal number가 같다면 원소의 개수가 같은것이다.
  • Problem with one-hot encoding: this requires the same number of parameters as measuring V(s) directly
  • i.e. V is a dict with ISI keys and ISI values
  • if we do one-hot encoding, each Component $θ_i$ actually represents V(s=i) itself

One-Hot Encoding

  • one positive aspect to using one-hot encoding
  • suppose our code is not working(our V isn’t accurate)
  • we can have perfectly good code/no bugs, but still might not yield good results because feature are bad
  • Change feature transformer to use one-hot encoding
  • if it starts working, that confirm our features are bat(since it’s the same as a non-approximate method)

Alternative to One-Hot

  • in case of GridWorld, each(i,j) represents a position in 2-D space
  • it’s more like 2 real numbers than a category
  • Vector x can be (i,j) itself
  • could scale it so mean = 0 and var = 1
  • this x is the “raw data”
  • problem
    • model is only linear
    • for fixed j, V(i) is just a line

Polynomials

  • Recall from linear regression class: we can make new features by creating polynomials
  • Recall from calculus: infinite taylor expansion can approximate any function
  • Ex. second order terms
    • $x_1$^2
    • $x_2$^2
    • $x_1$$x_2$
  • don’t overfit

10. Approximation MC Prediction

  • Replace V(s) with linear model
  • there are two main steps
    1. Play game, get sequence of stats and returns
    2. Update V(s) as average of return
  • With Approximation
    1. Play game, get sequence of stats and returns
    2. Update V(s) as average of return

Pseudocode

def mc_approx_prediction(π):
  θ = random
  for i = 1..N
    states_and_returns = play_game
    for s, g in states_and_returns:
      x = Φ(s)
      θ = θ + α(g-θ^T*x)x

11. Approximation TD(0)

  • apply approximation to TD(0) -> but one caveat(警告)
  • Main difference between MC and TD(0): instead of Using G, we use r+ɣV(s’)
  • Problem
    • the target is not a real target, because it require a model prediction
    • Gradient is not a true gradient, so we call it a “Semi-Gradient”
  • Remember don’t need to calculate returns, use rewards directly

12. Semi-Gradient SARSA

  • SARSA with approximation
  • we will approximate Q
  • More difficult than Approximating V, Since instead of approximating ISI value, we need to approximate ISI x IAI values
  • Model Prediction appears in target again, so this is another instance of semi gradient
  • Features
    • Need to combine(s,a) -> x
    • Simple Idea: take our old encoding of s(r,c,r*c) and add one-hot encoding of action
    • x = (r,c,r*c,U,D,L,R,1)
    • r,c is the raw and column
    • it well not approximate Q well but try to find it
  • Best Features
    x = [
     r && U,
     c* && U,
     r*r && U,
     c*c && U,
     r*c && U,
     l && U,
     r && D,
    ]
    
    • 6 per action x 4actions + 1bias = 25 features
    • tabular method : 9states x 4actions = 36
    • action value function을 Q-Table로 작성하여 푸는 방법을 Tabular Methods
    • Tabular Methods를 state 나 action이 작을때만 적용 가능 하다고 한다.
    • 왜냐하면 각각의 state에 action마다 Q값을 넣어줘야 하기 때문이다. 그래서 실제 환경이나 실생활, 혹은 연속적인 환경에서는 적용을 할 수 없다.
  • Similar to NLP: word2idx is a dict that maps each word to a unique index in x
  • SA2IDX(Semi-gradient SARSA) is a dict that maps(s,a) to a unique index in x

13. Summary

  • State Space can grow too large to feasibly enumerate
  • Approximation methods allow us to compress number of parameters needed
  • differentiable Models are a good fit, because we can use stochastic gradient decent
  • Online Learning is good because if we have a long episode, agent can learn during the episode
  • Everything we learned is just as applicable to deep learning / neural nets
  • x = (i,j) is not expressive enough, so we used feature engineering
  • we applied approximation to:
    • MC Prediction
    • TD(0) Prediction(semi-Gradient)
    • SARSA(Semi-Gradient)
  • Why didn’t we apply approximation to Q-Learning?
    • Q-learning is an off-policy method
    • Sources have stated approximation for off-policy control methods do not have good convergence characteristics (utton & Barto)
    • we are encouraged to modify SARSA to use Q-learning instead
    • Recall: with Q-learning the a’ we use in update is not necessarily the action we will take next
    • but it has been done at “Deep Q Learning”
    • we’re encouraged to modify SARSA to use Q-Learning instead

    Reference:

    Artificial Intelligence Reinforcement Learning

    Advance AI : Deep-Reinforcement Learning

    Cutting-Edge Deep-Reinforcement Learning

Comment  Read more

gRPC란 무엇인가

|

gRPC

  • Robot을 연구하다 보면 리눅스 체제의 컴퓨터와 하드웨어 연결하는데 있어 gRPC라는 이용하는 곳을 본적이 있을 것입니다.
  • gRPC는 어떤 환경에서도 동작하는 모던한 오픈소스 원격 프로시저 요청 (Remote Procedure Call, RPC) 프레임워크입니다.
  • gRPC는 구글이 최초로 개발한 오픈 소스 원격 프로시저 호출 (RPC) 시스템이다.
  • HTTP 기반 원격 함수 호출을 해주는 즉, RPC(Remote Procedure Call) 프레임워크라고 할 수 있습니다.
  • gRPC는 구글에서 10년 이상동안 수 많은 MSA와 데이터센터 사이를 연결하기 위해 사용하던 Stubby라고 부르던 범용 RPC 인프라를 크로스플랫폼, 오픈소스화해서 만들어졌습니다.
    • Stubby를 공개하기엔 구글 사내 서비스와 너무 타이트하게 연결이 있어서 spdy, http/2, QUIC 등을 지원하는 기능을 추가하고 Stubby기능을 좀 더 표준화하도록 수정해서 오픈되었습니다.
  • RPC는 네트워크 상 원격에 있는 서버의 서비스를 호출하는데 사용되는 프로토콜로 IDL(Interface Definition Language)로 인터페이스를 정의한 후 이에 해당하는 Skeleton 과 Stub 코드를 통해 프로그래밍 언어에서 호출해서 사용하는 방식이라고 보면 됩니다.
  • gRPC stub
    • client side에서 요청을 grpc 형태로 만들어주는 역할을 하는 컴포넌트의 이름입니다.
  • 최근에는 HTTP를 활용한 SOAP, RESTful 등이 많이 활용되어서 RPC는 거의 사용이 되지 않으나 요청/응답을 위한 규약이 명시적이지 않다는 단점으로 인해 다시 RPC의 방식을 채용한 프렘임워크들이 나오기 시작했습니다
  • gRPC는 자바,C/C++ 뿐만 아니라 Node.js, Python, Ruby, PHP, Go, Android 기반, Objective-C 등 다양한 언어들을 지원함으로 서버간 뿐만이 아니라 클라이언트 어플리케이션이나 모바일 앱에서도 사용가능한 RPC 프레임워크입니다.

0. gRPC가 반드시 제공해야할 기능

  • Services not Objects, Messages not References
    • 요청을 큰 덩어리로 만들고 object를 여러 service에 분산되도록 만들지 않는 것(Don’t distribute your objects, Martin Fowler), 그리고 너무 높은 네트워크비용을 방지하는것(Fallacies of distributed computing, wikipedia).
  • Streaming
  • Blocking & Non-Blocking
  • gRPC Principles 참조

1. 사전 준비 사항

  • golang 기반으로 gRPC를 테스트하려면 당연히 golang이 설치되어야 합니다. 그리고 gRPC는 함수 호출간 직렬화된 데이터를 주고 받는데 구조화된 객체를 직렬화하기 위해서 Protocol Buffers 를 사용하고 있으므로 함께 설치하여 줍니다.

1.1 Golang 설치

  • 다음의 사이트를 참조하여 golang 바이너리를 설치합니다. (이 문서에서는 Linux/MacOS 기반으로 설명합니다.)
  • 다운로드 받은 압축파일을 다음의 명령어를 통해 설치합니다.
    tar -C /usr/local -xzf <다운로드 받은 압축파일>
    
  • 압축을 푼 후 적절한 위치에 go 소스가 위치할 디렉토리를 생성한 후 $HOME/.profile에 다음의 환경변수를 설정합니다. ``` $HOME 아래에 work라는 디렉토리 생성

mkdir $HOME/work export GOROOT=/usr/local/go export GOPATH=$HOME/work export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

- 여기까지 설치를 완료하였으면 다음의 코드를 통해 정상동작 테스트합니다. 먼저 다음의 디렉토리를 생성합니다.

mkdir -p $GOPATH/src/hello

- 그리곤 hello.go 파일명으로 다음의 코드를 생성합니다.

package main

import “fmt”

func main() { fmt.Printf(“hello, world\n”) }

- 소스코드를 생성하였으면 빌드합니다.

cd $GOPATH/src/hello go build

- 컴파일이 정상적으로 완료된 후 다음의 명령을 통해서 실행하여 결과를 확인합니다.

./hello hello, world

### 1.2 gRPC 설치
- 다음의 명령을 통해서 gRPC를 설치합니다.

go get google.golang.org/grpc

### 1.3  Protocol Buffers 설치
- 다음의 경로에서 Protocol Buffers 압축파일을 받습니다. https://github.com/google/protobuf/releases – 다운받아야 할 압축파일명은 protoc-<버전>–<플랫폼>.zip 파일입니다.
- 다운받은 압축파일은 적당한 위치에 풀어서 해당하는 위치를 PATH에 추가합니다. 다음은 저의 설정 예입니다
<a href="https://postimg.cc/ZCFvHcF7"><img src="https://i.postimg.cc/YqTNpD4H/213223.png" width="700px" title="source: imgur.com" /></a>
- 다음으로 Golang 기반의 protoc 플러그인을 설치합니다.

go get -u github.com/golang/protobuf/{proto,protoc-gen-go}


## 2. 샘플을 통해 이해하기
- 1.2 항목에서 gRPC 를 설치하였으면 그 하위 디렉토리에 examples 들이 존재합니다. 그 중 helloworld를 통해서 알아보겠습니다.
그 위치는 아래와 같습니다.

cd $GOPATH/src/google.golang.org/grpc/helloworld

- 위의 디렉토리 하위에는 greeter_client, greeter_server, helloworld 의 세 디렉토리가 보입니다.
- 그 중 helloworld 하위엔 .proto 파일이 존재하며 이 파일이 gRPC 서비스가 명시되는 곳입니다.
- 여기에 존재하는 파일을 기준으로 protoc 명령을 통해 .pb.go 파일이 생성되며 이 파일은 클라이언트와 서버 코드와 함수 호출시 주고받을 메세지 타입이 생성됩니다.
- 서버 코드를 빌드하고 실행합니다. 위치는 “$GOPATH/src/google.golang.org/grpc/helloworld” 에서 실행합니다

go run greeter_server/main.go

- 그리고 터미널을 하나 더 열어서 다음의 명령으로 클라이언트를 실행합니다.

go run greeter_client/main.go

- 실행결과 “Greeting: Hello world” 메시지가 나오면 정상 실행된 것입니다.

## 3. gRPC 서비스 업데이트
- 앞서 실행한 명령은 SayHello라는 함수를 클라이언트가 호출하면 서버에서 메세지를 받아서 클라이언트가 출력하는 내용이었습니다.
- 여기에 SayHelloAgain이라는 함수를 추가하도록 하겠습니다.
- 다음과 같이 .proto 파일을 업데이트합니다

helloworld.proto 파일의 위치

$GOPATH/src/google.golang.org/grpc/examples/helloworld/helloworld/helloworld.proto



// The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} // Sends another greeting rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} }

// The request message containing the user’s name. message HelloRequest { string name = 1; }

// The response message containing the greetings message HelloReply { string message = 1; }



- 다음으로 gRPC 코드를 생성합니다.


protoc -I helloworld/ helloworld/helloworld.proto –go_out=plugins=grpc:helloworld



- 서버 및 클라이언트 코드를 수정한 후 실행하여 수정된 내용이 반영되었는지 확인합니다.

- 서버코드 업데이트 – greeter_server/main.go


func (s server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (pb.HelloReply, error) { return &pb.HelloReply{Message: “Hello again “ + in.Name}, nil }



- 클라이언트 업데이트 – greeter_client/main.go


r, err = c.SayHelloAgain(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf(“could not greet: %v”, err) } log.Printf(“Greeting: %s”, r.Message)



- 코드 수정되었으면 실행하여 동작을 확인합니다.
- 서버 실행


go run greeter_server/main.go



- 클라이언트 실행


go run greeter_client/main.go ```

  • 다음과 같이 실행결과를 확인합니다.

4. gRPC의 장점

  • Low Latency, Highly scalable, distributed systems
    • 클라우드 서버와 커뮤니케이션하는 모바일 클라이언트를 지원하는데에 초점이 맞춰져있습니다.
  • http/2를 이용한 reverse proxy 가능
    • 서버간에 http 1.1 keep-alive로 통신하고 있을 경우, 특정 요청이 holding되면 다음 요청도 전부 holding되는 문제가 생길 수 있습니다
    • http/2 reverse proxy를 통해 multiplex하게 서버와 요청을 주고 받을 수 있게 됩니다.
  • vendasta에서 gRPC 사용을 통해 얻은 세 가지 이점
    • gRPC를 이용해 5개 이상의 언어로 이루어진 SDK-서버 간의 통신을 통합할 수 있었습니다.
      • SDK 개발시에 더 이상 개발자가 api문서를 작성하지 않아도되고, api 형태가 어떤식으로 되어있는지 물어볼 필요가 없어졌습니다
      • vendasta에서는 하나의 서버에 통신하기 위해 여러 언어로 SDK를 만들어서 해당 이점이 극대화될 수 있었습니다.
    • gRPC 사용을 통해, 어떤 요청이 끝날 때 까지 기다릴 필요가 없이, 첫 요청이 들어오면 순서와 관계없이 서버에서 응답을 내보내주면 되기 때문에 첫 화면 구성이 더 빨라졌습니다.
    • JSON을 프로토콜 버퍼로 변환하고난 뒤에, 서버/클라이언트에서 Serialization / Deserialization하는 것에 대한 어려움을 해소할 수 있게 되었습니다.
      • gRPC에서는 하나의 요청 / 응답 형태에서 타입이 정해진 message를 사용합니다.
  • Protocol Buffer
    • XML, json등으로 들어온 요청 / 응답을 Protocol Buffer를 이용해 직렬화하여 더 작은 크기의 요청 / 응답으로 만들 수 있습니다.
    • 기본적으로는 base128을 이용한 byte array 직렬화를 사용하지만, 사용방식에 따라 json, text 직렬화로 사용 가능합니다.

5. gRPC Life Cycle

  • RPC 요청 1
    • 처음 gRPC요청을 하기 위해 metadata를 서버에 전송하고, 서버에서는 deadline을 설정해서 client에 돌려줍니다.
      • deadline은 RPC 요청의 성공 여부와 관계 없이 해당 RPC 요청을 언제 timeout시켜서 종료할지에 대한 정보를 갖고 있습니다
    • 서버는 바로 서버의 metadata를 response하거나, client의 다음 요청을 기다립니다
      • 서버의 metadata는 반드시 response보다 먼저 보내야 합니다.
    • 서버가 클라이언트로부터 요청을 받았다면, 어떤 것이든지 응답을 보내줘야 합니다
    • status가 ok라면 client가 응답을 받아서 요청을 완료합니다.
  • Server streaming RPC
    • 서버에서는 클라이언트에 response를 보내고 뒤따르는 메타데이터가 있다면 보낸 뒤에 complete를 의미하는 패킷을 보내는 것으로 연결을 종료합니다.
  • Client streaming RPC
    • 클라이언트에서는 request를 하나로 보내는 대신 여러 개를 스트리밍으로 보낼 수 있습니다.
    • 서버는 일반적으로 하나의 response를 보내지만, 클라이언트가 모든 request를 보낼 때까지 기다릴 필요는 없습니다.
  • Bidirectional streaming RPC
    • 양방향 스트리밍 RPC에서는 클라이언트의 요청으로 stream이 연결된 뒤에, 서버에서는 클라이언트의 추가 요청을 기다립니다.
    • 어플리케이션에 따라 다르겠지만, 클라이언트와 서버는 순서와 관계없이 읽기/쓰기를 반복할 것입니다
      • 스트림은 완전하게 독립적으로 동작합니다.
    • 서버는 클라이언트의 모든 요청을 기다리거나, 핑퐁식으로 메시지를 주고받거나 할 수 있습니다.
  • 데드라인과 타임아웃
    • gRPC는 클라이언트가 DEADLINE_EXCEEDED 에러가 발생해서 RPC가 종료되기 전에 얼마나 RPC를 기다려야 하는지에 대해 정할 수 있습니다.
    • 서버에서는 쿼리를 날려서 특정 RPC가 time out이 되었는지, RPC 커넥션 시간이 얼마나 남았는지를 확인할 수 있습니다.
    • 언어별로 데드라인이나 타임아웃의 형태는 다르게 설정됩니다
      • 어떤 언어에서는 디폴트 데드라인이 없기도 하고, 어떤 언어는 특정 시각이 지나면 데드라인으로 판단하기도하고, 몇몇 언어는 특정 시간이 지나면 타임아웃으로 판단하기도 합니다.
  • RPC Termination
    • gRPC에서는, RPC의 종료를 클라이언트 / 서버에서 각각 판단합니다.
      • 서버에서는 response가 finish 됐을 때, 클라이언트에서는 deadline이 지났을 때 등.
  • Canceling RPCs
    • 서버, 클라이언트 모두 어떤 시점에서든지 RPC 연결을 취소할 수 있습니다.
      • RPC를 취소한다는 것이 요청을 “롤백 (undo)” 한다는 의미는 아닙니다.
  • Metadata
    • metadata는 key-value list로 정의된 RPC 요청에 대한 정보입니다.
      • header와 비슷한 형태인듯합니다.
  • Channels
    • 채널은 client 에서 stub을 만들 때 생성되는 호스트와 포트로 특정되는 gRPC 서버 연결에 대한 정보를 가집니다.
    • 채널의 설정을 변경하거나, state (connected, idle)를 확인할 수 있습니다.

      6. gRPC 적용전 환경세팅

  • centOS 6에서 C++ gRPC가 빌드되지 않는 문제가 있었습니다 (2017년 1월 18일)
    • https://github.com/grpc/grpc/issues/9365
    • gRPC 자바를 사용하면 되긴 합니다(https://grpc.io/docs/quickstart/java.html)
      • JDK 7 이상
  • 아직 웹에서는 안정적으로 사용할 수 없습니다.
    • 다만 웹용 프로젝트가 2018년 10월 23일에 릴리즈되긴 했습니다(https://github.com/grpc/grpc-web, https://grpc.io/blog/grpc-web-ga)
    • gRPC-Web은 브라우저-서버간의 gRPC통신을 가능하게 만들어줍니다.
  • NGINX의 버전이 최소 1.13.10(18년 3월 20일 릴리즈, 18년 4월 17일 1.14.0에 포함되었습니다)이 되어야 합니다.
    • Server Push가 적용되어 있습니다
    • gRPC proxy pass가 적용되어있습니다.
  • NGINX에 http/2 reverse proxy가 도입되지 않을 예정이기 때문에, http/2 또는 h2c로 nginx 서버간에 통신을 하기위해서는 gRPC를 사용하거나 server push를 사용해야 합니다.

    7. 서비스에 gRPC 적용 방식 예정

  • Mobile, PC
    • Client(web)-REST => Proxy Server (Nginx -> gRPC Gateway) => Server (Nginx -> gRPC stub -> spring)
  • client - server(load balancer) - server(backend) 사이의 stream은 하나를 공유해서 사용하게 되나요?
    • client - server(backend) 사이의 stream이 독립적이기 때문에, server (load balancer) - server(backend) 사이의 stream도 여러 개가 생성되게 됩니다.
  • thrift와 비교해서 장점은 어떤 것이 있나요?
    • 성능적인 장점은 없습니다. 다만, gRPC의 경우 proto 파일(message)을 통한 클라이언트 별 구현이 용이하기 때문에 thrift에 비해 커뮤니케이션 비용을 줄여줄 수 있다는 장점이 있습니다
  • 당장 사용할 수 있나요?
    • api g/w 에서 보안 부분을 처리해줘야합니다 (gRPC 요청에 대한 hmac 인증 적용 등)
    • gRPC에서 채널단위 보안 / 요청단위 보안에 관련된 API를 제공하지만, token방식의 보안은 구글 OAuth2를 사용할 때만 지원하는듯 합니다. abstact 클래스를 직접 구현해서 기능을 확장하도록 권장하고 있습니다.

Reference

IBM DEVELOPER

Widian’s Hobby Notes

Comment  Read more

13. TD Temporal Difference Learning

|

Temporal Difference (TD) Learning

  • this section is a 3rd technique for solving MDPs
  • TD = Temporal Difference(TD) Learning
  • Combines ideas from DP and MC
  • Disadvantage of DP: requires full model of environment, never learns from experience
  • MC and TD learn from experience
  • MC can only update after completing episode, but DP uses Bootstrapping(Making an initial estimate)
  • We will see that TD also uses Bootstrapping and is fully online, can update value during an episode

    1. TD Learning

  • Same approach as before
  • First Predict Problem
  • them control problem
  • 2 control methods:
    • SARSA
    • Q-Learning
  • Model-Free Reinforcement Learning
  • TD methods learn directly from episode of experience.
  • no Knowledge of MDP Transition / rewards
  • TD learns from incomplete episodes by Bootstrapping
  • TD updates a guess towards a guess
  • MC와 다른점은, MC는 실제 에피소드가 끝나고 받게 되는 보상을 사용하여 Value Function을 업데이트 하였다
  • TD에서는 실제 보상과 다음 step에 대한 미래추정가치를 사용해서 학습한다.
  • 이때 사용하는 보상과 Value Function의 합을 TD Target -그리고 TD Target 과 실제 V(S)와의 차이를 TD error라고 표현한다.
  • MC에서의 Value function이 업데이트 되는 과정이 왼쪽(에피소드가 전체적으로 끝나서 그의 보상을 나누어 단계별로 업데이트)
  • TD는 각 단계별로 업데이트가 되는 과정으로 오른쪽 그림
  • TD의 장점은 에피소드 중간에서도 학습을 하게 된다는 것이다.
  • MC에서는 에피소드가 끝날때까지 기다렸다가 업데이트가 발생하고 학습하기 떄문이다.
  • TD는 종료 없는 연속적인 에피소드에서도 학습할 수 있다.
  • Return $G_t$ = R(t+1)+ɣR(t+2)+…+ɣ^(t-1)$R_T) is unbiased estimate of $v_π$($S_t$)
  • True TD Target R(t+1)+ɣV(S(t+1)) is biased estimate of $v_π$($S_t$)
  • TD Target is much lower variance than the return:
    • return depends on many random actions, transitions, rewards
    • TD Target depends on one random action, transition, reward
  • V policy가 실제 G에 대해서 unbias라 할때는 TD Target도 V policy를 추종하기 unbias이다. 하지만 TD Target에 V policy를 추정하는 V(St+1)를 사용하기에 실제값이 아니라 실제값을 추정하는 값임으로 bias가 발생한다. 그리고 TD Target은 단지 하나의 step에서만 계산하기에 noise가 작게 되므로 상대적으로 variance가 낮게 나타난다.
  • MC has high variance, zero bias
    • good convergence properties
    • even with function approximation
    • not very sensitive to initial value
    • very simple to understand and use
  • TD has low variance, some bias
    • Usually more efficient than MC
    • TD(0) converges to $v_π$(s)
    • but not always with function approximation
    • More sensitive to initial value
  • Compare on variance between MC and TD
  • Bootstrapping이 더 학습하는데 효율적이다.
  • MC and TD converge : V(s) -> $v_π$(s) as experience -> ∞ (에피소드는 무한 반복하게 되면 결국 수렴하게 되어있다.)
  • but what about batch solution for finite experience
  • e.g repeatedly sample episode k ∈ [1,K]
  • Apply MC or TD(0) to episode k
  • For example, first episode A got reward “0” and B got reward “0”
  • from Second Episode B got reward “1” to seven episode. and B got 0 at the last episode.
  • then A will go B within 100 % and then reward will be “0”
  • in the MC methods, A will get reward “0” because the episode pass Through A is one that final reward is zero 6- in the TD methods, running another episode because of B value update to “6” then A value also going to be updated
  • MC converges to solution with minimum mean-square
    • best fit to the observe returns :
    • in the AB example, V(A)=0
  • TD(0) converges to solution of max likelihood Markov Model
    • Solution to the MDP (S,A,P^,R^,ɣ) that best fits the data
    • in the AB example, V(A) = 0.75
  • TD(0)방식은 max likelihood Markv 방식을 사용하여 수렴하는 알고리즘이다. MDP 기반으로 실제적인 값을 찾아가게 되기 때문에 V(A)의 값이 6/8 평균가치가 계산되어 0.75값으로 업데이트가 된다.
  • TD exploits Markov property
    • Usually more efficient in Markov environment
  • MC does not exploit Markov property
    • Usually more effective in Non-Markov environment
  • MC 알고르짐
  • Bootstrapping을 사용하여 states에 대한 value들을 추정하여 사용하는 방법 TD
  • DP 방식
  • DP 방식에서는 모델을 통해서 이미 MDP를 알고 있고 이에 대한 value 와 reward를 통해 학습을 하기 때문에 위에와 같이 나옵니다.
  • Bootstrapping: update involves an estimate
    • MC does not bootstrap
    • DP bootstraps
    • TD bootstrap
  • Sampling update samples an expectation
    • MC samples
    • DP does not sample
    • TD samples
  • DP와 TP에서 사용하는 Bootstrapping은 추정 값을 기반으로 하여 업데이트
  • MC에서 사용하는 샘플링은 expectation을 샘플하여 업데이트 한다.
  • TD도 샘플링을 한지만 DP처럼 full backup을 하지 않는다.

2. TD(0) Prediction

  • Apply TD to prediction problem
  • algorithm is called TD(0)
  • there is also TD(1) and TD(λ)
  • it is related to Q-Learning and approximation methods

MC

  • Recall: one Disadvantage of MC is we need to wait until the episode is finished then we calculate return
  • also recall: Multiple ways of calculating averages
  • General “average-finding” equation
  • Does not require us to store all returns
  • Constant alpha is moving average/exponential decay

Value function

  • now recall: the definition of V
  • We can define it recursively

TD(0)

  • can we just combine these(MC & Value Function)
  • instead of sampling the return, use the recursive definition
  • this is TD(0)
  • why this is fully online? we can update V(s) as soon as we know s’

sources of randomness

  • In Mc, randomness arises when an episode can play out in different ways(due to stochastic policy, or stochastic state transitions)
  • in TD(0), we have another source of randomness
    • G is an exact sample in MC
    • r + ɣV(s’) is itself an estimate of G
  • we are estimating from other estimates(bootstrapping)

Summary

  • TD(0) is advantageous in comparison to MC/DP
  • Unlike DP, we don’t require a model of the environment, and only update V for states we visit
  • unlike MC, we don’t need to wait for an episode to finish
  • advantageous for very long episodes
  • also applicable to continuous(non-episodic)tasks

3. TD Learning for Control

  • Apply TD(0) to Control
  • we can probably guess what we’re going to do by now
  • use Generalized policy iteration, alternate between TD(0) for prediction, policy improvement using greedy action selection
  • Use Value iteration method: Update Q in-place, improve policy after every change
  • skip the part where we do full policy evaluation

4. SARSA

  • Recall from MC: we want to use Q because it’s indexed by a, V is only indexed by s
  • Q has the same recursive form
  • Same limitation as MC: need lots of samples in order to converge
  • require the 5-tuuple:(s,a,r,s’,a’)
  • Hence the name
  • TD방식과 다른점은 Value function을 쓰지 않고 Q Fucntion을 쓴다.
  • Like MC, still requires us to know Q(s,a) for all a, in order to choose argmax
  • problem: if we follow a deterministic policy, we would only fill in 1/IAI values on each episode
  • Leave most of Q untouched
  • Remedy(处理方法): Exploring starts or policy that includes exploration
  • use epsilon-greedy

Pseudocode

Q(s,a) = arbitrary, Q(terminal,a) = 0
for t=1..N
  s = start_state, a = epsilon_greedy_from(Q(s))
  while not game over:
    s', r = do_action(a)
    a' = episode_greedy_from(Q(s'))
    Q(s,a) = Q(s,a) + alpha + [r + gamma*Q(s',a')-Q(s,a)]
    s = s', a = q'
  • Interesting fact : convergence proof has never been published
  • has been stated informally that it will converge of policy converges to greedy
  • we can achieve this by seeing ε = 1/t
  • Or ε = c/t or ε= c/$t^a$
  • Hyperparameters

Learning Rate

  • Recall that learning rate can also decay
  • problem:
    • if we set α = 1/t
    • at every iteration, only one (s,a) pair will be updated for Q(s,a)
    • Learning rate will decay even for values we have never updated
    • Could we just only decrease α after every episode?
    • No
    • Many elements of Q(s,a) are not updated during an episode
  • we take inspiration from deep learning: AdaGrad and RMSprop(adaptive learning rates)
  • Effective Learning rate Decays more when previous gradient has been larger
  • in other words: the more it has changed in the past, the less it will change in the future
  • our version is simpler: keep a count of every(s,a) pair seen:
    • α(s,a) = $α_0$ / count(s,a)
  • Equivalently
    • α(s,a) = $α_0$ / (k+m*count(s,a))

5. Q-Learning

  • Main Theme: Generalize policy iteration
    • Policy evaluation
    • Policy Improvement(greedy wrt(with regard to) current value)
  • what we’ve been studying: on-policy methods
  • we always follow the current best policy
  • Q-Learning is an off-policy methds
  • do any random action, and still find Q*
  • Looks similar SARSA
  • instead of choosing a’ based on argmax of Q, we update Q(s,a) directly with max over Q(s’,a’)
  • isn’t that the same, since a’=argmax[a’]{Q(s’,a’)}?
  • we don’t need to actually do action a’ as the next move
  • therefore, we use Q(s’,a’) in the update for Q(s,a), even if we don’t do a’ next
  • Doesn’t matter what policy we follow
  • Reality: Random actions -> suboptimal(then use greed) -> takes longer for episode to finish
  • takeaway: doesn’t matter what policy we use
  • Under What circumstance is Q-learning == SARSA?
  • if policy used for Q-learning is greedy
  • then we’ll be doing Sarsa, but we also be doing Q-Learning

6.Summary

  • TD combines aspects of MC and DP
  • MC: Learn From experience / play the game
  • Generalized idea of taking sample mean of returns
    • Multi-armed bandit
  • MC is not fully online
  • DP: bootstrapping, recursive from of value function
  • TD(0) = MC + DP (combines)
  • Instead of taking sample mean of returns, we take sample mean of estimated returns, based on r and V(s’)

TD Summary

  • Control
  • On-policy: SARSA
  • Off-policy : Q-Learning

TD Disadvantage

  • Need Q(s,a)
  • state space can easily become infeasible to enumerate
  • need to enumerate every action for every state
  • Q may not even fit into memory
  • Measuring Q(s,a) for all s and a is called the tabular(表格式的) method
  • Next, we will learn about function approximated methods which allow us to compress the amount of space needed to represent Q

Reference:

Artificial Intelligence Reinforcement Learning

Advance AI : Deep-Reinforcement Learning

Cutting-Edge Deep-Reinforcement Learning

Comment  Read more

12. Monte Carlo Methods

|

Montel Carlo(MC) Methods Introduction

  • Last Section: Dynamic Programming
  • would that work for self-driving cars or video games?
  • can i just set the state of the agent?
  • “god-mode” capabilities?
  • MC Methods learn purely from experience
  • Montel Carlo usually refers to any method with a significant random component
  • Random Component in RL is the return
  • With MC, instead of calculating the true expected value of G, we calculate its sample mean
  • Need to assume episode tasks only
  • Episode must terminate before we calculate return
  • Not “fully” online since we need to wait for entire episode to finish before updating
  • (full online mean is update after every action)
  • monte carlo methods is not fully online which mean it is updated after episode to finish
  • Should Remind you of multi-armed bandit
  • Multi-Armed bandit : average reward after every action
  • MDPs: average the return
  • One way to think of MC-MDP is every state is a separate multi-armed bandit problem
  • Follow the same pattern
  • Prediction Problem(Finding Value given policy)
  • Control Problem(finding optimal policy)

1. Monte Carlo for prediction Problem

  • Recall what V(s) is :
  • Any expected value can be approximated like
  • “i” is episode, “t” is steps

How do we generate G?

  • just play a bunch of episode, log the states and reward sequences
    s1 s2 s3 ... sT
    r1 r2 r3 ... rT
    
  • Calculate G from Definition: G(t) = r(t+1)+gamma*G(t+1)

  • very helpful to calculate G by iterating through states in reverse order
  • Once we have(s,G) pairs, average them for each s

Multiple Visits to s

  • what if we see the same state more than once in an episode
  • E.g. we see s at t=1 and t=3
  • which return should we use? G(1) or G(3
  • First-visit method :
    • Use t = 1 only
  • Every-visit method :
    • Use both t=1 and t=3 as samples
  • Surprisingly, it has been proven that both lead to same answer

First-Visit MC Pseudocode

def first_visit_monte_carlo_prediction(π, N):
  V = random initialization
  all_return = {} # default = []
  do N times:
    states, returns = play_episode
    for s, g in zip(states, returns):
      if not seen s in this episode yet:
        all_return[s].append(g)
        V(s) = sample_mean(all_returns[s])
  return V

Sample Mean

  • Notice how we store all returns in a list
  • Didn’t we discuss how that’s inefficient?
  • Can also use previous mean to calculate current mean
  • Can also use moving average for non-stationary problems
  • Everything we learned before still applies
  • Rules of probability still apply
  • Central limit Theorem
  • Variance of estimate = Variance of RV(Random Value) / N

Calculating Returns from Rewards

s = grid.current_state()
states_and_rewards = [(s,0)]
while not game_over:
  a = policy(s)
  r = grid.move(a)
  s = grid.current_state()
  states_and_rewards.append((s,r))

G = 0
states_and_returns = []
for s,r in reverse(states_and_rewards):
  states_and_returns.((s,G))
  G = r + gamma*G
states_and_returns.reverse

MC

  • Recall: one Disadvantage of DP is that we need to loop through all states
  • MC: only update V for visited states
  • We don’t even need to know what all the states are, we can just discover them as we play

2. MC for Windy Gridworld

  • Windy Gridworld, different policy
  • Policy/transitions were deterministic, MC not really needed
  • in windy gridworld, p(s’r I s,a) not deterministic
  • with this policy, we try to get to goal
  • Values can be -ve, if overall wind pushes us to losing state more often

code

# https://deeplearningcourses.com/c/artificial-intelligence-reinforcement-learning-in-python
# https://www.udemy.com/artificial-intelligence-reinforcement-learning-in-python
from __future__ import print_function, division
from builtins import range
# Note: you may need to update your version of future
# sudo pip install -U future


import numpy as np
from grid_world import standard_grid, negative_grid
from iterative_policy_evaluation import print_values, print_policy

SMALL_ENOUGH = 1e-3
GAMMA = 0.9
ALL_POSSIBLE_ACTIONS = ('U', 'D', 'L', 'R')

# NOTE: this is only policy evaluation, not optimization

def random_action(a):
  # choose given a with probability 0.5
  # choose some other a' != a with probability 0.5/3
  p = np.random.random()
  if p < 0.5:
    return a
  else:
    tmp = list(ALL_POSSIBLE_ACTIONS)
    tmp.remove(a)
    return np.random.choice(tmp)

def play_game(grid, policy):
  # returns a list of states and corresponding returns

  # reset game to start at a random position
  # we need to do this, because given our current deterministic policy
  # we would never end up at certain states, but we still want to measure their value
  start_states = list(grid.actions.keys())
  start_idx = np.random.choice(len(start_states))
  grid.set_state(start_states[start_idx])
# random start

  s = grid.current_state()
  states_and_rewards = [(s, 0)] # list of tuples of (state, reward)
  while not grid.game_over():
    a = policy[s]
    a = random_action(a)
    r = grid.move(a)
    s = grid.current_state()
    states_and_rewards.append((s, r))
  # calculate the returns by working backwards from the terminal state
  G = 0
  states_and_returns = []
  first = True
  for s, r in reversed(states_and_rewards):
    # the value of the terminal state is 0 by definition
    # we should ignore the first state we encounter
    # and ignore the last G, which is meaningless since it doesn't correspond to any move
    if first:
      first = False
    else:
      states_and_returns.append((s, G))
    G = r + GAMMA*G
  states_and_returns.reverse() # we want it to be in order of state visited
  return states_and_returns


if __name__ == '__main__':
  # use the standard grid again (0 for every step) so that we can compare
  # to iterative policy evaluation
  grid = standard_grid()

  # print rewards
  print("rewards:")
  print_values(grid.rewards, grid)

  # state -> action
  # found by policy_iteration_random on standard_grid
  # MC method won't get exactly this, but should be close
  # values:
  # ---------------------------
  #  0.43|  0.56|  0.72|  0.00|
  # ---------------------------
  #  0.33|  0.00|  0.21|  0.00|
  # ---------------------------
  #  0.25|  0.18|  0.11| -0.17|
  # policy:
  # ---------------------------
  #   R  |   R  |   R  |      |
  # ---------------------------
  #   U  |      |   U  |      |
  # ---------------------------
  #   U  |   L  |   U  |   L  |
  policy = {
    (2, 0): 'U',
    (1, 0): 'U',
    (0, 0): 'R',
    (0, 1): 'R',
    (0, 2): 'R',
    (1, 2): 'U',
    (2, 1): 'L',
    (2, 2): 'U',
    (2, 3): 'L',
  }

  # initialize V(s) and returns
  V = {}
  returns = {} # dictionary of state -> list of returns we've received
  states = grid.all_states()
  for s in states:
    if s in grid.actions:
      returns[s] = []
    # 빈값을 넣어는다 initializize
    else:
      # terminal state or state we can't otherwise get to
      V[s] = 0

  # repeat until convergence
# 5000 iterative
  for t in range(5000):

    # generate an episode using pi
    states_and_returns = play_game(grid, policy)
    seen_states = set()
    for s, G in states_and_returns:
      # check if we have already seen s
      # called "first-visit" MC policy evaluation
      if s not in seen_states:
        returns[s].append(G)
        V[s] = np.mean(returns[s])
        seen_states.add(s)

  print("values:")
  print_values(V, grid)
  print("policy:")
  print_policy(policy, grid)

2. MC for Control Problem

  • Let’s now move on to control problem
  • Can we use MC?
  • Problem: we only have V(s) for a given policy, we don’t know what actions will lead to better V(s) because we can’t do look-ahead search
  • only play episode and get states/returns
  • key is to use Q(s,a)
  • we can choose argmax[a]{Q,a}

MC for Q(s,a)

  • simple modification
  • instead of list of tuples(s,G)
  • return list of triples(s,a,G)

Problem with Q(s,a)

  • with V(s) we only need ISI different estimates
  • with Q(s,a) we need IsI x IAI different estimates
  • Many more iterations of MC are needed
  • should remind us of explore-exploit dilemma
  • if we follow a fixed policy, we only do 1 action per state
  • we can only fill in ISI / (ISI x IAI) = 1 / IAI values in Q
  • Can fix it by using the “exploring-starts” methods
  • we choose a random initial state and a random initial action
  • thereafter follow policy
  • this is consistent with our definition of Q :

Back to Control Problem

  • if we think actually, we’ll realize we already know the answer
  • Generalized policy iteration:
    • Alternate between policy evaluation and policy improvement
  • we know how to do evaluation
  • policy improvement same as always : π(s) = $argmax_s$Q(s,a)

Problem with MC

  • Problem: same as before - we have an iterative algorithm inside an iterative algorithm
  • For Q we need lots of samples

3. Solution

  • Similar value iteration
  • Do not start a fresh MC evaluation on each round
    • would take too long to collect samples
  • instead, just keep updating the same Q
  • Do policy improvement after every episode
  • therefore, generate only one episode per iteration

Pseudocode ``` Q = random, pi =random

While True : s, a = randomly select from S and A states_actions_returns = play_game(start=(s,a)) for s,a,G in state_actions_returns: returns(s,a).append(G) Q(s,a) = average(returns(s,a)) for s in states: pi(s) = argmax[a]{Q(s,a)} ```

Another Problem with MC

  • What if policy includes an action that bumps into a wall?
  • we end up in same state as before
  • if we follow this policy, episode will never finish
  • Hack:
  • if we end up in same state after doing action, give this a reward of -100, and end the episode

MC-ES

  • Interesting fact: this converges even though the samples for Q are for different policies
  • if Q is suboptimal, then policy will change, causing Q to change
  • we can only achieve stability when both value and policy converge to optimal value and optimal policy
  • Another interesting fact: this has never been formally proven

4. MC Control without ES

  • Disadvantage of previous control method : needs exploring starts
  • Could be infeasible(不可能的) for games we are not playing in “god-mode”
  • E.g Self-driving car
  • remove need for ES(exploring starts)
  • Recall: all the techniques we learned for the multi-armed bandit are applicable here
  • let’s not be greedy, but epsilon-greedy instead
  • code modification:
    • Remove exploring starts
    • change policy to sometimes be random
  • Epsilon-soft
    • some sources refer to a method call “epsilon-soft”
    • Idea: We want a lower limit for every action to be selected
  • But we also use epsilon to decide if we want to explore:
  • From now on, we’ll just refer to this as epsilon-greedy

추가 설명

  • 즉 해보지 않은 행동에 대해서도 가끔 선택할 수 있게 하는 방법
  • 방법에는 두가지가 있다
    • On-policy : 결정했던 행동들을 가지고 정책을 평가 발전한다
    • Off-Policy : 다른 방법에 의해 만들어진 데이터로 정책 평가와 발전한다.
  • Monte Carlo ES는 On-Policy
  • Monte Carlo without ES 는 Off-Policy
  • On-policy Control 방법은 정책이 Soft 하다. Soft의 뜻은 정책의 모든 확률이 0 이상, 즉 초기에 모든 행동을 일정 확률로 할 가능성이 있다가 점점 결정적인 최적의 정책으로 바뀐다(deterministic Optimal Policy).
  • Off-Policy Control은 Epsilon Greedy 방법을 이용하여 랜덤하게 행동을 선택할 확률 최소값은 Epsilon / IA(s)I 이며, 나머지 확률 1-epsilon+epsilon/IA(s)I 로 greedy 행동을 취한다. (1-epsilon에 epsilon/IA(s)I 추가한 이유는 랜덤하게 하는 행동중 하나가 이 greedy로 행동 할 것이기 때문이다.)
  • epsilon-greedy 정책은 확률이 π(a I s) >= epsilon/IA(s)I로, e-soft policy의 예이다.
  • 즉 exporing starts 가정 없이 탐험을 할 수 없기 때문에 무작정 가치를 따라 Greedy하게 행동하도록 할 수 없다.
  • epsilon-greedy policy 또한 정책 개선 이론에 따라 확실히 개선된다. π’를 epsilon-greedy policy라고 하였을 때( weighted average가 1 이고, 가장 큰 수보다 작거나 같다. 아래식은 모든 행동에 대한 확률의 합이 1이 되도록 한 식이다.)
  • 결국 정책 x의 가치의 합이기 때문에 이는 상태 가치홤수와 같다. 결국 $q_π$(s,π’(s))>=$v_π$(s) 이므로, 정책 개선 이론에 따라 π’>=π(즉 $v+π$(s)>=$v_π$(s))가 된다.
  • epsilon-soft policy 과에 차이점은 epsilon-soft가 들어갔다는 차이밖에 없다. 동일한 행동과 상태들, epsilon에 따라 랜덤한 행동을 하는 것까지 같다. 아래에 variable $v_$^~ $q_$^~ 이 새로운 환경에 최적의 가치 함수들이라고 하자. 그럼 epsilon-soft policy 는 $v_π$ = $v_π$^~라면 π는 최적이라고 할 수 있을 것이다.

  • $v_π$ = $v_π$^~ 로 바꾸면
  • Policy iteration은 epsilon-soft policy 에도 적용이 된다는 것을 보였을 것이다. epsilon-soft-poilicy 에 greedy policy를 적용하면 매 step마다 개선이 확실 된다는 것을 보이며, exploring starts를 제거했다.

How often will we reach off-policy states?

  • Consider a state K steps away from the start
  • the probability that we get there by pure exploration is small
  • we need to run MC many times to converge for these states

5. MC Summary

  • Last Section, DP: we knew all the state transition probability and never played the game
  • this section: learn from experience
  • main idea: approximate the expected return with sample mean
  • First-visit and every-visit

MC VS DP

  • MC can be more efficient than DP because we don’t need to loop through all states
  • But also means we might not get the “full” value function, since some states will never be reached or reached very rarely
  • more data -> more accuracy
  • We used exploring starts to ensure we had adequate data for each state

MC Control

  • Use Q instead of V
  • No look-ahead search
  • Problem: MC loop inside another loop
  • We took the same approach as value iteration: update the policy after every episode, keep updating the same Q in-place
  • Surprising: it converges even though the samples are not all for the same policy
  • Never formally proved to converge
  • we then removed exploring starts assumption by replacing it with epsilon-greedy
  • MDPs are like different multi-armed bandit problem at each state

Reference:

Artificial Intelligence Reinforcement Learning

Advance AI : Deep-Reinforcement Learning

Cutting-Edge Deep-Reinforcement Learning

Comment  Read more