close_btn
로그인, 회원가입후 더 많은 혜택을 누리세요 로그인 회원가입 닫기

 

https://github.com/modulabs/RL4RWS/blob/master/reinforcement-learning/02_qlearning_dummy.py

 

 

<< Q-Table >>
Q-learning에서는 앞으로 어떤 action을 취할지 결정하기 위해서 Q-table을 사용하는데,
Q-table은 맵과 같은 모양(Frozen-Lake의 경우 4x4)으로 만들어지며
각 칸에는 해당 칸에서 각각의 action을 취할 때 기대하는 reward 값으로 채워진다.
(한 state에서 취할 수 있는 action이 상하좌우 4개이기 때문에 각 칸마다 4개의 값이 필요하다)
    action |  L  |  D  |  R  |  U |
state
-----------------------------------
0           |      |      |     |     |
-----------------------------------
1           |      |      |     |     |
-----------------------------------
2           |      |      |     |     |
-----------------------------------
3           |      |      |     |     |
-----------------------------------
...           |      |      |     |     |
-----------------------------------
Q-learning을 진행하면서 Q-table의 각 reward 값을 업데이트 하여 최상의 결과값을 리턴할 수 있도록 해야한다.
2강에서는 Q-learning의 알고리즘을 제외하고 Q-table이 업데이트되는 법에 대해서 이해하도록 한다.
<< Q-table 업데이트 방식 >>
-------------------------
|   0  |  1  |  2   |  3  |
-------------------------
|   4  |  5  |  6   |  7  |
-------------------------
|   8  |  9  |  10 |  11 |
-------------------------
|  12 |  13 |  14 |  15 |<-Goal
-------------------------
Dummy Q-learning은 0으로 채워놓은 Q-테이블에서 시작해서 각 state에서 취할 action을 랜덤으로 선택한다.
(상하좌우 모두 reward가 0이기 때문에)
Frozen-Lake에서는 결승점에 도달할 때만 reward 1이 주어지기 때문에 결승점에 도착하기 전에는
reward는 무조건 0이 리턴된다. action은 랜덤으로 정해지기 때문에 보통 구멍에 빠져서 게임이 종료되는 상황이 
반복 되다가 우연히 결승점에 다다르면 그제서야 reward가 1이 주어진다. 
그럼 학습하는 agent는 이 전 칸에서 어떤 action(예를 들어 14번칸에서 오른쪽)을 하면 결승점에 다다른다는 것을
알게 된다. 그럼 이 전 칸의 Q-table을 업데이트 할 수 있다(14번칸에서 오른쪽의 값을 1로 업데이트).
이처럼 Q-table은 우연히 결승점에 도착한 상황을 토대로 시작점까지 거꾸로 거슬러 올라가면서 Q값을 업데이트하는
방식을 사용한다. (결승점에 도착하기 위해서는 14번에서 오른쪽으로 가야한다. 14번에 다다르기 위해서는 
10번에서 아래로 가야한다. 10번에 가기 위해서는 ... ) 이런 알고리즘을 식으로 표현하면 아래와 같다.
Q[state, action] = reward + max(Q[new_state])
<< Dummy Q-learning >>
2강의 Dummy Q-learning에서는 1이 채워지지 않는 칸에서 action이 랜덤으로 정해지기 때문에 
갈림길의 경우에는 랜덤으로 돌아다니다가 어떤 길로 우연히 처음 들게 되었는지에 따라 Q-테이블의 모양이 달라지게 된다.
한 state의 여러 action 중에서 1 값을 갖는 건 무조건 하나일 수 밖에 없다.
일단 1이 채워지면 그 다음부터는 max값을 따라서 1이 채워진 방향으로만 지나갈 것이기 때문이다.
또한, 아무리 빠른 지름길이 있더라도, 1이 채워지지 않게 되면 그 길로 들어서지 못하게 되기 때문에 성공하더라도 최단거리일 가능성은 낮다.

 


1. regiser 추가

 

 
import gym
from gym.envs.registration import register

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={
        'map_name': '4x4',
        'is_slippery': False
    }
)

env = gym.make("FrozenLake-v3")

num_episodes = 1000
for i in range(num_episodes) : # 학습을 num_episodes 만큼 시키면서 업데이트
    env.reset()​
    done = None 
    while not done:                            # 게임 한판
        #####env.render()                      # 속도를 위해 주석 처리함
        action = env.action_space.sample()
        state, reward, done, _ = env.step(action) 
    env.render()                               # 에피소드가 끝날 때 마다 상태 확인

 

현재까지 사용한 FrozenLake-V3은 OpenAI GYM에서 기본적으로 제공한 환경이 이었다.

FrozenLake-V0은 Stochastic 환경을 제공하고 

Dummy Q-learning은 환경을 단순화하기 위해 Deteministic 환경에서 학습을 진행한다.

 

'is_slippery': False 이면 Deteministic 환경이고

'is_slippery': True 이면 Stochastic 환경이다.

 

 

 


2. numpy를 사용하여 Q를 생성하고 rargmax 함수 생성 후 활용

 

 
import gym
from gym.envs.registration import register
import numpy as np      ####  http://yujuwon.tistory.com/entry/NumPy
import random

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={
        'map_name': '4x4',
        'is_slippery': False
    }
)

env = gym.make("FrozenLake-v3")

Q = np.zeros([env.observation_space.n, env.action_space.n])    # (16,4) : 4*4 map + 상하좌우 4개

num_episodes = 1000

def rargmax(vector) :
    m = np.amax(vector)                    # Return the maximum of an array or maximum along an axis (0 아니면 1)
    indices = np.nonzero(vector == m)[0]   # np.nonzero(True/False vector) => 최대값인 요소들만 걸러내
    return random.choice(indices)          # 그 중 하나 랜덤으로 선택

for i in range(num_episodes) :             # 학습을 num_episodes 만큼 시키면서 업데이트
    state = env.reset()                    # 리셋
    done = None
    while not done:                        # 게임 한판
        action = rargmax(Q[state, :])      
        new_state, reward, done, _ = env.step(action) 
        Q[state, action] = reward + np.max(Q[new_state, :])  

 

Q를 생성한다. 2차원 배열 16 x 4 각상태마다 전후좌우 값 저장

numpy 사용 배열 생성

rargmax 함수 작성 action을 선택할 때 Q 값을 가지고 선택한다.

Q값이 높은 action을 선택하고 Q값이 값으면 값은 값 중에 랜덤으로 선택한다.

 

rargmax 함수에 의해서 action이 선택이 되고 선택된 action을 사용하여 env.step 함수가 호출된다.이때 환경이 Deterministic 환경에서 다음 상태로 이동한다.

env.step 함수 리턴값은 new_state, reward, done 변수를 업데이트 한다.

상태 천이가 이루어진 후에는 Q 값을 업데이트 한다.

 


3.  디버그 코드 추가

 

matplotlib install

  - sudo apt-get update

  - sudo pip install matplotlib

  - sudo apt-get install python3-tk

 

 
import gym
from gym.envs.registration import register
import numpy as np      ####  http://yujuwon.tistory.com/entry/NumPy
import random
import matplotlib.pyplot as plt

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={
        'map_name': '4x4',
        'is_slippery': False
    }
)

env = gym.make("FrozenLake-v3")

Q = np.zeros([env.observation_space.n, env.action_space.n])    # (16,4) : 4*4 map + 상하좌우 4개

num_episodes = 1000
rList = []
successRate = []

def rargmax(vector) :
    m = np.amax(vector)                    # Return the maximum of an array or maximum along an axis (0 아니면 1)
    indices = np.nonzero(vector == m)[0]   # np.nonzero(True/False vector) => 최대값인 요소들만 걸러내
    return random.choice(indices)          # 그 중 하나 랜덤으로 선택

for i in range(num_episodes) :             # 학습을 num_episodes 만큼 시키면서 업데이트
    state = env.reset()                    # 리셋
    total_reward = 0                       # 나중에 그래프를 그리기 위한 (성공하면 1, 실패하면 0)
    done = None
    while not done:
        action = rargmax(Q[state, :])
        new_state, reward, done, _ = env.step(action) 
        Q[state, action] = reward + np.max(Q[new_state, :]) 
        total_reward += reward
        state = new_state
    rList.append(total_reward)                 # 이번 게임에서 reward가 0인지 1인지
    successRate.append(sum(rList)/(i+1))       # 지금까지의 성공률
print("Final Q-Table")
print(Q)
print("Success Rate : ", successRate[-1])
plt.plot(range(len(successRate)), successRate) # 성공률 그래프
plt.plot(range(len(rList)), rList)             # reward 그래프
plt.show()


 

 

 

 

번호 제목 글쓴이 날짜 조회 수
공지 RL4RWS 이용 안내 모두의연구소 2017.09.04 2030
35 강화학습 실습 6. Tensorflow 설치 및 간단한 테스트 cosmos 2018.02.11 1093
34 강화학습 실습 5. FrozonLake - Q-Learning on Stochastic World file cosmos 2018.02.09 208
33 강화학습 실습 4. FrozonLake - Q-Learning : Exploit & Exploration file cosmos 2018.02.09 230
» 강화학습 실습 3. FrozonLake - dummy Q-learning file cosmos 2018.02.09 293
31 강화학습 실습 2. FrozonLake 동작 시켜 보기 file cosmos 2018.02.09 211
30 강화학습 실습 1. Python과 OpenAI Gym 설치 및 간단한 동작 file cosmos 2018.02.09 538
29 1차 아두이노 및 부품 리스트 file cosmos 2018.02.07 133
28 2월 6일 세미나 진행 내용 cosmos 2018.02.06 63
27 아두이노 기반 실물 제작 발표자료 file cosmos 2018.02.02 123
26 아두이노 설치 및 초음파센서, 모터, 블루투스 예제 사이트 정리 cosmos 2018.02.01 830
25 향후 일정 정리 file cosmos 2018.01.31 159
24 1월 30일 세미나 진행 내용 cosmos 2018.01.31 35
23 강화학습의 진화 : 3차원 및 물리환경의 적용 - LG blog file cosmos 2018.01.26 127
22 1월 23일 세미나 진행 내용 cosmos 2018.01.23 86
21 Autonomous self-learning systems 영문 번역 1차 file cosmos 2018.01.22 83
20 이산 시간 확률 과정, 마르코프 체인, 마르코프 의사결정 과정 관련 사이트 정리 cosmos 2018.01.18 639
19 시즌 2에 사용할 실물 회로 및 부품 file cosmos 2018.01.12 87
18 10월 31일 세미나에서 진행할 내용 cosmos 2017.10.31 70
17 Line Tracer 예제 코드 컴파일 하기 [4] file 쪼알 2017.10.26 169
16 10월 24일 세미나에서 진행할 내용 cosmos 2017.10.24 56