├── .gitignore ├── 1-grid-world ├── 1-policy-iteration │ ├── environment.py │ └── policy_iteration.py ├── 2-value-iteration │ ├── environment.py │ └── value_iteration.py ├── 3-monte-carlo │ ├── environment.py │ └── mc_agent.py ├── 4-sarsa │ ├── .python-version │ ├── environment.py │ └── sarsa_agent.py ├── 5-q-learning │ ├── .python-version │ ├── environment.py │ └── q_learning_agent.py ├── 6-deep-sarsa │ ├── deep_sarsa_agent.py │ ├── environment.py │ ├── save_graph │ │ └── deep_sarsa_trained.png │ └── save_model │ │ └── deep_sarsa_trained.h5 ├── 7-reinforce │ ├── environment.py │ ├── reinforce_agent.py │ ├── save_graph │ │ └── reinforce_trained.png │ └── save_model │ │ └── reinforce_trained.h5 ├── README.md ├── gridworld.png └── img │ ├── circle.png │ ├── down.png │ ├── left.png │ ├── rectangle.png │ ├── right.png │ ├── triangle.png │ └── up.png ├── 2-cartpole ├── 1-dqn │ ├── cartpole_dqn.py │ ├── save_graph │ │ └── cartpole_dqn.png │ └── save_model │ │ └── cartpole_dqn_trained.h5 ├── 2-actor-critic │ ├── cartpole_a2c.py │ ├── save_graph │ │ └── cartpole_a2c.png │ └── save_model │ │ ├── cartpole_actor_trained.h5 │ │ └── cartpole_critic_trained.h5 ├── LICENSE ├── README.md └── cartpole.png ├── 3-atari ├── 1-breakout │ ├── breakout_a3c.py │ ├── breakout_dqn.py │ ├── play_a3c_model.py │ ├── play_dqn_model.py │ ├── save_model │ │ ├── breakout_a3c_1_actor.h5 │ │ ├── breakout_a3c_1_critic.h5 │ │ ├── breakout_a3c_2_actor.h5 │ │ ├── breakout_a3c_2_critic.h5 │ │ ├── breakout_a3c_3_actor.h5 │ │ ├── breakout_a3c_3_critic.h5 │ │ ├── breakout_a3c_4_actor.h5 │ │ ├── breakout_a3c_4_critic.h5 │ │ ├── breakout_a3c_5_actor.h5 │ │ ├── breakout_a3c_5_critic.h5 │ │ ├── breakout_dqn.h5 │ │ ├── breakout_dqn_1.h5 │ │ ├── breakout_dqn_2.h5 │ │ ├── breakout_dqn_3.h5 │ │ ├── breakout_dqn_4.h5 │ │ └── breakout_dqn_5.h5 │ └── summary │ │ ├── breakout_a3c │ │ └── events.out.tfevents.1497264638 │ │ └── breakout_dqn │ │ └── events.out.tfevents.1496968668.young-System-Product-Name └── LICENSE ├── LICENSE ├── README.md ├── images └── Reinforcement-Learning.png ├── requirements.txt └── wiki ├── README.md ├── how-to-windows(english).md ├── img ├── how-to-windows.png ├── link-env-with-pychar-1.png ├── link-env-with-pychar-2.png ├── link-env-with-pychar.png ├── numpy_install.png ├── numpy_install2.png ├── numpy_install3.png ├── python3png.png ├── python_install.png ├── win_atari.png ├── win_atari.py3.png ├── win_breakout.png ├── win_breakout2.png ├── win_git.png ├── win_git2.png ├── win_gym.png ├── win_make.png ├── win_make2.png ├── win_msys2.png ├── win_msys2_2.png ├── win_msys2_3.png ├── win_msys2_4.png ├── win_msys2_5.png ├── win_openai_gym.png ├── win_openai_gym2.png ├── win_openai_gym3.png ├── win_openai_gym4.png ├── win_openai_gym5.png ├── win_pycharm_install1.png ├── win_pycharm_project.png ├── win_pycharm_project2.png ├── win_pycharm_setting2.png ├── win_pycharm_settings.png ├── win_setting.png ├── win_setting2.png ├── win_setting3.png ├── win_setting4.png ├── win_setup.py.png ├── win_setup.py2.png └── win_xming.png ├── install_guide_osx.md ├── install_guide_ubuntu.md ├── install_guide_window.md └── install_image ├── atari_breakout.png ├── cartpole_exam.png ├── console_hello_world.png ├── default_config.png ├── file_setting.png ├── hello_world_ubuntu.png ├── openai_github.png ├── project_interpreter.png ├── pycham_new_project.png ├── pycharm_community.png ├── pycharm_drag.png ├── pycharm_init.png ├── python3_terminal.jpg ├── python_download.png ├── python_installed.png ├── python_intalled.png ├── rl_book_hello_world.png ├── rl_book_project.png ├── rl_book_venv.png ├── rl_book_virtualenv.png ├── rlcode_book_directory.png ├── rlcode_project.png ├── run_hello_world.png ├── sh_pycharm.sh.png └── terminal_rlcode_book.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.project 2 | *.pydevproject 3 | .idea/ 4 | .DS_Store 5 | __pycache__ -------------------------------------------------------------------------------- /1-grid-world/1-policy-iteration/environment.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import Button 3 | import time 4 | import numpy as np 5 | from PIL import ImageTk, Image 6 | 7 | PhotoImage = ImageTk.PhotoImage 8 | UNIT = 100 # 픽셀 수 9 | HEIGHT = 5 # 그리드월드 세로 10 | WIDTH = 5 # 그리드월드 가로 11 | TRANSITION_PROB = 1 12 | POSSIBLE_ACTIONS = [0, 1, 2, 3] # 좌, 우, 상, 하 13 | ACTIONS = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 좌표로 나타낸 행동 14 | REWARDS = [] 15 | 16 | 17 | class GraphicDisplay(tk.Tk): 18 | def __init__(self, agent): 19 | super(GraphicDisplay, self).__init__() 20 | self.title('Policy Iteration') 21 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT + 50)) 22 | self.texts = [] 23 | self.arrows = [] 24 | self.env = Env() 25 | self.agent = agent 26 | self.evaluation_count = 0 27 | self.improvement_count = 0 28 | self.is_moving = 0 29 | (self.up, self.down, self.left, self.right), self.shapes = self.load_images() 30 | self.canvas = self._build_canvas() 31 | self.text_reward(2, 2, "R : 1.0") 32 | self.text_reward(1, 2, "R : -1.0") 33 | self.text_reward(2, 1, "R : -1.0") 34 | 35 | def _build_canvas(self): 36 | canvas = tk.Canvas(self, bg='white', 37 | height=HEIGHT * UNIT, 38 | width=WIDTH * UNIT) 39 | # 버튼 초기화 40 | iteration_button = Button(self, text="Evaluate", 41 | command=self.evaluate_policy) 42 | iteration_button.configure(width=10, activebackground="#33B5E5") 43 | canvas.create_window(WIDTH * UNIT * 0.13, HEIGHT * UNIT + 10, 44 | window=iteration_button) 45 | policy_button = Button(self, text="Improve", 46 | command=self.improve_policy) 47 | policy_button.configure(width=10, activebackground="#33B5E5") 48 | canvas.create_window(WIDTH * UNIT * 0.37, HEIGHT * UNIT + 10, 49 | window=policy_button) 50 | policy_button = Button(self, text="move", command=self.move_by_policy) 51 | policy_button.configure(width=10, activebackground="#33B5E5") 52 | canvas.create_window(WIDTH * UNIT * 0.62, HEIGHT * UNIT + 10, 53 | window=policy_button) 54 | policy_button = Button(self, text="reset", command=self.reset) 55 | policy_button.configure(width=10, activebackground="#33B5E5") 56 | canvas.create_window(WIDTH * UNIT * 0.87, HEIGHT * UNIT + 10, 57 | window=policy_button) 58 | 59 | # 그리드 생성 60 | for col in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 61 | x0, y0, x1, y1 = col, 0, col, HEIGHT * UNIT 62 | canvas.create_line(x0, y0, x1, y1) 63 | for row in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 64 | x0, y0, x1, y1 = 0, row, HEIGHT * UNIT, row 65 | canvas.create_line(x0, y0, x1, y1) 66 | 67 | # 캔버스에 이미지 추가 68 | self.rectangle = canvas.create_image(50, 50, image=self.shapes[0]) 69 | canvas.create_image(250, 150, image=self.shapes[1]) 70 | canvas.create_image(150, 250, image=self.shapes[1]) 71 | canvas.create_image(250, 250, image=self.shapes[2]) 72 | 73 | canvas.pack() 74 | 75 | return canvas 76 | 77 | def load_images(self): 78 | up = PhotoImage(Image.open("../img/up.png").resize((13, 13))) 79 | right = PhotoImage(Image.open("../img/right.png").resize((13, 13))) 80 | left = PhotoImage(Image.open("../img/left.png").resize((13, 13))) 81 | down = PhotoImage(Image.open("../img/down.png").resize((13, 13))) 82 | rectangle = PhotoImage(Image.open("../img/rectangle.png").resize((65, 65))) 83 | triangle = PhotoImage(Image.open("../img/triangle.png").resize((65, 65))) 84 | circle = PhotoImage(Image.open("../img/circle.png").resize((65, 65))) 85 | return (up, down, left, right), (rectangle, triangle, circle) 86 | 87 | def reset(self): 88 | if self.is_moving == 0: 89 | self.evaluation_count = 0 90 | self.improvement_count = 0 91 | for i in self.texts: 92 | self.canvas.delete(i) 93 | 94 | for i in self.arrows: 95 | self.canvas.delete(i) 96 | self.agent.value_table = [[0.0] * WIDTH for _ in range(HEIGHT)] 97 | self.agent.policy_table = ([[[0.25, 0.25, 0.25, 0.25]] * WIDTH 98 | for _ in range(HEIGHT)]) 99 | self.agent.policy_table[2][2] = [] 100 | x, y = self.canvas.coords(self.rectangle) 101 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 102 | 103 | def text_value(self, row, col, contents, font='Helvetica', size=10, 104 | style='normal', anchor="nw"): 105 | origin_x, origin_y = 85, 70 106 | x, y = origin_y + (UNIT * col), origin_x + (UNIT * row) 107 | font = (font, str(size), style) 108 | text = self.canvas.create_text(x, y, fill="black", text=contents, 109 | font=font, anchor=anchor) 110 | return self.texts.append(text) 111 | 112 | def text_reward(self, row, col, contents, font='Helvetica', size=10, 113 | style='normal', anchor="nw"): 114 | origin_x, origin_y = 5, 5 115 | x, y = origin_y + (UNIT * col), origin_x + (UNIT * row) 116 | font = (font, str(size), style) 117 | text = self.canvas.create_text(x, y, fill="black", text=contents, 118 | font=font, anchor=anchor) 119 | return self.texts.append(text) 120 | 121 | def rectangle_move(self, action): 122 | base_action = np.array([0, 0]) 123 | location = self.find_rectangle() 124 | self.render() 125 | if action == 0 and location[0] > 0: # 상 126 | base_action[1] -= UNIT 127 | elif action == 1 and location[0] < HEIGHT - 1: # 하 128 | base_action[1] += UNIT 129 | elif action == 2 and location[1] > 0: # 좌 130 | base_action[0] -= UNIT 131 | elif action == 3 and location[1] < WIDTH - 1: # 우 132 | base_action[0] += UNIT 133 | # move agent 134 | self.canvas.move(self.rectangle, base_action[0], base_action[1]) 135 | 136 | def find_rectangle(self): 137 | temp = self.canvas.coords(self.rectangle) 138 | x = (temp[0] / 100) - 0.5 139 | y = (temp[1] / 100) - 0.5 140 | return int(y), int(x) 141 | 142 | def move_by_policy(self): 143 | if self.improvement_count != 0 and self.is_moving != 1: 144 | self.is_moving = 1 145 | 146 | x, y = self.canvas.coords(self.rectangle) 147 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 148 | 149 | x, y = self.find_rectangle() 150 | while len(self.agent.policy_table[x][y]) != 0: 151 | self.after(100, 152 | self.rectangle_move(self.agent.get_action([x, y]))) 153 | x, y = self.find_rectangle() 154 | self.is_moving = 0 155 | 156 | def draw_one_arrow(self, col, row, policy): 157 | if col == 2 and row == 2: 158 | return 159 | 160 | if policy[0] > 0: # up 161 | origin_x, origin_y = 50 + (UNIT * row), 10 + (UNIT * col) 162 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 163 | image=self.up)) 164 | if policy[1] > 0: # down 165 | origin_x, origin_y = 50 + (UNIT * row), 90 + (UNIT * col) 166 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 167 | image=self.down)) 168 | if policy[2] > 0: # left 169 | origin_x, origin_y = 10 + (UNIT * row), 50 + (UNIT * col) 170 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 171 | image=self.left)) 172 | if policy[3] > 0: # right 173 | origin_x, origin_y = 90 + (UNIT * row), 50 + (UNIT * col) 174 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 175 | image=self.right)) 176 | 177 | def draw_from_policy(self, policy_table): 178 | for i in range(HEIGHT): 179 | for j in range(WIDTH): 180 | self.draw_one_arrow(i, j, policy_table[i][j]) 181 | 182 | def print_value_table(self, value_table): 183 | for i in range(WIDTH): 184 | for j in range(HEIGHT): 185 | self.text_value(i, j, value_table[i][j]) 186 | 187 | def render(self): 188 | time.sleep(0.1) 189 | self.canvas.tag_raise(self.rectangle) 190 | self.update() 191 | 192 | def evaluate_policy(self): 193 | self.evaluation_count += 1 194 | for i in self.texts: 195 | self.canvas.delete(i) 196 | self.agent.policy_evaluation() 197 | self.print_value_table(self.agent.value_table) 198 | 199 | def improve_policy(self): 200 | self.improvement_count += 1 201 | for i in self.arrows: 202 | self.canvas.delete(i) 203 | self.agent.policy_improvement() 204 | self.draw_from_policy(self.agent.policy_table) 205 | 206 | 207 | class Env: 208 | def __init__(self): 209 | self.transition_probability = TRANSITION_PROB 210 | self.width = WIDTH 211 | self.height = HEIGHT 212 | self.reward = [[0] * WIDTH for _ in range(HEIGHT)] 213 | self.possible_actions = POSSIBLE_ACTIONS 214 | self.reward[2][2] = 1 # (2,2) 좌표 동그라미 위치에 보상 1 215 | self.reward[1][2] = -1 # (1,2) 좌표 세모 위치에 보상 -1 216 | self.reward[2][1] = -1 # (2,1) 좌표 세모 위치에 보상 -1 217 | self.all_state = [] 218 | 219 | for x in range(WIDTH): 220 | for y in range(HEIGHT): 221 | state = [x, y] 222 | self.all_state.append(state) 223 | 224 | def get_reward(self, state, action): 225 | next_state = self.state_after_action(state, action) 226 | return self.reward[next_state[0]][next_state[1]] 227 | 228 | def state_after_action(self, state, action_index): 229 | action = ACTIONS[action_index] 230 | return self.check_boundary([state[0] + action[0], state[1] + action[1]]) 231 | 232 | @staticmethod 233 | def check_boundary(state): 234 | state[0] = (0 if state[0] < 0 else WIDTH - 1 235 | if state[0] > WIDTH - 1 else state[0]) 236 | state[1] = (0 if state[1] < 0 else HEIGHT - 1 237 | if state[1] > HEIGHT - 1 else state[1]) 238 | return state 239 | 240 | def get_transition_prob(self, state, action): 241 | return self.transition_probability 242 | 243 | def get_all_states(self): 244 | return self.all_state 245 | -------------------------------------------------------------------------------- /1-grid-world/1-policy-iteration/policy_iteration.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import random 3 | from environment import GraphicDisplay, Env 4 | 5 | 6 | class PolicyIteration: 7 | def __init__(self, env): 8 | # 환경에 대한 객체 선언 9 | self.env = env 10 | # 가치함수를 2차원 리스트로 초기화 11 | self.value_table = [[0.0] * env.width for _ in range(env.height)] 12 | # 상 하 좌 우 동일한 확률로 정책 초기화 13 | self.policy_table = [[[0.25, 0.25, 0.25, 0.25]] * env.width 14 | for _ in range(env.height)] 15 | # 마침 상태의 설정 16 | self.policy_table[2][2] = [] 17 | # 감가율 18 | self.discount_factor = 0.9 19 | 20 | def policy_evaluation(self): 21 | 22 | # 다음 가치함수 초기화 23 | next_value_table = [[0.00] * self.env.width 24 | for _ in range(self.env.height)] 25 | 26 | # 모든 상태에 대해서 벨만 기대방정식을 계산 27 | for state in self.env.get_all_states(): 28 | value = 0.0 29 | # 마침 상태의 가치 함수 = 0 30 | if state == [2, 2]: 31 | next_value_table[state[0]][state[1]] = value 32 | continue 33 | 34 | # 벨만 기대 방정식 35 | for action in self.env.possible_actions: 36 | next_state = self.env.state_after_action(state, action) 37 | reward = self.env.get_reward(state, action) 38 | next_value = self.get_value(next_state) 39 | value += (self.get_policy(state)[action] * 40 | (reward + self.discount_factor * next_value)) 41 | 42 | next_value_table[state[0]][state[1]] = round(value, 2) 43 | 44 | self.value_table = next_value_table 45 | 46 | # 현재 가치 함수에 대해서 탐욕 정책 발전 47 | def policy_improvement(self): 48 | next_policy = self.policy_table 49 | for state in self.env.get_all_states(): 50 | if state == [2, 2]: 51 | continue 52 | value = -99999 53 | max_index = [] 54 | # 반환할 정책 초기화 55 | result = [0.0, 0.0, 0.0, 0.0] 56 | 57 | # 모든 행동에 대해서 [보상 + (감가율 * 다음 상태 가치함수)] 계산 58 | for index, action in enumerate(self.env.possible_actions): 59 | next_state = self.env.state_after_action(state, action) 60 | reward = self.env.get_reward(state, action) 61 | next_value = self.get_value(next_state) 62 | temp = reward + self.discount_factor * next_value 63 | 64 | # 받을 보상이 최대인 행동의 index(최대가 복수라면 모두)를 추출 65 | if temp == value: 66 | max_index.append(index) 67 | elif temp > value: 68 | value = temp 69 | max_index.clear() 70 | max_index.append(index) 71 | 72 | # 행동의 확률 계산 73 | prob = 1 / len(max_index) 74 | 75 | for index in max_index: 76 | result[index] = prob 77 | 78 | next_policy[state[0]][state[1]] = result 79 | 80 | self.policy_table = next_policy 81 | 82 | # 특정 상태에서 정책에 따른 행동을 반환 83 | def get_action(self, state): 84 | # 0 ~ 1 사이의 값을 무작위로 추출 85 | random_pick = random.randrange(100) / 100 86 | 87 | policy = self.get_policy(state) 88 | policy_sum = 0.0 89 | # 정책에 담긴 행동 중에 무작위로 한 행동을 추출 90 | for index, value in enumerate(policy): 91 | policy_sum += value 92 | if random_pick < policy_sum: 93 | return index 94 | 95 | # 상태에 따른 정책 반환 96 | def get_policy(self, state): 97 | if state == [2, 2]: 98 | return 0.0 99 | return self.policy_table[state[0]][state[1]] 100 | 101 | # 가치 함수의 값을 반환 102 | def get_value(self, state): 103 | # 소숫점 둘째 자리까지만 계산 104 | return round(self.value_table[state[0]][state[1]], 2) 105 | 106 | if __name__ == "__main__": 107 | env = Env() 108 | policy_iteration = PolicyIteration(env) 109 | grid_world = GraphicDisplay(policy_iteration) 110 | grid_world.mainloop() 111 | -------------------------------------------------------------------------------- /1-grid-world/2-value-iteration/environment.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | import time 3 | import numpy as np 4 | import random 5 | from PIL import ImageTk, Image 6 | 7 | PhotoImage = ImageTk.PhotoImage 8 | UNIT = 100 # 픽셀 수 9 | HEIGHT = 5 # 그리드월드 세로 10 | WIDTH = 5 # 그리드월드 가로 11 | TRANSITION_PROB = 1 12 | POSSIBLE_ACTIONS = [0, 1, 2, 3] # 상, 하, 좌, 우 13 | ACTIONS = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 좌표로 나타낸 행동 14 | REWARDS = [] 15 | 16 | 17 | class GraphicDisplay(tk.Tk): 18 | def __init__(self, value_iteration): 19 | super(GraphicDisplay, self).__init__() 20 | self.title('Value Iteration') 21 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT + 50)) 22 | self.texts = [] 23 | self.arrows = [] 24 | self.env = Env() 25 | self.agent = value_iteration 26 | self.iteration_count = 0 27 | self.improvement_count = 0 28 | self.is_moving = 0 29 | (self.up, self.down, self.left, 30 | self.right), self.shapes = self.load_images() 31 | self.canvas = self._build_canvas() 32 | self.text_reward(2, 2, "R : 1.0") 33 | self.text_reward(1, 2, "R : -1.0") 34 | self.text_reward(2, 1, "R : -1.0") 35 | 36 | def _build_canvas(self): 37 | canvas = tk.Canvas(self, bg='white', 38 | height=HEIGHT * UNIT, 39 | width=WIDTH * UNIT) 40 | # 버튼 초기화 41 | iteration_button = tk.Button(self, text="Calculate", 42 | command=self.calculate_value) 43 | iteration_button.configure(width=10, activebackground="#33B5E5") 44 | canvas.create_window(WIDTH * UNIT * 0.13, (HEIGHT * UNIT) + 10, 45 | window=iteration_button) 46 | 47 | policy_button = tk.Button(self, text="Print Policy", 48 | command=self.print_optimal_policy) 49 | policy_button.configure(width=10, activebackground="#33B5E5") 50 | canvas.create_window(WIDTH * UNIT * 0.37, (HEIGHT * UNIT) + 10, 51 | window=policy_button) 52 | 53 | policy_button = tk.Button(self, text="Move", 54 | command=self.move_by_policy) 55 | policy_button.configure(width=10, activebackground="#33B5E5") 56 | canvas.create_window(WIDTH * UNIT * 0.62, (HEIGHT * UNIT) + 10, 57 | window=policy_button) 58 | 59 | policy_button = tk.Button(self, text="Clear", command=self.clear) 60 | policy_button.configure(width=10, activebackground="#33B5E5") 61 | canvas.create_window(WIDTH * UNIT * 0.87, (HEIGHT * UNIT) + 10, 62 | window=policy_button) 63 | 64 | # 그리드 생성 65 | for col in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 66 | x0, y0, x1, y1 = col, 0, col, HEIGHT * UNIT 67 | canvas.create_line(x0, y0, x1, y1) 68 | for row in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 69 | x0, y0, x1, y1 = 0, row, HEIGHT * UNIT, row 70 | canvas.create_line(x0, y0, x1, y1) 71 | 72 | # 캔버스에 이미지 추가 73 | self.rectangle = canvas.create_image(50, 50, image=self.shapes[0]) 74 | canvas.create_image(250, 150, image=self.shapes[1]) 75 | canvas.create_image(150, 250, image=self.shapes[1]) 76 | canvas.create_image(250, 250, image=self.shapes[2]) 77 | 78 | canvas.pack() 79 | 80 | return canvas 81 | 82 | def load_images(self): 83 | PhotoImage = ImageTk.PhotoImage 84 | up = PhotoImage(Image.open("../img/up.png").resize((13, 13))) 85 | right = PhotoImage(Image.open("../img/right.png").resize((13, 13))) 86 | left = PhotoImage(Image.open("../img/left.png").resize((13, 13))) 87 | down = PhotoImage(Image.open("../img/down.png").resize((13, 13))) 88 | rectangle = PhotoImage( 89 | Image.open("../img/rectangle.png").resize((65, 65))) 90 | triangle = PhotoImage( 91 | Image.open("../img/triangle.png").resize((65, 65))) 92 | circle = PhotoImage(Image.open("../img/circle.png").resize((65, 65))) 93 | return (up, down, left, right), (rectangle, triangle, circle) 94 | 95 | def clear(self): 96 | 97 | if self.is_moving == 0: 98 | self.iteration_count = 0 99 | self.improvement_count = 0 100 | for i in self.texts: 101 | self.canvas.delete(i) 102 | 103 | for i in self.arrows: 104 | self.canvas.delete(i) 105 | 106 | self.agent.value_table = [[0.0] * WIDTH for _ in range(HEIGHT)] 107 | 108 | x, y = self.canvas.coords(self.rectangle) 109 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 110 | 111 | def reset(self): 112 | self.update() 113 | time.sleep(0.5) 114 | self.canvas.delete(self.rectangle) 115 | return self.canvas.coords(self.rectangle) 116 | 117 | def text_value(self, row, col, contents, font='Helvetica', size=12, 118 | style='normal', anchor="nw"): 119 | origin_x, origin_y = 85, 70 120 | x, y = origin_y + (UNIT * col), origin_x + (UNIT * row) 121 | font = (font, str(size), style) 122 | text = self.canvas.create_text(x, y, fill="black", text=contents, 123 | font=font, anchor=anchor) 124 | return self.texts.append(text) 125 | 126 | def text_reward(self, row, col, contents, font='Helvetica', size=12, 127 | style='normal', anchor="nw"): 128 | origin_x, origin_y = 5, 5 129 | x, y = origin_y + (UNIT * col), origin_x + (UNIT * row) 130 | font = (font, str(size), style) 131 | text = self.canvas.create_text(x, y, fill="black", text=contents, 132 | font=font, anchor=anchor) 133 | return self.texts.append(text) 134 | 135 | def rectangle_move(self, action): 136 | base_action = np.array([0, 0]) 137 | location = self.find_rectangle() 138 | self.render() 139 | if action == 0 and location[0] > 0: # up 140 | base_action[1] -= UNIT 141 | elif action == 1 and location[0] < HEIGHT - 1: # down 142 | base_action[1] += UNIT 143 | elif action == 2 and location[1] > 0: # left 144 | base_action[0] -= UNIT 145 | elif action == 3 and location[1] < WIDTH - 1: # right 146 | base_action[0] += UNIT 147 | 148 | self.canvas.move(self.rectangle, base_action[0], 149 | base_action[1]) # move agent 150 | 151 | def find_rectangle(self): 152 | temp = self.canvas.coords(self.rectangle) 153 | x = (temp[0] / 100) - 0.5 154 | y = (temp[1] / 100) - 0.5 155 | return int(y), int(x) 156 | 157 | def move_by_policy(self): 158 | 159 | if self.improvement_count != 0 and self.is_moving != 1: 160 | self.is_moving = 1 161 | x, y = self.canvas.coords(self.rectangle) 162 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 163 | 164 | x, y = self.find_rectangle() 165 | while len(self.agent.get_action([x, y])) != 0: 166 | action = random.sample(self.agent.get_action([x, y]), 1)[0] 167 | self.after(100, self.rectangle_move(action)) 168 | x, y = self.find_rectangle() 169 | self.is_moving = 0 170 | 171 | def draw_one_arrow(self, col, row, action): 172 | if col == 2 and row == 2: 173 | return 174 | if action == 0: # up 175 | origin_x, origin_y = 50 + (UNIT * row), 10 + (UNIT * col) 176 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 177 | image=self.up)) 178 | elif action == 1: # down 179 | origin_x, origin_y = 50 + (UNIT * row), 90 + (UNIT * col) 180 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 181 | image=self.down)) 182 | elif action == 3: # right 183 | origin_x, origin_y = 90 + (UNIT * row), 50 + (UNIT * col) 184 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 185 | image=self.right)) 186 | elif action == 2: # left 187 | origin_x, origin_y = 10 + (UNIT * row), 50 + (UNIT * col) 188 | self.arrows.append(self.canvas.create_image(origin_x, origin_y, 189 | image=self.left)) 190 | 191 | def draw_from_values(self, state, action_list): 192 | i = state[0] 193 | j = state[1] 194 | for action in action_list: 195 | self.draw_one_arrow(i, j, action) 196 | 197 | def print_values(self, values): 198 | for i in range(WIDTH): 199 | for j in range(HEIGHT): 200 | self.text_value(i, j, values[i][j]) 201 | 202 | def render(self): 203 | time.sleep(0.1) 204 | self.canvas.tag_raise(self.rectangle) 205 | self.update() 206 | 207 | def calculate_value(self): 208 | self.iteration_count += 1 209 | for i in self.texts: 210 | self.canvas.delete(i) 211 | self.agent.value_iteration() 212 | self.print_values(self.agent.value_table) 213 | 214 | def print_optimal_policy(self): 215 | self.improvement_count += 1 216 | for i in self.arrows: 217 | self.canvas.delete(i) 218 | for state in self.env.get_all_states(): 219 | action = self.agent.get_action(state) 220 | self.draw_from_values(state, action) 221 | 222 | 223 | class Env: 224 | def __init__(self): 225 | self.transition_probability = TRANSITION_PROB 226 | self.width = WIDTH # Width of Grid World 227 | self.height = HEIGHT # Height of GridWorld 228 | self.reward = [[0] * WIDTH for _ in range(HEIGHT)] 229 | self.possible_actions = POSSIBLE_ACTIONS 230 | self.reward[2][2] = 1 # reward 1 for circle 231 | self.reward[1][2] = -1 # reward -1 for triangle 232 | self.reward[2][1] = -1 # reward -1 for triangle 233 | self.all_state = [] 234 | 235 | for x in range(WIDTH): 236 | for y in range(HEIGHT): 237 | state = [x, y] 238 | self.all_state.append(state) 239 | 240 | def get_reward(self, state, action): 241 | next_state = self.state_after_action(state, action) 242 | return self.reward[next_state[0]][next_state[1]] 243 | 244 | def state_after_action(self, state, action_index): 245 | action = ACTIONS[action_index] 246 | return self.check_boundary([state[0] + action[0], state[1] + action[1]]) 247 | 248 | @staticmethod 249 | def check_boundary(state): 250 | state[0] = (0 if state[0] < 0 else WIDTH - 1 251 | if state[0] > WIDTH - 1 else state[0]) 252 | state[1] = (0 if state[1] < 0 else HEIGHT - 1 253 | if state[1] > HEIGHT - 1 else state[1]) 254 | return state 255 | 256 | def get_transition_prob(self, state, action): 257 | return self.transition_probability 258 | 259 | def get_all_states(self): 260 | return self.all_state 261 | -------------------------------------------------------------------------------- /1-grid-world/2-value-iteration/value_iteration.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from environment import GraphicDisplay, Env 3 | 4 | class ValueIteration: 5 | def __init__(self, env): 6 | # 환경 객체 생성 7 | self.env = env 8 | # 가치 함수를 2차원 리스트로 초기화 9 | self.value_table = [[0.0] * env.width for _ in range(env.height)] 10 | # 감가율 11 | self.discount_factor = 0.9 12 | 13 | # 가치 이터레이션 14 | # 벨만 최적 방정식을 통해 다음 가치 함수 계산 15 | def value_iteration(self): 16 | next_value_table = [[0.0] * self.env.width for _ in 17 | range(self.env.height)] 18 | for state in self.env.get_all_states(): 19 | if state == [2, 2]: 20 | next_value_table[state[0]][state[1]] = 0.0 21 | continue 22 | # 가치 함수를 위한 빈 리스트 23 | value_list = [] 24 | 25 | # 가능한 모든 행동에 대해 계산 26 | for action in self.env.possible_actions: 27 | next_state = self.env.state_after_action(state, action) 28 | reward = self.env.get_reward(state, action) 29 | next_value = self.get_value(next_state) 30 | value_list.append((reward + self.discount_factor * next_value)) 31 | # 최댓값을 다음 가치 함수로 대입 32 | next_value_table[state[0]][state[1]] = round(max(value_list), 2) 33 | self.value_table = next_value_table 34 | 35 | # 현재 가치 함수로부터 행동을 반환 36 | def get_action(self, state): 37 | action_list = [] 38 | max_value = -99999 39 | 40 | if state == [2, 2]: 41 | return [] 42 | 43 | # 모든 행동에 대해 큐함수 (보상 + (감가율 * 다음 상태 가치함수))를 계산 44 | # 최대 큐 함수를 가진 행동(복수일 경우 여러 개)을 반환 45 | for action in self.env.possible_actions: 46 | 47 | next_state = self.env.state_after_action(state, action) 48 | reward = self.env.get_reward(state, action) 49 | next_value = self.get_value(next_state) 50 | value = (reward + self.discount_factor * next_value) 51 | 52 | if value > max_value: 53 | action_list.clear() 54 | action_list.append(action) 55 | max_value = value 56 | elif value == max_value: 57 | action_list.append(action) 58 | 59 | return action_list 60 | 61 | def get_value(self, state): 62 | return round(self.value_table[state[0]][state[1]], 2) 63 | 64 | if __name__ == "__main__": 65 | env = Env() 66 | value_iteration = ValueIteration(env) 67 | grid_world = GraphicDisplay(value_iteration) 68 | grid_world.mainloop() 69 | -------------------------------------------------------------------------------- /1-grid-world/3-monte-carlo/environment.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | import tkinter as tk 4 | from PIL import ImageTk, Image 5 | 6 | np.random.seed(1) 7 | PhotoImage = ImageTk.PhotoImage 8 | UNIT = 100 # 픽셀 수 9 | HEIGHT = 5 # 그리드 월드 세로 10 | WIDTH = 5 # 그리드 월드 가로 11 | 12 | 13 | class Env(tk.Tk): 14 | def __init__(self): 15 | super(Env, self).__init__() 16 | self.action_space = ['u', 'd', 'l', 'r'] 17 | self.n_actions = len(self.action_space) 18 | self.title('monte carlo') 19 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT)) 20 | self.shapes = self.load_images() 21 | self.canvas = self._build_canvas() 22 | self.texts = [] 23 | 24 | def _build_canvas(self): 25 | canvas = tk.Canvas(self, bg='white', 26 | height=HEIGHT * UNIT, 27 | width=WIDTH * UNIT) 28 | # 그리드 생성 29 | for c in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 30 | x0, y0, x1, y1 = c, 0, c, HEIGHT * UNIT 31 | canvas.create_line(x0, y0, x1, y1) 32 | for r in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 33 | x0, y0, x1, y1 = 0, r, HEIGHT * UNIT, r 34 | canvas.create_line(x0, y0, x1, y1) 35 | 36 | # 캔버스에 이미지 추가 37 | self.rectangle = canvas.create_image(50, 50, image=self.shapes[0]) 38 | self.triangle1 = canvas.create_image(250, 150, image=self.shapes[1]) 39 | self.triangle2 = canvas.create_image(150, 250, image=self.shapes[1]) 40 | self.circle = canvas.create_image(250, 250, image=self.shapes[2]) 41 | 42 | canvas.pack() 43 | 44 | return canvas 45 | 46 | def load_images(self): 47 | rectangle = PhotoImage( 48 | Image.open("../img/rectangle.png").resize((65, 65))) 49 | triangle = PhotoImage( 50 | Image.open("../img/triangle.png").resize((65, 65))) 51 | circle = PhotoImage( 52 | Image.open("../img/circle.png").resize((65, 65))) 53 | 54 | return rectangle, triangle, circle 55 | 56 | @staticmethod 57 | def coords_to_state(coords): 58 | x = int((coords[0] - 50) / 100) 59 | y = int((coords[1] - 50) / 100) 60 | return [x, y] 61 | 62 | def reset(self): 63 | self.update() 64 | time.sleep(0.5) 65 | x, y = self.canvas.coords(self.rectangle) 66 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 67 | return self.coords_to_state(self.canvas.coords(self.rectangle)) 68 | 69 | def step(self, action): 70 | state = self.canvas.coords(self.rectangle) 71 | base_action = np.array([0, 0]) 72 | self.render() 73 | 74 | if action == 0: # 상 75 | if state[1] > UNIT: 76 | base_action[1] -= UNIT 77 | elif action == 1: # 하 78 | if state[1] < (HEIGHT - 1) * UNIT: 79 | base_action[1] += UNIT 80 | elif action == 2: # 좌 81 | if state[0] > UNIT: 82 | base_action[0] -= UNIT 83 | elif action == 3: # 우 84 | if state[0] < (WIDTH - 1) * UNIT: 85 | base_action[0] += UNIT 86 | # 에이전트 이동 87 | self.canvas.move(self.rectangle, base_action[0], base_action[1]) 88 | # 에이전트(빨간 네모)를 가장 상위로 배치 89 | self.canvas.tag_raise(self.rectangle) 90 | 91 | next_state = self.canvas.coords(self.rectangle) 92 | 93 | # 보상 함수 94 | if next_state == self.canvas.coords(self.circle): 95 | reward = 100 96 | done = True 97 | elif next_state in [self.canvas.coords(self.triangle1), 98 | self.canvas.coords(self.triangle2)]: 99 | reward = -100 100 | done = True 101 | else: 102 | reward = 0 103 | done = False 104 | 105 | next_state = self.coords_to_state(next_state) 106 | 107 | return next_state, reward, done 108 | 109 | def render(self): 110 | time.sleep(0.03) 111 | self.update() 112 | -------------------------------------------------------------------------------- /1-grid-world/3-monte-carlo/mc_agent.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | from collections import defaultdict 4 | from environment import Env 5 | 6 | 7 | # 몬테카를로 에이전트 (모든 에피소드 각각의 샘플로 부터 학습) 8 | class MCAgent: 9 | def __init__(self, actions): 10 | self.width = 5 11 | self.height = 5 12 | self.actions = actions 13 | self.learning_rate = 0.01 14 | self.discount_factor = 0.9 15 | self.epsilon = 0.1 16 | self.samples = [] 17 | self.value_table = defaultdict(float) 18 | 19 | # 메모리에 샘플을 추가 20 | def save_sample(self, state, reward, done): 21 | self.samples.append([state, reward, done]) 22 | 23 | # 모든 에피소드에서 에이전트가 방문한 상태의 큐 함수를 업데이트 24 | def update(self): 25 | G_t = 0 26 | visit_state = [] 27 | for reward in reversed(self.samples): 28 | state = str(reward[0]) 29 | if state not in visit_state: 30 | visit_state.append(state) 31 | G_t = reward[1] + self.discount_factor * G_t 32 | value = self.value_table[state] 33 | self.value_table[state] = (value + 34 | self.learning_rate * (G_t - value)) 35 | 36 | # 큐 함수에 따라서 행동을 반환 37 | # 입실론 탐욕 정책에 따라서 행동을 반환 38 | def get_action(self, state): 39 | if np.random.rand() < self.epsilon: 40 | # 랜덤 행동 41 | action = np.random.choice(self.actions) 42 | else: 43 | # 큐 함수에 따른 행동 44 | next_state = self.possible_next_state(state) 45 | action = self.arg_max(next_state) 46 | return int(action) 47 | 48 | # 후보가 여럿이면 arg_max를 계산하고 무작위로 하나를 반환 49 | @staticmethod 50 | def arg_max(next_state): 51 | max_index_list = [] 52 | max_value = next_state[0] 53 | for index, value in enumerate(next_state): 54 | if value > max_value: 55 | max_index_list.clear() 56 | max_value = value 57 | max_index_list.append(index) 58 | elif value == max_value: 59 | max_index_list.append(index) 60 | return random.choice(max_index_list) 61 | 62 | # 가능한 다음 모든 상태들을 반환 63 | def possible_next_state(self, state): 64 | col, row = state 65 | next_state = [0.0] * 4 66 | 67 | if row != 0: 68 | next_state[0] = self.value_table[str([col, row - 1])] 69 | else: 70 | next_state[0] = self.value_table[str(state)] 71 | if row != self.height - 1: 72 | next_state[1] = self.value_table[str([col, row + 1])] 73 | else: 74 | next_state[1] = self.value_table[str(state)] 75 | if col != 0: 76 | next_state[2] = self.value_table[str([col - 1, row])] 77 | else: 78 | next_state[2] = self.value_table[str(state)] 79 | if col != self.width - 1: 80 | next_state[3] = self.value_table[str([col + 1, row])] 81 | else: 82 | next_state[3] = self.value_table[str(state)] 83 | 84 | return next_state 85 | 86 | 87 | # 메인 함수 88 | if __name__ == "__main__": 89 | env = Env() 90 | agent = MCAgent(actions=list(range(env.n_actions))) 91 | 92 | for episode in range(1000): 93 | state = env.reset() 94 | action = agent.get_action(state) 95 | 96 | while True: 97 | env.render() 98 | 99 | # 다음 상태로 이동 100 | # 보상은 숫자이고, 완료 여부는 boolean 101 | next_state, reward, done = env.step(action) 102 | agent.save_sample(next_state, reward, done) 103 | 104 | # 다음 행동 받아옴 105 | action = agent.get_action(next_state) 106 | 107 | # 에피소드가 완료됐을 때, 큐 함수 업데이트 108 | if done: 109 | agent.update() 110 | agent.samples.clear() 111 | break 112 | -------------------------------------------------------------------------------- /1-grid-world/4-sarsa/.python-version: -------------------------------------------------------------------------------- 1 | 3.5.0 2 | -------------------------------------------------------------------------------- /1-grid-world/4-sarsa/environment.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | import tkinter as tk 4 | from PIL import ImageTk, Image 5 | 6 | np.random.seed(1) 7 | PhotoImage = ImageTk.PhotoImage 8 | UNIT = 100 # 필셀 수 9 | HEIGHT = 5 # 그리드 월드 가로 10 | WIDTH = 5 # 그리드 월드 세로 11 | 12 | 13 | class Env(tk.Tk): 14 | def __init__(self): 15 | super(Env, self).__init__() 16 | self.action_space = ['u', 'd', 'l', 'r'] 17 | self.n_actions = len(self.action_space) 18 | self.title('SARSA') 19 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT)) 20 | self.shapes = self.load_images() 21 | self.canvas = self._build_canvas() 22 | self.texts = [] 23 | 24 | def _build_canvas(self): 25 | canvas = tk.Canvas(self, bg='white', 26 | height=HEIGHT * UNIT, 27 | width=WIDTH * UNIT) 28 | # 그리드 생성 29 | for c in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 30 | x0, y0, x1, y1 = c, 0, c, HEIGHT * UNIT 31 | canvas.create_line(x0, y0, x1, y1) 32 | for r in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 33 | x0, y0, x1, y1 = 0, r, HEIGHT * UNIT, r 34 | canvas.create_line(x0, y0, x1, y1) 35 | 36 | # 캔버스에 이미지 추가 37 | self.rectangle = canvas.create_image(50, 50, image=self.shapes[0]) 38 | self.triangle1 = canvas.create_image(250, 150, image=self.shapes[1]) 39 | self.triangle2 = canvas.create_image(150, 250, image=self.shapes[1]) 40 | self.circle = canvas.create_image(250, 250, image=self.shapes[2]) 41 | 42 | canvas.pack() 43 | 44 | return canvas 45 | 46 | def load_images(self): 47 | rectangle = PhotoImage( 48 | Image.open("../img/rectangle.png").resize((65, 65))) 49 | triangle = PhotoImage( 50 | Image.open("../img/triangle.png").resize((65, 65))) 51 | circle = PhotoImage( 52 | Image.open("../img/circle.png").resize((65, 65))) 53 | 54 | return rectangle, triangle, circle 55 | 56 | def text_value(self, row, col, contents, action, font='Helvetica', size=10, 57 | style='normal', anchor="nw"): 58 | if action == 0: 59 | origin_x, origin_y = 7, 42 60 | elif action == 1: 61 | origin_x, origin_y = 85, 42 62 | elif action == 2: 63 | origin_x, origin_y = 42, 5 64 | else: 65 | origin_x, origin_y = 42, 77 66 | 67 | x, y = origin_y + (UNIT * col), origin_x + (UNIT * row) 68 | font = (font, str(size), style) 69 | text = self.canvas.create_text(x, y, fill="black", text=contents, 70 | font=font, anchor=anchor) 71 | return self.texts.append(text) 72 | 73 | def print_value_all(self, q_table): 74 | for i in self.texts: 75 | self.canvas.delete(i) 76 | self.texts.clear() 77 | for x in range(HEIGHT): 78 | for y in range(WIDTH): 79 | for action in range(0, 4): 80 | state = [x, y] 81 | if str(state) in q_table.keys(): 82 | temp = q_table[str(state)][action] 83 | self.text_value(y, x, round(temp, 2), action) 84 | 85 | def coords_to_state(self, coords): 86 | x = int((coords[0] - 50) / 100) 87 | y = int((coords[1] - 50) / 100) 88 | return [x, y] 89 | 90 | def reset(self): 91 | self.update() 92 | time.sleep(0.5) 93 | x, y = self.canvas.coords(self.rectangle) 94 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 95 | self.render() 96 | return self.coords_to_state(self.canvas.coords(self.rectangle)) 97 | 98 | def step(self, action): 99 | state = self.canvas.coords(self.rectangle) 100 | base_action = np.array([0, 0]) 101 | self.render() 102 | 103 | if action == 0: # 상 104 | if state[1] > UNIT: 105 | base_action[1] -= UNIT 106 | elif action == 1: # 하 107 | if state[1] < (HEIGHT - 1) * UNIT: 108 | base_action[1] += UNIT 109 | elif action == 2: # 좌 110 | if state[0] > UNIT: 111 | base_action[0] -= UNIT 112 | elif action == 3: # 우 113 | if state[0] < (WIDTH - 1) * UNIT: 114 | base_action[0] += UNIT 115 | 116 | # 에이전트 이동 117 | self.canvas.move(self.rectangle, base_action[0], base_action[1]) 118 | # 에이전트(빨간 네모)를 가장 상위로 배치 119 | self.canvas.tag_raise(self.rectangle) 120 | next_state = self.canvas.coords(self.rectangle) 121 | 122 | # 보상 함수 123 | if next_state == self.canvas.coords(self.circle): 124 | reward = 100 125 | done = True 126 | elif next_state in [self.canvas.coords(self.triangle1), 127 | self.canvas.coords(self.triangle2)]: 128 | reward = -100 129 | done = True 130 | else: 131 | reward = 0 132 | done = False 133 | 134 | next_state = self.coords_to_state(next_state) 135 | 136 | 137 | 138 | return next_state, reward, done 139 | 140 | def render(self): 141 | time.sleep(0.03) 142 | self.update() 143 | -------------------------------------------------------------------------------- /1-grid-world/4-sarsa/sarsa_agent.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | from collections import defaultdict 4 | from environment import Env 5 | 6 | 7 | class SARSAgent: 8 | def __init__(self, actions): 9 | self.actions = actions 10 | self.learning_rate = 0.01 11 | self.discount_factor = 0.9 12 | self.epsilon = 0.1 13 | self.q_table = defaultdict(lambda: [0.0, 0.0, 0.0, 0.0]) 14 | 15 | # 의 샘플로부터 큐함수를 업데이트 16 | def learn(self, state, action, reward, next_state, next_action): 17 | current_q = self.q_table[state][action] 18 | next_state_q = self.q_table[next_state][next_action] 19 | new_q = (current_q + self.learning_rate * 20 | (reward + self.discount_factor * next_state_q - current_q)) 21 | self.q_table[state][action] = new_q 22 | 23 | # 입실론 탐욕 정책에 따라서 행동을 반환 24 | def get_action(self, state): 25 | if np.random.rand() < self.epsilon: 26 | # 무작위 행동 반환 27 | action = np.random.choice(self.actions) 28 | else: 29 | # 큐함수에 따른 행동 반환 30 | state_action = self.q_table[state] 31 | action = self.arg_max(state_action) 32 | return action 33 | 34 | @staticmethod 35 | def arg_max(state_action): 36 | max_index_list = [] 37 | max_value = state_action[0] 38 | for index, value in enumerate(state_action): 39 | if value > max_value: 40 | max_index_list.clear() 41 | max_value = value 42 | max_index_list.append(index) 43 | elif value == max_value: 44 | max_index_list.append(index) 45 | return random.choice(max_index_list) 46 | 47 | if __name__ == "__main__": 48 | env = Env() 49 | agent = SARSAgent(actions=list(range(env.n_actions))) 50 | 51 | for episode in range(1000): 52 | # 게임 환경과 상태를 초기화 53 | state = env.reset() 54 | # 현재 상태에 대한 행동을 선택 55 | action = agent.get_action(str(state)) 56 | 57 | while True: 58 | env.render() 59 | 60 | # 행동을 위한 후 다음상태 보상 에피소드의 종료 여부를 받아옴 61 | next_state, reward, done = env.step(action) 62 | # 다음 상태에서의 다음 행동 선택 63 | next_action = agent.get_action(str(next_state)) 64 | 65 | # 로 큐함수를 업데이트 66 | agent.learn(str(state), action, reward, str(next_state), next_action) 67 | 68 | state = next_state 69 | action = next_action 70 | 71 | # 모든 큐함수를 화면에 표시 72 | env.print_value_all(agent.q_table) 73 | 74 | if done: 75 | break 76 | 77 | -------------------------------------------------------------------------------- /1-grid-world/5-q-learning/.python-version: -------------------------------------------------------------------------------- 1 | 3.5.0 2 | -------------------------------------------------------------------------------- /1-grid-world/5-q-learning/environment.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | import tkinter as tk 4 | from PIL import ImageTk, Image 5 | 6 | np.random.seed(1) 7 | PhotoImage = ImageTk.PhotoImage 8 | UNIT = 100 # 픽셀 수 9 | HEIGHT = 5 # 그리드월드 세로 10 | WIDTH = 5 # 그리드월드 가로 11 | 12 | 13 | class Env(tk.Tk): 14 | def __init__(self): 15 | super(Env, self).__init__() 16 | self.action_space = ['u', 'd', 'l', 'r'] 17 | self.n_actions = len(self.action_space) 18 | self.title('Q Learning') 19 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT)) 20 | self.shapes = self.load_images() 21 | self.canvas = self._build_canvas() 22 | self.texts = [] 23 | 24 | def _build_canvas(self): 25 | canvas = tk.Canvas(self, bg='white', 26 | height=HEIGHT * UNIT, 27 | width=WIDTH * UNIT) 28 | # 그리드 생성 29 | for c in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 30 | x0, y0, x1, y1 = c, 0, c, HEIGHT * UNIT 31 | canvas.create_line(x0, y0, x1, y1) 32 | for r in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 33 | x0, y0, x1, y1 = 0, r, HEIGHT * UNIT, r 34 | canvas.create_line(x0, y0, x1, y1) 35 | 36 | # 캔버스에 이미지 추가 37 | self.rectangle = canvas.create_image(50, 50, image=self.shapes[0]) 38 | self.triangle1 = canvas.create_image(250, 150, image=self.shapes[1]) 39 | self.triangle2 = canvas.create_image(150, 250, image=self.shapes[1]) 40 | self.circle = canvas.create_image(250, 250, image=self.shapes[2]) 41 | 42 | canvas.pack() 43 | 44 | return canvas 45 | 46 | def load_images(self): 47 | rectangle = PhotoImage( 48 | Image.open("../img/rectangle.png").resize((65, 65))) 49 | triangle = PhotoImage( 50 | Image.open("../img/triangle.png").resize((65, 65))) 51 | circle = PhotoImage( 52 | Image.open("../img/circle.png").resize((65, 65))) 53 | 54 | return rectangle, triangle, circle 55 | 56 | def text_value(self, row, col, contents, action, font='Helvetica', size=10, 57 | style='normal', anchor="nw"): 58 | 59 | if action == 0: 60 | origin_x, origin_y = 7, 42 61 | elif action == 1: 62 | origin_x, origin_y = 85, 42 63 | elif action == 2: 64 | origin_x, origin_y = 42, 5 65 | else: 66 | origin_x, origin_y = 42, 77 67 | 68 | x, y = origin_y + (UNIT * col), origin_x + (UNIT * row) 69 | font = (font, str(size), style) 70 | text = self.canvas.create_text(x, y, fill="black", text=contents, 71 | font=font, anchor=anchor) 72 | return self.texts.append(text) 73 | 74 | def print_value_all(self, q_table): 75 | for i in self.texts: 76 | self.canvas.delete(i) 77 | self.texts.clear() 78 | for i in range(HEIGHT): 79 | for j in range(WIDTH): 80 | for action in range(0, 4): 81 | state = [i, j] 82 | if str(state) in q_table.keys(): 83 | temp = q_table[str(state)][action] 84 | self.text_value(j, i, round(temp, 2), action) 85 | 86 | def coords_to_state(self, coords): 87 | x = int((coords[0] - 50) / 100) 88 | y = int((coords[1] - 50) / 100) 89 | return [x, y] 90 | 91 | def state_to_coords(self, state): 92 | x = int(state[0] * 100 + 50) 93 | y = int(state[1] * 100 + 50) 94 | return [x, y] 95 | 96 | def reset(self): 97 | self.update() 98 | time.sleep(0.5) 99 | x, y = self.canvas.coords(self.rectangle) 100 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 101 | self.render() 102 | return self.coords_to_state(self.canvas.coords(self.rectangle)) 103 | 104 | def step(self, action): 105 | state = self.canvas.coords(self.rectangle) 106 | base_action = np.array([0, 0]) 107 | self.render() 108 | 109 | if action == 0: # 상 110 | if state[1] > UNIT: 111 | base_action[1] -= UNIT 112 | elif action == 1: # 하 113 | if state[1] < (HEIGHT - 1) * UNIT: 114 | base_action[1] += UNIT 115 | elif action == 2: # 좌 116 | if state[0] > UNIT: 117 | base_action[0] -= UNIT 118 | elif action == 3: # 우 119 | if state[0] < (WIDTH - 1) * UNIT: 120 | base_action[0] += UNIT 121 | 122 | # 에이전트 이동 123 | self.canvas.move(self.rectangle, base_action[0], base_action[1]) 124 | # 에이전트(빨간 네모)를 가장 상위로 배치 125 | self.canvas.tag_raise(self.rectangle) 126 | next_state = self.canvas.coords(self.rectangle) 127 | 128 | # 보상 함수 129 | if next_state == self.canvas.coords(self.circle): 130 | reward = 100 131 | done = True 132 | elif next_state in [self.canvas.coords(self.triangle1), 133 | self.canvas.coords(self.triangle2)]: 134 | reward = -100 135 | done = True 136 | else: 137 | reward = 0 138 | done = False 139 | 140 | next_state = self.coords_to_state(next_state) 141 | return next_state, reward, done 142 | 143 | def render(self): 144 | time.sleep(0.03) 145 | self.update() 146 | -------------------------------------------------------------------------------- /1-grid-world/5-q-learning/q_learning_agent.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | from environment import Env 4 | from collections import defaultdict 5 | 6 | class QLearningAgent: 7 | def __init__(self, actions): 8 | # 행동 = [0, 1, 2, 3] 순서대로 상, 하, 좌, 우 9 | self.actions = actions 10 | self.learning_rate = 0.01 11 | self.discount_factor = 0.9 12 | self.epsilon = 0.9 13 | self.q_table = defaultdict(lambda: [0.0, 0.0, 0.0, 0.0]) 14 | 15 | # 샘플로부터 큐함수 업데이트 16 | def learn(self, state, action, reward, next_state): 17 | q_1 = self.q_table[state][action] 18 | # 벨만 최적 방정식을 사용한 큐함수의 업데이트 19 | q_2 = reward + self.discount_factor * max(self.q_table[next_state]) 20 | self.q_table[state][action] += self.learning_rate * (q_2 - q_1) 21 | 22 | # 큐함수에 의거하여 입실론 탐욕 정책에 따라서 행동을 반환 23 | def get_action(self, state): 24 | if np.random.rand() < self.epsilon: 25 | # 무작위 행동 반환 26 | action = np.random.choice(self.actions) 27 | else: 28 | # 큐함수에 따른 행동 반환 29 | state_action = self.q_table[state] 30 | action = self.arg_max(state_action) 31 | return action 32 | 33 | @staticmethod 34 | def arg_max(state_action): 35 | max_index_list = [] 36 | max_value = state_action[0] 37 | for index, value in enumerate(state_action): 38 | if value > max_value: 39 | max_index_list.clear() 40 | max_value = value 41 | max_index_list.append(index) 42 | elif value == max_value: 43 | max_index_list.append(index) 44 | return random.choice(max_index_list) 45 | 46 | if __name__ == "__main__": 47 | env = Env() 48 | agent = QLearningAgent(actions=list(range(env.n_actions))) 49 | 50 | for episode in range(1000): 51 | state = env.reset() 52 | 53 | while True: 54 | env.render() 55 | 56 | # 현재 상태에 대한 행동 선택 57 | action = agent.get_action(str(state)) 58 | # 행동을 취한 후 다음 상태, 보상 에피소드의 종료여부를 받아옴 59 | next_state, reward, done = env.step(action) 60 | 61 | # 로 큐함수를 업데이트 62 | agent.learn(str(state), action, reward, str(next_state)) 63 | state = next_state 64 | # 모든 큐함수를 화면에 표시 65 | env.print_value_all(agent.q_table) 66 | 67 | if done: 68 | break 69 | -------------------------------------------------------------------------------- /1-grid-world/6-deep-sarsa/deep_sarsa_agent.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import pylab 3 | import random 4 | import numpy as np 5 | from environment import Env 6 | from keras.layers import Dense 7 | from keras.optimizers import Adam 8 | from keras.models import Sequential 9 | 10 | EPISODES = 1000 11 | 12 | 13 | # 그리드월드 예제에서의 딥살사 에이전트 14 | class DeepSARSAgent: 15 | def __init__(self): 16 | self.load_model = False 17 | # 에이전트가 가능한 모든 행동 정의 18 | self.action_space = [0, 1, 2, 3, 4] 19 | # 상태의 크기와 행동의 크기 정의 20 | self.action_size = len(self.action_space) 21 | self.state_size = 15 22 | self.discount_factor = 0.99 23 | self.learning_rate = 0.001 24 | 25 | self.epsilon = 1. # exploration 26 | self.epsilon_decay = .9999 27 | self.epsilon_min = 0.01 28 | self.model = self.build_model() 29 | 30 | if self.load_model: 31 | self.epsilon = 0.05 32 | self.model.load_weights('./save_model/deep_sarsa_trained.h5') 33 | 34 | # 상태가 입력 큐함수가 출력인 인공신경망 생성 35 | def build_model(self): 36 | model = Sequential() 37 | model.add(Dense(30, input_dim=self.state_size, activation='relu')) 38 | model.add(Dense(30, activation='relu')) 39 | model.add(Dense(self.action_size, activation='linear')) 40 | model.summary() 41 | model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate)) 42 | return model 43 | 44 | # 입실론 탐욕 방법으로 행동 선택 45 | def get_action(self, state): 46 | if np.random.rand() <= self.epsilon: 47 | # 무작위 행동 반환 48 | return random.randrange(self.action_size) 49 | else: 50 | # 모델로부터 행동 산출 51 | state = np.float32(state) 52 | q_values = self.model.predict(state) 53 | return np.argmax(q_values[0]) 54 | 55 | def train_model(self, state, action, reward, next_state, next_action, done): 56 | if self.epsilon > self.epsilon_min: 57 | self.epsilon *= self.epsilon_decay 58 | 59 | state = np.float32(state) 60 | next_state = np.float32(next_state) 61 | target = self.model.predict(state)[0] 62 | # 살사의 큐함수 업데이트 식 63 | if done: 64 | target[action] = reward 65 | else: 66 | target[action] = (reward + self.discount_factor * 67 | self.model.predict(next_state)[0][next_action]) 68 | 69 | # 출력 값 reshape 70 | target = np.reshape(target, [1, 5]) 71 | # 인공신경망 업데이트 72 | self.model.fit(state, target, epochs=1, verbose=0) 73 | 74 | 75 | if __name__ == "__main__": 76 | # 환경과 에이전트 생성 77 | env = Env() 78 | agent = DeepSARSAgent() 79 | 80 | global_step = 0 81 | scores, episodes = [], [] 82 | 83 | for e in range(EPISODES): 84 | done = False 85 | score = 0 86 | state = env.reset() 87 | state = np.reshape(state, [1, 15]) 88 | 89 | while not done: 90 | # env 초기화 91 | global_step += 1 92 | 93 | # 현재 상태에 대한 행동 선택 94 | action = agent.get_action(state) 95 | # 선택한 행동으로 환경에서 한 타임스텝 진행 후 샘플 수집 96 | next_state, reward, done = env.step(action) 97 | next_state = np.reshape(next_state, [1, 15]) 98 | next_action = agent.get_action(next_state) 99 | # 샘플로 모델 학습 100 | agent.train_model(state, action, reward, next_state, next_action, 101 | done) 102 | state = next_state 103 | score += reward 104 | 105 | state = copy.deepcopy(next_state) 106 | 107 | if done: 108 | # 에피소드마다 학습 결과 출력 109 | scores.append(score) 110 | episodes.append(e) 111 | pylab.plot(episodes, scores, 'b') 112 | pylab.savefig("./save_graph/deep_sarsa_.png") 113 | print("episode:", e, " score:", score, "global_step", 114 | global_step, " epsilon:", agent.epsilon) 115 | 116 | # 100 에피소드마다 모델 저장 117 | if e % 100 == 0: 118 | agent.model.save_weights("./save_model/deep_sarsa.h5") 119 | -------------------------------------------------------------------------------- /1-grid-world/6-deep-sarsa/environment.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | import tkinter as tk 4 | from PIL import ImageTk, Image 5 | 6 | PhotoImage = ImageTk.PhotoImage 7 | UNIT = 50 # 픽셀 수 8 | HEIGHT = 5 # 그리드 세로 9 | WIDTH = 5 # 그리드 가로 10 | 11 | np.random.seed(1) 12 | 13 | 14 | class Env(tk.Tk): 15 | def __init__(self): 16 | super(Env, self).__init__() 17 | self.action_space = ['u', 'd', 'l', 'r'] 18 | self.action_size = len(self.action_space) 19 | self.title('DeepSARSA') 20 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT)) 21 | self.shapes = self.load_images() 22 | self.canvas = self._build_canvas() 23 | self.counter = 0 24 | self.rewards = [] 25 | self.goal = [] 26 | # 장애물 설정 27 | self.set_reward([0, 1], -1) 28 | self.set_reward([1, 2], -1) 29 | self.set_reward([2, 3], -1) 30 | # 목표 지점 설정 31 | self.set_reward([4, 4], 1) 32 | 33 | def _build_canvas(self): 34 | canvas = tk.Canvas(self, bg='white', 35 | height=HEIGHT * UNIT, 36 | width=WIDTH * UNIT) 37 | # 그리드 생성 38 | for c in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 39 | x0, y0, x1, y1 = c, 0, c, HEIGHT * UNIT 40 | canvas.create_line(x0, y0, x1, y1) 41 | for r in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 42 | x0, y0, x1, y1 = 0, r, HEIGHT * UNIT, r 43 | canvas.create_line(x0, y0, x1, y1) 44 | 45 | self.rewards = [] 46 | self.goal = [] 47 | # 캔버스에 이미지 추가 48 | x, y = UNIT/2, UNIT/2 49 | self.rectangle = canvas.create_image(x, y, image=self.shapes[0]) 50 | 51 | canvas.pack() 52 | 53 | return canvas 54 | 55 | def load_images(self): 56 | rectangle = PhotoImage( 57 | Image.open("../img/rectangle.png").resize((30, 30))) 58 | triangle = PhotoImage( 59 | Image.open("../img/triangle.png").resize((30, 30))) 60 | circle = PhotoImage( 61 | Image.open("../img/circle.png").resize((30, 30))) 62 | 63 | return rectangle, triangle, circle 64 | 65 | def reset_reward(self): 66 | 67 | for reward in self.rewards: 68 | self.canvas.delete(reward['figure']) 69 | 70 | self.rewards.clear() 71 | self.goal.clear() 72 | self.set_reward([0, 1], -1) 73 | self.set_reward([1, 2], -1) 74 | self.set_reward([2, 3], -1) 75 | 76 | # #goal 77 | self.set_reward([4, 4], 1) 78 | 79 | def set_reward(self, state, reward): 80 | state = [int(state[0]), int(state[1])] 81 | x = int(state[0]) 82 | y = int(state[1]) 83 | temp = {} 84 | if reward > 0: 85 | temp['reward'] = reward 86 | temp['figure'] = self.canvas.create_image((UNIT * x) + UNIT / 2, 87 | (UNIT * y) + UNIT / 2, 88 | image=self.shapes[2]) 89 | 90 | self.goal.append(temp['figure']) 91 | 92 | 93 | elif reward < 0: 94 | temp['direction'] = -1 95 | temp['reward'] = reward 96 | temp['figure'] = self.canvas.create_image((UNIT * x) + UNIT / 2, 97 | (UNIT * y) + UNIT / 2, 98 | image=self.shapes[1]) 99 | 100 | temp['coords'] = self.canvas.coords(temp['figure']) 101 | temp['state'] = state 102 | self.rewards.append(temp) 103 | 104 | # new methods 105 | 106 | def check_if_reward(self, state): 107 | check_list = dict() 108 | check_list['if_goal'] = False 109 | rewards = 0 110 | 111 | for reward in self.rewards: 112 | if reward['state'] == state: 113 | rewards += reward['reward'] 114 | if reward['reward'] == 1: 115 | check_list['if_goal'] = True 116 | 117 | check_list['rewards'] = rewards 118 | 119 | return check_list 120 | 121 | def coords_to_state(self, coords): 122 | x = int((coords[0] - UNIT / 2) / UNIT) 123 | y = int((coords[1] - UNIT / 2) / UNIT) 124 | return [x, y] 125 | 126 | def reset(self): 127 | self.update() 128 | time.sleep(0.5) 129 | x, y = self.canvas.coords(self.rectangle) 130 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 131 | self.reset_reward() 132 | return self.get_state() 133 | 134 | def step(self, action): 135 | self.counter += 1 136 | self.render() 137 | 138 | if self.counter % 2 == 1: 139 | self.rewards = self.move_rewards() 140 | 141 | next_coords = self.move(self.rectangle, action) 142 | check = self.check_if_reward(self.coords_to_state(next_coords)) 143 | done = check['if_goal'] 144 | reward = check['rewards'] 145 | 146 | self.canvas.tag_raise(self.rectangle) 147 | 148 | s_ = self.get_state() 149 | 150 | return s_, reward, done 151 | 152 | def get_state(self): 153 | 154 | location = self.coords_to_state(self.canvas.coords(self.rectangle)) 155 | agent_x = location[0] 156 | agent_y = location[1] 157 | 158 | states = list() 159 | 160 | for reward in self.rewards: 161 | reward_location = reward['state'] 162 | states.append(reward_location[0] - agent_x) 163 | states.append(reward_location[1] - agent_y) 164 | if reward['reward'] < 0: 165 | states.append(-1) 166 | states.append(reward['direction']) 167 | else: 168 | states.append(1) 169 | 170 | return states 171 | 172 | def move_rewards(self): 173 | new_rewards = [] 174 | for temp in self.rewards: 175 | if temp['reward'] == 1: 176 | new_rewards.append(temp) 177 | continue 178 | temp['coords'] = self.move_const(temp) 179 | temp['state'] = self.coords_to_state(temp['coords']) 180 | new_rewards.append(temp) 181 | return new_rewards 182 | 183 | def move_const(self, target): 184 | 185 | s = self.canvas.coords(target['figure']) 186 | 187 | base_action = np.array([0, 0]) 188 | 189 | if s[0] == (WIDTH - 1) * UNIT + UNIT / 2: 190 | target['direction'] = 1 191 | elif s[0] == UNIT / 2: 192 | target['direction'] = -1 193 | 194 | if target['direction'] == -1: 195 | base_action[0] += UNIT 196 | elif target['direction'] == 1: 197 | base_action[0] -= UNIT 198 | 199 | if (target['figure'] is not self.rectangle 200 | and s == [(WIDTH - 1) * UNIT, (HEIGHT - 1) * UNIT]): 201 | base_action = np.array([0, 0]) 202 | 203 | self.canvas.move(target['figure'], base_action[0], base_action[1]) 204 | 205 | s_ = self.canvas.coords(target['figure']) 206 | 207 | return s_ 208 | 209 | def move(self, target, action): 210 | s = self.canvas.coords(target) 211 | 212 | base_action = np.array([0, 0]) 213 | 214 | if action == 0: # 상 215 | if s[1] > UNIT: 216 | base_action[1] -= UNIT 217 | elif action == 1: # 하 218 | if s[1] < (HEIGHT - 1) * UNIT: 219 | base_action[1] += UNIT 220 | elif action == 2: # 우 221 | if s[0] < (WIDTH - 1) * UNIT: 222 | base_action[0] += UNIT 223 | elif action == 3: # 좌 224 | if s[0] > UNIT: 225 | base_action[0] -= UNIT 226 | 227 | self.canvas.move(target, base_action[0], base_action[1]) 228 | 229 | s_ = self.canvas.coords(target) 230 | 231 | return s_ 232 | 233 | def render(self): 234 | # 게임 속도 조정 235 | time.sleep(0.05) 236 | self.update() 237 | -------------------------------------------------------------------------------- /1-grid-world/6-deep-sarsa/save_graph/deep_sarsa_trained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/6-deep-sarsa/save_graph/deep_sarsa_trained.png -------------------------------------------------------------------------------- /1-grid-world/6-deep-sarsa/save_model/deep_sarsa_trained.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/6-deep-sarsa/save_model/deep_sarsa_trained.h5 -------------------------------------------------------------------------------- /1-grid-world/7-reinforce/environment.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | import tkinter as tk 4 | from PIL import ImageTk, Image 5 | 6 | PhotoImage = ImageTk.PhotoImage 7 | UNIT = 50 # 픽셀 수 8 | HEIGHT = 5 # 그리드월드 세로 9 | WIDTH = 5 # 그리드월드 가로 10 | 11 | np.random.seed(1) 12 | 13 | 14 | class Env(tk.Tk): 15 | def __init__(self): 16 | super(Env, self).__init__() 17 | self.action_space = ['u', 'd', 'l', 'r'] 18 | self.action_size = len(self.action_space) 19 | self.title('Reinforce') 20 | self.geometry('{0}x{1}'.format(HEIGHT * UNIT, HEIGHT * UNIT)) 21 | self.shapes = self.load_images() 22 | self.canvas = self._build_canvas() 23 | self.counter = 0 24 | self.rewards = [] 25 | self.goal = [] 26 | # 장애물 설정 27 | self.set_reward([0, 1], -1) 28 | self.set_reward([1, 2], -1) 29 | self.set_reward([2, 3], -1) 30 | # 목표지점 설정 31 | self.set_reward([4, 4], 1) 32 | 33 | def _build_canvas(self): 34 | canvas = tk.Canvas(self, bg='white', 35 | height=HEIGHT * UNIT, 36 | width=WIDTH * UNIT) 37 | # 그리드 생성 38 | for c in range(0, WIDTH * UNIT, UNIT): # 0~400 by 80 39 | x0, y0, x1, y1 = c, 0, c, HEIGHT * UNIT 40 | canvas.create_line(x0, y0, x1, y1) 41 | for r in range(0, HEIGHT * UNIT, UNIT): # 0~400 by 80 42 | x0, y0, x1, y1 = 0, r, HEIGHT * UNIT, r 43 | canvas.create_line(x0, y0, x1, y1) 44 | 45 | self.rewards = [] 46 | self.goal = [] 47 | # 캔버스에 이미지 추가 48 | x, y = UNIT/2, UNIT/2 49 | self.rectangle = canvas.create_image(x, y, image=self.shapes[0]) 50 | 51 | canvas.pack() 52 | 53 | return canvas 54 | 55 | def load_images(self): 56 | rectangle = PhotoImage( 57 | Image.open("../img/rectangle.png").resize((30, 30))) 58 | triangle = PhotoImage( 59 | Image.open("../img/triangle.png").resize((30, 30))) 60 | circle = PhotoImage( 61 | Image.open("../img/circle.png").resize((30, 30))) 62 | 63 | return rectangle, triangle, circle 64 | 65 | def reset_reward(self): 66 | 67 | for reward in self.rewards: 68 | self.canvas.delete(reward['figure']) 69 | 70 | self.rewards.clear() 71 | self.goal.clear() 72 | self.set_reward([0, 1], -1) 73 | self.set_reward([1, 2], -1) 74 | self.set_reward([2, 3], -1) 75 | 76 | # 목표 지점 77 | self.set_reward([4, 4], 1) 78 | 79 | def set_reward(self, state, reward): 80 | state = [int(state[0]), int(state[1])] 81 | x = int(state[0]) 82 | y = int(state[1]) 83 | temp = {} 84 | if reward > 0: 85 | temp['reward'] = reward 86 | temp['figure'] = self.canvas.create_image((UNIT * x) + UNIT / 2, 87 | (UNIT * y) + UNIT / 2, 88 | image=self.shapes[2]) 89 | 90 | self.goal.append(temp['figure']) 91 | 92 | 93 | elif reward < 0: 94 | temp['direction'] = -1 95 | temp['reward'] = reward 96 | temp['figure'] = self.canvas.create_image((UNIT * x) + UNIT / 2, 97 | (UNIT * y) + UNIT / 2, 98 | image=self.shapes[1]) 99 | 100 | temp['coords'] = self.canvas.coords(temp['figure']) 101 | temp['state'] = state 102 | self.rewards.append(temp) 103 | 104 | def check_if_reward(self, state): 105 | check_list = dict() 106 | check_list['if_goal'] = False 107 | rewards = 0 108 | 109 | for reward in self.rewards: 110 | if reward['state'] == state: 111 | rewards += reward['reward'] 112 | if reward['reward'] > 0: 113 | check_list['if_goal'] = True 114 | 115 | check_list['rewards'] = rewards 116 | 117 | return check_list 118 | 119 | def coords_to_state(self, coords): 120 | x = int((coords[0] - UNIT / 2) / UNIT) 121 | y = int((coords[1] - UNIT / 2) / UNIT) 122 | return [x, y] 123 | 124 | def reset(self): 125 | self.update() 126 | x, y = self.canvas.coords(self.rectangle) 127 | self.canvas.move(self.rectangle, UNIT / 2 - x, UNIT / 2 - y) 128 | self.reset_reward() 129 | return self.get_state() 130 | 131 | def step(self, action): 132 | self.counter += 1 133 | self.render() 134 | 135 | if self.counter % 2 == 1: 136 | self.rewards = self.move_rewards() 137 | 138 | next_coords = self.move(self.rectangle, action) 139 | check = self.check_if_reward(self.coords_to_state(next_coords)) 140 | done = check['if_goal'] 141 | reward = check['rewards'] 142 | reward -= 0.1 143 | self.canvas.tag_raise(self.rectangle) 144 | 145 | s_ = self.get_state() 146 | 147 | return s_, reward, done 148 | 149 | def get_state(self): 150 | 151 | location = self.coords_to_state(self.canvas.coords(self.rectangle)) 152 | agent_x = location[0] 153 | agent_y = location[1] 154 | 155 | states = list() 156 | 157 | for reward in self.rewards: 158 | reward_location = reward['state'] 159 | states.append(reward_location[0] - agent_x) 160 | states.append(reward_location[1] - agent_y) 161 | if reward['reward'] < 0: 162 | states.append(-1) 163 | states.append(reward['direction']) 164 | else: 165 | states.append(1) 166 | 167 | return states 168 | 169 | def move_rewards(self): 170 | new_rewards = [] 171 | for temp in self.rewards: 172 | if temp['reward'] > 0: 173 | new_rewards.append(temp) 174 | continue 175 | temp['coords'] = self.move_const(temp) 176 | temp['state'] = self.coords_to_state(temp['coords']) 177 | new_rewards.append(temp) 178 | return new_rewards 179 | 180 | def move_const(self, target): 181 | 182 | s = self.canvas.coords(target['figure']) 183 | 184 | base_action = np.array([0, 0]) 185 | 186 | if s[0] == (WIDTH - 1) * UNIT + UNIT / 2: 187 | target['direction'] = 1 188 | elif s[0] == UNIT / 2: 189 | target['direction'] = -1 190 | 191 | if target['direction'] == -1: 192 | base_action[0] += UNIT 193 | elif target['direction'] == 1: 194 | base_action[0] -= UNIT 195 | 196 | if (target['figure'] is not self.rectangle 197 | and s == [(WIDTH - 1) * UNIT, (HEIGHT - 1) * UNIT]): 198 | base_action = np.array([0, 0]) 199 | 200 | self.canvas.move(target['figure'], base_action[0], base_action[1]) 201 | 202 | s_ = self.canvas.coords(target['figure']) 203 | 204 | return s_ 205 | 206 | def move(self, target, action): 207 | s = self.canvas.coords(target) 208 | 209 | base_action = np.array([0, 0]) 210 | 211 | if action == 0: # 상 212 | if s[1] > UNIT: 213 | base_action[1] -= UNIT 214 | elif action == 1: # 하 215 | if s[1] < (HEIGHT - 1) * UNIT: 216 | base_action[1] += UNIT 217 | elif action == 2: # 우 218 | if s[0] < (WIDTH - 1) * UNIT: 219 | base_action[0] += UNIT 220 | elif action == 3: # 좌 221 | if s[0] > UNIT: 222 | base_action[0] -= UNIT 223 | 224 | self.canvas.move(target, base_action[0], base_action[1]) 225 | 226 | s_ = self.canvas.coords(target) 227 | 228 | return s_ 229 | 230 | def render(self): 231 | # 게임 속도 조정 232 | time.sleep(0.07) 233 | self.update() 234 | -------------------------------------------------------------------------------- /1-grid-world/7-reinforce/reinforce_agent.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import pylab 3 | import numpy as np 4 | from environment import Env 5 | from keras.layers import Dense 6 | from keras.optimizers import Adam 7 | from keras.models import Sequential 8 | from keras import backend as K 9 | 10 | EPISODES = 2500 11 | 12 | # 그리드월드 예제에서의 REINFORCE 에이전트 13 | class ReinforceAgent: 14 | def __init__(self): 15 | self.load_model = False 16 | # 가능한 모든 행동 정의 17 | self.action_space = [0, 1, 2, 3, 4] 18 | # 상태와 행동의 크기 정의 19 | self.action_size = len(self.action_space) 20 | self.state_size = 15 21 | self.discount_factor = 0.99 22 | self.learning_rate = 0.001 23 | 24 | self.model = self.build_model() 25 | self.optimizer = self.optimizer() 26 | self.states, self.actions, self.rewards = [], [], [] 27 | 28 | if self.load_model: 29 | self.model.load_weights('./save_model/reinforce_trained.h5') 30 | 31 | # 상태가 입력, 각 행동의 확률이 출력인 인공신경망 생성 32 | def build_model(self): 33 | model = Sequential() 34 | model.add(Dense(24, input_dim=self.state_size, activation='relu')) 35 | model.add(Dense(24, activation='relu')) 36 | model.add(Dense(self.action_size, activation='softmax')) 37 | model.summary() 38 | return model 39 | 40 | # 정책신경망을 업데이트 하기 위한 오류함수와 훈련함수의 생성 41 | def optimizer(self): 42 | action = K.placeholder(shape=[None, 5]) 43 | discounted_rewards = K.placeholder(shape=[None, ]) 44 | 45 | # 크로스 엔트로피 오류함수 계산 46 | action_prob = K.sum(action * self.model.output, axis=1) 47 | cross_entropy = K.log(action_prob) * discounted_rewards 48 | loss = -K.sum(cross_entropy) 49 | 50 | # 정책신경망을 업데이트하는 훈련함수 생성 51 | optimizer = Adam(lr=self.learning_rate) 52 | updates = optimizer.get_updates(self.model.trainable_weights,[], 53 | loss) 54 | train = K.function([self.model.input, action, discounted_rewards], [], 55 | updates=updates) 56 | 57 | return train 58 | 59 | # 정책신경망으로 행동 선택 60 | def get_action(self, state): 61 | policy = self.model.predict(state)[0] 62 | return np.random.choice(self.action_size, 1, p=policy)[0] 63 | 64 | # 반환값 계산 65 | def discount_rewards(self, rewards): 66 | discounted_rewards = np.zeros_like(rewards) 67 | running_add = 0 68 | for t in reversed(range(0, len(rewards))): 69 | running_add = running_add * self.discount_factor + rewards[t] 70 | discounted_rewards[t] = running_add 71 | return discounted_rewards 72 | 73 | # 한 에피소드 동안의 상태, 행동, 보상을 저장 74 | def append_sample(self, state, action, reward): 75 | self.states.append(state[0]) 76 | self.rewards.append(reward) 77 | act = np.zeros(self.action_size) 78 | act[action] = 1 79 | self.actions.append(act) 80 | 81 | # 정책신경망 업데이트 82 | def train_model(self): 83 | discounted_rewards = np.float32(self.discount_rewards(self.rewards)) 84 | discounted_rewards -= np.mean(discounted_rewards) 85 | discounted_rewards /= np.std(discounted_rewards) 86 | 87 | self.optimizer([self.states, self.actions, discounted_rewards]) 88 | self.states, self.actions, self.rewards = [], [], [] 89 | 90 | 91 | if __name__ == "__main__": 92 | # 환경과 에이전트의 생성 93 | env = Env() 94 | agent = ReinforceAgent() 95 | 96 | global_step = 0 97 | scores, episodes = [], [] 98 | 99 | for e in range(EPISODES): 100 | done = False 101 | score = 0 102 | # env 초기화 103 | state = env.reset() 104 | state = np.reshape(state, [1, 15]) 105 | 106 | while not done: 107 | global_step += 1 108 | # 현재 상태에 대한 행동 선택 109 | action = agent.get_action(state) 110 | # 선택한 행동으로 환경에서 한 타임스탭 진행 후 샘플 수집 111 | next_state, reward, done = env.step(action) 112 | next_state = np.reshape(next_state, [1, 15]) 113 | 114 | agent.append_sample(state, action, reward) 115 | score += reward 116 | state = copy.deepcopy(next_state) 117 | 118 | if done: 119 | # 에피소드마다 정책신경망 업데이트 120 | agent.train_model() 121 | scores.append(score) 122 | episodes.append(e) 123 | score = round(score,2) 124 | print("episode:", e, " score:", score, " time_step:", 125 | global_step) 126 | 127 | # 100 에피소드마다 학습 결과 출력 및 모델 저장 128 | if e % 100 == 0: 129 | pylab.plot(episodes, scores, 'b') 130 | pylab.savefig("./save_graph/reinforce.png") 131 | agent.model.save_weights("./save_model/reinforce.h5") 132 | -------------------------------------------------------------------------------- /1-grid-world/7-reinforce/save_graph/reinforce_trained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/7-reinforce/save_graph/reinforce_trained.png -------------------------------------------------------------------------------- /1-grid-world/7-reinforce/save_model/reinforce_trained.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/7-reinforce/save_model/reinforce_trained.h5 -------------------------------------------------------------------------------- /1-grid-world/README.md: -------------------------------------------------------------------------------- 1 | # Grid World with Reinforcement Learning 2 | This is Grid World example that we made for the simple algorithm test 3 | The game is simple. The red rectangle must arrive in the circle, avoiding triangle. 4 | 5 |

6 | 7 |
8 | 9 | 10 | 11 | ## Dynamic Programming 12 | **1. Policy Iteration** 13 | 14 | **2. Value Iteration** 15 | 16 |
17 | 18 | ## Reinforcement Learning Fundamental Algorithms 19 | **3. Monte-Carlo** 20 | 21 | **4. SARSA** 22 | 23 | **5. Q-Learning** 24 | 25 |
26 | 27 | ## Futher Reinforcement Learning Algorithms 28 | >we have changed Grid World so the obstacles are moving. To solve this problem, we have to use function approximator. 29 | We used Neural Network as function approximator 30 | 31 |

32 | 33 |
34 | 35 | **6. DQN** 36 | 37 | **7. Policy Gradient** 38 | 39 | 40 | -------------------------------------------------------------------------------- /1-grid-world/gridworld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/gridworld.png -------------------------------------------------------------------------------- /1-grid-world/img/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/circle.png -------------------------------------------------------------------------------- /1-grid-world/img/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/down.png -------------------------------------------------------------------------------- /1-grid-world/img/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/left.png -------------------------------------------------------------------------------- /1-grid-world/img/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/rectangle.png -------------------------------------------------------------------------------- /1-grid-world/img/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/right.png -------------------------------------------------------------------------------- /1-grid-world/img/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/triangle.png -------------------------------------------------------------------------------- /1-grid-world/img/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/1-grid-world/img/up.png -------------------------------------------------------------------------------- /2-cartpole/1-dqn/cartpole_dqn.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import gym 3 | import pylab 4 | import random 5 | import numpy as np 6 | from collections import deque 7 | from keras.layers import Dense 8 | from keras.optimizers import Adam 9 | from keras.models import Sequential 10 | 11 | EPISODES = 300 12 | 13 | 14 | # 카트폴 예제에서의 DQN 에이전트 15 | class DQNAgent: 16 | def __init__(self, state_size, action_size): 17 | self.render = False 18 | self.load_model = False 19 | 20 | # 상태와 행동의 크기 정의 21 | self.state_size = state_size 22 | self.action_size = action_size 23 | 24 | # DQN 하이퍼파라미터 25 | self.discount_factor = 0.99 26 | self.learning_rate = 0.001 27 | self.epsilon = 1.0 28 | self.epsilon_decay = 0.999 29 | self.epsilon_min = 0.01 30 | self.batch_size = 64 31 | self.train_start = 1000 32 | 33 | # 리플레이 메모리, 최대 크기 2000 34 | self.memory = deque(maxlen=2000) 35 | 36 | # 모델과 타깃 모델 생성 37 | self.model = self.build_model() 38 | self.target_model = self.build_model() 39 | 40 | # 타깃 모델 초기화 41 | self.update_target_model() 42 | 43 | if self.load_model: 44 | self.model.load_weights("./save_model/cartpole_dqn_trained.h5") 45 | 46 | # 상태가 입력, 큐함수가 출력인 인공신경망 생성 47 | def build_model(self): 48 | model = Sequential() 49 | model.add(Dense(24, input_dim=self.state_size, activation='relu', 50 | kernel_initializer='he_uniform')) 51 | model.add(Dense(24, activation='relu', 52 | kernel_initializer='he_uniform')) 53 | model.add(Dense(self.action_size, activation='linear', 54 | kernel_initializer='he_uniform')) 55 | model.summary() 56 | model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate)) 57 | return model 58 | 59 | # 타깃 모델을 모델의 가중치로 업데이트 60 | def update_target_model(self): 61 | self.target_model.set_weights(self.model.get_weights()) 62 | 63 | # 입실론 탐욕 정책으로 행동 선택 64 | def get_action(self, state): 65 | if np.random.rand() <= self.epsilon: 66 | return random.randrange(self.action_size) 67 | else: 68 | q_value = self.model.predict(state) 69 | return np.argmax(q_value[0]) 70 | 71 | # 샘플 을 리플레이 메모리에 저장 72 | def append_sample(self, state, action, reward, next_state, done): 73 | self.memory.append((state, action, reward, next_state, done)) 74 | 75 | # 리플레이 메모리에서 무작위로 추출한 배치로 모델 학습 76 | def train_model(self): 77 | if self.epsilon > self.epsilon_min: 78 | self.epsilon *= self.epsilon_decay 79 | 80 | # 메모리에서 배치 크기만큼 무작위로 샘플 추출 81 | mini_batch = random.sample(self.memory, self.batch_size) 82 | 83 | states = np.zeros((self.batch_size, self.state_size)) 84 | next_states = np.zeros((self.batch_size, self.state_size)) 85 | actions, rewards, dones = [], [], [] 86 | 87 | for i in range(self.batch_size): 88 | states[i] = mini_batch[i][0] 89 | actions.append(mini_batch[i][1]) 90 | rewards.append(mini_batch[i][2]) 91 | next_states[i] = mini_batch[i][3] 92 | dones.append(mini_batch[i][4]) 93 | 94 | # 현재 상태에 대한 모델의 큐함수 95 | # 다음 상태에 대한 타깃 모델의 큐함수 96 | target = self.model.predict(states) 97 | target_val = self.target_model.predict(next_states) 98 | 99 | # 벨만 최적 방정식을 이용한 업데이트 타깃 100 | for i in range(self.batch_size): 101 | if dones[i]: 102 | target[i][actions[i]] = rewards[i] 103 | else: 104 | target[i][actions[i]] = rewards[i] + self.discount_factor * ( 105 | np.amax(target_val[i])) 106 | 107 | self.model.fit(states, target, batch_size=self.batch_size, 108 | epochs=1, verbose=0) 109 | 110 | 111 | if __name__ == "__main__": 112 | # CartPole-v1 환경, 최대 타임스텝 수가 500 113 | env = gym.make('CartPole-v1') 114 | state_size = env.observation_space.shape[0] 115 | action_size = env.action_space.n 116 | 117 | # DQN 에이전트 생성 118 | agent = DQNAgent(state_size, action_size) 119 | 120 | scores, episodes = [], [] 121 | 122 | for e in range(EPISODES): 123 | done = False 124 | score = 0 125 | # env 초기화 126 | state = env.reset() 127 | state = np.reshape(state, [1, state_size]) 128 | 129 | while not done: 130 | if agent.render: 131 | env.render() 132 | 133 | # 현재 상태로 행동을 선택 134 | action = agent.get_action(state) 135 | # 선택한 행동으로 환경에서 한 타임스텝 진행 136 | next_state, reward, done, info = env.step(action) 137 | next_state = np.reshape(next_state, [1, state_size]) 138 | # 에피소드가 중간에 끝나면 -100 보상 139 | reward = reward if not done or score == 499 else -100 140 | 141 | # 리플레이 메모리에 샘플 저장 142 | agent.append_sample(state, action, reward, next_state, done) 143 | # 매 타임스텝마다 학습 144 | if len(agent.memory) >= agent.train_start: 145 | agent.train_model() 146 | 147 | score += reward 148 | state = next_state 149 | 150 | if done: 151 | # 각 에피소드마다 타깃 모델을 모델의 가중치로 업데이트 152 | agent.update_target_model() 153 | 154 | score = score if score == 500 else score + 100 155 | # 에피소드마다 학습 결과 출력 156 | scores.append(score) 157 | episodes.append(e) 158 | pylab.plot(episodes, scores, 'b') 159 | pylab.savefig("./save_graph/cartpole_dqn.png") 160 | print("episode:", e, " score:", score, " memory length:", 161 | len(agent.memory), " epsilon:", agent.epsilon) 162 | 163 | # 이전 10개 에피소드의 점수 평균이 490보다 크면 학습 중단 164 | if np.mean(scores[-min(10, len(scores)):]) > 490: 165 | agent.model.save_weights("./save_model/cartpole_dqn.h5") 166 | sys.exit() 167 | -------------------------------------------------------------------------------- /2-cartpole/1-dqn/save_graph/cartpole_dqn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/2-cartpole/1-dqn/save_graph/cartpole_dqn.png -------------------------------------------------------------------------------- /2-cartpole/1-dqn/save_model/cartpole_dqn_trained.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/2-cartpole/1-dqn/save_model/cartpole_dqn_trained.h5 -------------------------------------------------------------------------------- /2-cartpole/2-actor-critic/cartpole_a2c.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import gym 3 | import pylab 4 | import numpy as np 5 | from keras.layers import Dense 6 | from keras.models import Sequential 7 | from keras.optimizers import Adam 8 | from keras import backend as K 9 | 10 | EPISODES = 1000 11 | 12 | 13 | # 카트폴 예제에서의 액터-크리틱(A2C) 에이전트 14 | class A2CAgent: 15 | def __init__(self, state_size, action_size): 16 | self.render = False 17 | self.load_model = False 18 | # 상태와 행동의 크기 정의 19 | self.state_size = state_size 20 | self.action_size = action_size 21 | self.value_size = 1 22 | 23 | # 액터-크리틱 하이퍼파라미터 24 | self.discount_factor = 0.99 25 | self.actor_lr = 0.001 26 | self.critic_lr = 0.005 27 | 28 | # 정책신경망과 가치신경망 생성 29 | self.actor = self.build_actor() 30 | self.critic = self.build_critic() 31 | self.actor_updater = self.actor_optimizer() 32 | self.critic_updater = self.critic_optimizer() 33 | 34 | if self.load_model: 35 | self.actor.load_weights("./save_model/cartpole_actor_trained.h5") 36 | self.critic.load_weights("./save_model/cartpole_critic_trained.h5") 37 | 38 | # actor: 상태를 받아 각 행동의 확률을 계산 39 | def build_actor(self): 40 | actor = Sequential() 41 | actor.add(Dense(24, input_dim=self.state_size, activation='relu', 42 | kernel_initializer='he_uniform')) 43 | actor.add(Dense(self.action_size, activation='softmax', 44 | kernel_initializer='he_uniform')) 45 | actor.summary() 46 | return actor 47 | 48 | # critic: 상태를 받아서 상태의 가치를 계산 49 | def build_critic(self): 50 | critic = Sequential() 51 | critic.add(Dense(24, input_dim=self.state_size, activation='relu', 52 | kernel_initializer='he_uniform')) 53 | critic.add(Dense(24, input_dim=self.state_size, activation='relu', 54 | kernel_initializer='he_uniform')) 55 | critic.add(Dense(self.value_size, activation='linear', 56 | kernel_initializer='he_uniform')) 57 | critic.summary() 58 | return critic 59 | 60 | # 정책신경망의 출력을 받아 확률적으로 행동을 선택 61 | def get_action(self, state): 62 | policy = self.actor.predict(state, batch_size=1).flatten() 63 | return np.random.choice(self.action_size, 1, p=policy)[0] 64 | 65 | # 정책신경망을 업데이트하는 함수 66 | def actor_optimizer(self): 67 | action = K.placeholder(shape=[None, self.action_size]) 68 | advantage = K.placeholder(shape=[None, ]) 69 | 70 | action_prob = K.sum(action * self.actor.output, axis=1) 71 | cross_entropy = K.log(action_prob) * advantage 72 | loss = -K.sum(cross_entropy) 73 | 74 | optimizer = Adam(lr=self.actor_lr) 75 | updates = optimizer.get_updates(self.actor.trainable_weights, [], loss) 76 | train = K.function([self.actor.input, action, advantage], [], 77 | updates=updates) 78 | return train 79 | 80 | # 가치신경망을 업데이트하는 함수 81 | def critic_optimizer(self): 82 | target = K.placeholder(shape=[None, ]) 83 | 84 | loss = K.mean(K.square(target - self.critic.output)) 85 | 86 | optimizer = Adam(lr=self.critic_lr) 87 | updates = optimizer.get_updates(self.critic.trainable_weights, [], loss) 88 | train = K.function([self.critic.input, target], [], updates=updates) 89 | 90 | return train 91 | 92 | # 각 타임스텝마다 정책신경망과 가치신경망을 업데이트 93 | def train_model(self, state, action, reward, next_state, done): 94 | value = self.critic.predict(state)[0] 95 | next_value = self.critic.predict(next_state)[0] 96 | 97 | act = np.zeros([1, self.action_size]) 98 | act[0][action] = 1 99 | 100 | # 벨만 기대 방정식를 이용한 어드벤티지와 업데이트 타깃 101 | if done: 102 | advantage = reward - value 103 | target = [reward] 104 | else: 105 | advantage = (reward + self.discount_factor * next_value) - value 106 | target = reward + self.discount_factor * next_value 107 | 108 | self.actor_updater([state, act, advantage]) 109 | self.critic_updater([state, target]) 110 | 111 | 112 | if __name__ == "__main__": 113 | # CartPole-v1 환경, 최대 타임스텝 수가 500 114 | env = gym.make('CartPole-v1') 115 | # 환경으로부터 상태와 행동의 크기를 받아옴 116 | state_size = env.observation_space.shape[0] 117 | action_size = env.action_space.n 118 | 119 | # 액터-크리틱(A2C) 에이전트 생성 120 | agent = A2CAgent(state_size, action_size) 121 | 122 | scores, episodes = [], [] 123 | 124 | for e in range(EPISODES): 125 | done = False 126 | score = 0 127 | state = env.reset() 128 | state = np.reshape(state, [1, state_size]) 129 | 130 | while not done: 131 | if agent.render: 132 | env.render() 133 | 134 | action = agent.get_action(state) 135 | next_state, reward, done, info = env.step(action) 136 | next_state = np.reshape(next_state, [1, state_size]) 137 | # 에피소드가 중간에 끝나면 -100 보상 138 | reward = reward if not done or score == 499 else -100 139 | 140 | agent.train_model(state, action, reward, next_state, done) 141 | 142 | score += reward 143 | state = next_state 144 | 145 | if done: 146 | # 에피소드마다 학습 결과 출력 147 | score = score if score == 500.0 else score + 100 148 | scores.append(score) 149 | episodes.append(e) 150 | pylab.plot(episodes, scores, 'b') 151 | pylab.savefig("./save_graph/cartpole_a2c.png") 152 | print("episode:", e, " score:", score) 153 | 154 | # 이전 10개 에피소드의 점수 평균이 490보다 크면 학습 중단 155 | if np.mean(scores[-min(10, len(scores)):]) > 490: 156 | agent.actor.save_weights("./save_model/cartpole_actor.h5") 157 | agent.critic.save_weights( 158 | "./save_model/cartpole_critic.h5") 159 | sys.exit() 160 | -------------------------------------------------------------------------------- /2-cartpole/2-actor-critic/save_graph/cartpole_a2c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/2-cartpole/2-actor-critic/save_graph/cartpole_a2c.png -------------------------------------------------------------------------------- /2-cartpole/2-actor-critic/save_model/cartpole_actor_trained.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/2-cartpole/2-actor-critic/save_model/cartpole_actor_trained.h5 -------------------------------------------------------------------------------- /2-cartpole/2-actor-critic/save_model/cartpole_critic_trained.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/2-cartpole/2-actor-critic/save_model/cartpole_critic_trained.h5 -------------------------------------------------------------------------------- /2-cartpole/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Keon Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /2-cartpole/README.md: -------------------------------------------------------------------------------- 1 | # OpenAI gym Cartpole 2 | 3 | 4 | Various reinforcement learning algorithms for Cartpole example. 5 |

6 | -------------------------------------------------------------------------------- /2-cartpole/cartpole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/2-cartpole/cartpole.png -------------------------------------------------------------------------------- /3-atari/1-breakout/breakout_a3c.py: -------------------------------------------------------------------------------- 1 | from skimage.color import rgb2gray 2 | from skimage.transform import resize 3 | from keras.layers import Dense, Flatten, Input 4 | from keras.layers.convolutional import Conv2D 5 | from keras.optimizers import RMSprop 6 | from keras import backend as K 7 | from keras.models import Model 8 | import tensorflow as tf 9 | import numpy as np 10 | import threading 11 | import random 12 | import time 13 | import gym 14 | 15 | # 멀티쓰레딩을 위한 글로벌 변수 16 | global episode 17 | episode = 0 18 | EPISODES = 8000000 19 | # 환경 생성 20 | env_name = "BreakoutDeterministic-v4" 21 | 22 | 23 | # 브레이크아웃에서의 A3CAgent 클래스(글로벌신경망) 24 | class A3CAgent: 25 | def __init__(self, action_size): 26 | # 상태크기와 행동크기를 갖고옴 27 | self.state_size = (84, 84, 4) 28 | self.action_size = action_size 29 | # A3C 하이퍼파라미터 30 | self.discount_factor = 0.99 31 | self.no_op_steps = 30 32 | self.actor_lr = 2.5e-4 33 | self.critic_lr = 2.5e-4 34 | # 쓰레드의 갯수 35 | self.threads = 8 36 | 37 | # 정책신경망과 가치신경망을 생성 38 | self.actor, self.critic = self.build_model() 39 | # 정책신경망과 가치신경망을 업데이트하는 함수 생성 40 | self.optimizer = [self.actor_optimizer(), self.critic_optimizer()] 41 | 42 | # 텐서보드 설정 43 | self.sess = tf.InteractiveSession() 44 | K.set_session(self.sess) 45 | self.sess.run(tf.global_variables_initializer()) 46 | 47 | self.summary_placeholders, self.update_ops, self.summary_op = \ 48 | self.setup_summary() 49 | self.summary_writer = \ 50 | tf.summary.FileWriter('summary/breakout_a3c', self.sess.graph) 51 | 52 | # 쓰레드를 만들어 학습을 하는 함수 53 | def train(self): 54 | # 쓰레드 수만큼 Agent 클래스 생성 55 | agents = [Agent(self.action_size, self.state_size, 56 | [self.actor, self.critic], self.sess, 57 | self.optimizer, self.discount_factor, 58 | [self.summary_op, self.summary_placeholders, 59 | self.update_ops, self.summary_writer]) 60 | for _ in range(self.threads)] 61 | 62 | # 각 쓰레드 시작 63 | for agent in agents: 64 | time.sleep(1) 65 | agent.start() 66 | 67 | # 10분(600초)에 한번씩 모델을 저장 68 | while True: 69 | time.sleep(60 * 10) 70 | self.save_model("./save_model/breakout_a3c") 71 | 72 | # 정책신경망과 가치신경망을 생성 73 | def build_model(self): 74 | input = Input(shape=self.state_size) 75 | conv = Conv2D(16, (8, 8), strides=(4, 4), activation='relu')(input) 76 | conv = Conv2D(32, (4, 4), strides=(2, 2), activation='relu')(conv) 77 | conv = Flatten()(conv) 78 | fc = Dense(256, activation='relu')(conv) 79 | 80 | policy = Dense(self.action_size, activation='softmax')(fc) 81 | value = Dense(1, activation='linear')(fc) 82 | 83 | actor = Model(inputs=input, outputs=policy) 84 | critic = Model(inputs=input, outputs=value) 85 | 86 | # 가치와 정책을 예측하는 함수를 만들어냄 87 | actor._make_predict_function() 88 | critic._make_predict_function() 89 | 90 | actor.summary() 91 | critic.summary() 92 | 93 | return actor, critic 94 | 95 | # 정책신경망을 업데이트하는 함수 96 | def actor_optimizer(self): 97 | action = K.placeholder(shape=[None, self.action_size]) 98 | advantages = K.placeholder(shape=[None, ]) 99 | 100 | policy = self.actor.output 101 | 102 | # 정책 크로스 엔트로피 오류함수 103 | action_prob = K.sum(action * policy, axis=1) 104 | cross_entropy = K.log(action_prob + 1e-10) * advantages 105 | cross_entropy = -K.sum(cross_entropy) 106 | 107 | # 탐색을 지속적으로 하기 위한 엔트로피 오류 108 | entropy = K.sum(policy * K.log(policy + 1e-10), axis=1) 109 | entropy = K.sum(entropy) 110 | 111 | # 두 오류함수를 더해 최종 오류함수를 만듬 112 | loss = cross_entropy + 0.01 * entropy 113 | 114 | optimizer = RMSprop(lr=self.actor_lr, rho=0.99, epsilon=0.01) 115 | updates = optimizer.get_updates(self.actor.trainable_weights, [],loss) 116 | train = K.function([self.actor.input, action, advantages], 117 | [loss], updates=updates) 118 | return train 119 | 120 | # 가치신경망을 업데이트하는 함수 121 | def critic_optimizer(self): 122 | discounted_prediction = K.placeholder(shape=(None,)) 123 | 124 | value = self.critic.output 125 | 126 | # [반환값 - 가치]의 제곱을 오류함수로 함 127 | loss = K.mean(K.square(discounted_prediction - value)) 128 | 129 | optimizer = RMSprop(lr=self.critic_lr, rho=0.99, epsilon=0.01) 130 | updates = optimizer.get_updates(self.critic.trainable_weights, [],loss) 131 | train = K.function([self.critic.input, discounted_prediction], 132 | [loss], updates=updates) 133 | return train 134 | 135 | def load_model(self, name): 136 | self.actor.load_weights(name + "_actor.h5") 137 | self.critic.load_weights(name + "_critic.h5") 138 | 139 | def save_model(self, name): 140 | self.actor.save_weights(name + "_actor.h5") 141 | self.critic.save_weights(name + "_critic.h5") 142 | 143 | # 각 에피소드 당 학습 정보를 기록 144 | def setup_summary(self): 145 | episode_total_reward = tf.Variable(0.) 146 | episode_avg_max_q = tf.Variable(0.) 147 | episode_duration = tf.Variable(0.) 148 | 149 | tf.summary.scalar('Total Reward/Episode', episode_total_reward) 150 | tf.summary.scalar('Average Max Prob/Episode', episode_avg_max_q) 151 | tf.summary.scalar('Duration/Episode', episode_duration) 152 | 153 | summary_vars = [episode_total_reward, 154 | episode_avg_max_q, 155 | episode_duration] 156 | 157 | summary_placeholders = [tf.placeholder(tf.float32) 158 | for _ in range(len(summary_vars))] 159 | update_ops = [summary_vars[i].assign(summary_placeholders[i]) 160 | for i in range(len(summary_vars))] 161 | summary_op = tf.summary.merge_all() 162 | return summary_placeholders, update_ops, summary_op 163 | 164 | 165 | # 액터러너 클래스(쓰레드) 166 | class Agent(threading.Thread): 167 | def __init__(self, action_size, state_size, model, sess, 168 | optimizer, discount_factor, summary_ops): 169 | threading.Thread.__init__(self) 170 | 171 | # A3CAgent 클래스에서 상속 172 | self.action_size = action_size 173 | self.state_size = state_size 174 | self.actor, self.critic = model 175 | self.sess = sess 176 | self.optimizer = optimizer 177 | self.discount_factor = discount_factor 178 | [self.summary_op, self.summary_placeholders, 179 | self.update_ops, self.summary_writer] = summary_ops 180 | 181 | # 지정된 타임스텝동안 샘플을 저장할 리스트 182 | self.states, self.actions, self.rewards = [], [], [] 183 | 184 | # 로컬 모델 생성 185 | self.local_actor, self.local_critic = self.build_local_model() 186 | 187 | self.avg_p_max = 0 188 | self.avg_loss = 0 189 | 190 | # 모델 업데이트 주기 191 | self.t_max = 20 192 | self.t = 0 193 | 194 | def run(self): 195 | global episode 196 | env = gym.make(env_name) 197 | 198 | step = 0 199 | 200 | while episode < EPISODES: 201 | done = False 202 | dead = False 203 | 204 | score, start_life = 0, 5 205 | observe = env.reset() 206 | next_observe = observe 207 | 208 | # 0~30 상태동안 정지 209 | for _ in range(random.randint(1, 30)): 210 | observe = next_observe 211 | next_observe, _, _, _ = env.step(1) 212 | 213 | state = pre_processing(next_observe, observe) 214 | history = np.stack((state, state, state, state), axis=2) 215 | history = np.reshape([history], (1, 84, 84, 4)) 216 | 217 | while not done: 218 | step += 1 219 | self.t += 1 220 | observe = next_observe 221 | action, policy = self.get_action(history) 222 | 223 | # 1: 정지, 2: 왼쪽, 3: 오른쪽 224 | if action == 0: 225 | real_action = 1 226 | elif action == 1: 227 | real_action = 2 228 | else: 229 | real_action = 3 230 | 231 | # 죽었을 때 시작하기 위해 발사 행동을 함 232 | if dead: 233 | action = 0 234 | real_action = 1 235 | dead = False 236 | 237 | # 선택한 행동으로 한 스텝을 실행 238 | next_observe, reward, done, info = env.step(real_action) 239 | 240 | # 각 타임스텝마다 상태 전처리 241 | next_state = pre_processing(next_observe, observe) 242 | next_state = np.reshape([next_state], (1, 84, 84, 1)) 243 | next_history = np.append(next_state, history[:, :, :, :3], 244 | axis=3) 245 | 246 | # 정책의 최대값 247 | self.avg_p_max += np.amax(self.actor.predict( 248 | np.float32(history / 255.))) 249 | 250 | if start_life > info['ale.lives']: 251 | dead = True 252 | start_life = info['ale.lives'] 253 | 254 | score += reward 255 | reward = np.clip(reward, -1., 1.) 256 | 257 | # 샘플을 저장 258 | self.append_sample(history, action, reward) 259 | 260 | if dead: 261 | history = np.stack((next_state, next_state, 262 | next_state, next_state), axis=2) 263 | history = np.reshape([history], (1, 84, 84, 4)) 264 | else: 265 | history = next_history 266 | 267 | # 에피소드가 끝나거나 최대 타임스텝 수에 도달하면 학습을 진행 268 | if self.t >= self.t_max or done: 269 | self.train_model(done) 270 | self.update_local_model() 271 | self.t = 0 272 | 273 | if done: 274 | # 각 에피소드 당 학습 정보를 기록 275 | episode += 1 276 | print("episode:", episode, " score:", score, " step:", 277 | step) 278 | 279 | stats = [score, self.avg_p_max / float(step), 280 | step] 281 | for i in range(len(stats)): 282 | self.sess.run(self.update_ops[i], feed_dict={ 283 | self.summary_placeholders[i]: float(stats[i]) 284 | }) 285 | summary_str = self.sess.run(self.summary_op) 286 | self.summary_writer.add_summary(summary_str, episode + 1) 287 | self.avg_p_max = 0 288 | self.avg_loss = 0 289 | step = 0 290 | 291 | # k-스텝 prediction 계산 292 | def discounted_prediction(self, rewards, done): 293 | discounted_prediction = np.zeros_like(rewards) 294 | running_add = 0 295 | 296 | if not done: 297 | running_add = self.local_critic.predict(np.float32( 298 | self.states[-1] / 255.))[0] 299 | 300 | for t in reversed(range(0, len(rewards))): 301 | running_add = running_add * self.discount_factor + rewards[t] 302 | discounted_prediction[t] = running_add 303 | return discounted_prediction 304 | 305 | # 정책신경망과 가치신경망을 업데이트 306 | def train_model(self, done): 307 | discounted_prediction = self.discounted_prediction(self.rewards, done) 308 | 309 | states = np.zeros((len(self.states), 84, 84, 4)) 310 | for i in range(len(self.states)): 311 | states[i] = self.states[i] 312 | 313 | states = np.float32(states / 255.) 314 | 315 | values = self.local_critic.predict(states) 316 | values = np.reshape(values, len(values)) 317 | 318 | advantages = discounted_prediction - values 319 | 320 | self.optimizer[0]([states, self.actions, advantages]) 321 | self.optimizer[1]([states, discounted_prediction]) 322 | self.states, self.actions, self.rewards = [], [], [] 323 | 324 | # 로컬신경망을 생성하는 함수 325 | def build_local_model(self): 326 | input = Input(shape=self.state_size) 327 | conv = Conv2D(16, (8, 8), strides=(4, 4), activation='relu')(input) 328 | conv = Conv2D(32, (4, 4), strides=(2, 2), activation='relu')(conv) 329 | conv = Flatten()(conv) 330 | fc = Dense(256, activation='relu')(conv) 331 | policy = Dense(self.action_size, activation='softmax')(fc) 332 | value = Dense(1, activation='linear')(fc) 333 | 334 | local_actor = Model(inputs=input, outputs=policy) 335 | local_critic = Model(inputs=input, outputs=value) 336 | 337 | local_actor._make_predict_function() 338 | local_critic._make_predict_function() 339 | 340 | local_actor.set_weights(self.actor.get_weights()) 341 | local_critic.set_weights(self.critic.get_weights()) 342 | 343 | local_actor.summary() 344 | local_critic.summary() 345 | 346 | return local_actor, local_critic 347 | 348 | # 로컬신경망을 글로벌신경망으로 업데이트 349 | def update_local_model(self): 350 | self.local_actor.set_weights(self.actor.get_weights()) 351 | self.local_critic.set_weights(self.critic.get_weights()) 352 | 353 | # 정책신경망의 출력을 받아서 확률적으로 행동을 선택 354 | def get_action(self, history): 355 | history = np.float32(history / 255.) 356 | policy = self.local_actor.predict(history)[0] 357 | action_index = np.random.choice(self.action_size, 1, p=policy)[0] 358 | return action_index, policy 359 | 360 | # 샘플을 저장 361 | def append_sample(self, history, action, reward): 362 | self.states.append(history) 363 | act = np.zeros(self.action_size) 364 | act[action] = 1 365 | self.actions.append(act) 366 | self.rewards.append(reward) 367 | 368 | 369 | # 학습속도를 높이기 위해 흑백화면으로 전처리 370 | def pre_processing(next_observe, observe): 371 | processed_observe = np.maximum(next_observe, observe) 372 | processed_observe = np.uint8( 373 | resize(rgb2gray(processed_observe), (84, 84), mode='constant') * 255) 374 | return processed_observe 375 | 376 | if __name__ == "__main__": 377 | global_agent = A3CAgent(action_size=3) 378 | global_agent.train() 379 | -------------------------------------------------------------------------------- /3-atari/1-breakout/breakout_dqn.py: -------------------------------------------------------------------------------- 1 | from keras.layers.convolutional import Conv2D 2 | from keras.layers import Dense, Flatten 3 | from keras.optimizers import RMSprop 4 | from keras.models import Sequential 5 | from skimage.transform import resize 6 | from skimage.color import rgb2gray 7 | from collections import deque 8 | from keras import backend as K 9 | import tensorflow as tf 10 | import numpy as np 11 | import random 12 | import gym 13 | 14 | EPISODES = 50000 15 | 16 | 17 | # 브레이크아웃에서의 DQN 에이전트 18 | class DQNAgent: 19 | def __init__(self, action_size): 20 | self.render = False 21 | self.load_model = False 22 | # 상태와 행동의 크기 정의 23 | self.state_size = (84, 84, 4) 24 | self.action_size = action_size 25 | # DQN 하이퍼파라미터 26 | self.epsilon = 1. 27 | self.epsilon_start, self.epsilon_end = 1.0, 0.1 28 | self.exploration_steps = 1000000. 29 | self.epsilon_decay_step = (self.epsilon_start - self.epsilon_end) \ 30 | / self.exploration_steps 31 | self.batch_size = 32 32 | self.train_start = 50000 33 | self.update_target_rate = 10000 34 | self.discount_factor = 0.99 35 | # 리플레이 메모리, 최대 크기 400000 36 | self.memory = deque(maxlen=400000) 37 | self.no_op_steps = 30 38 | # 모델과 타겟모델을 생성하고 타겟모델 초기화 39 | self.model = self.build_model() 40 | self.target_model = self.build_model() 41 | self.update_target_model() 42 | 43 | self.optimizer = self.optimizer() 44 | 45 | # 텐서보드 설정 46 | self.sess = tf.InteractiveSession() 47 | K.set_session(self.sess) 48 | 49 | self.avg_q_max, self.avg_loss = 0, 0 50 | self.summary_placeholders, self.update_ops, self.summary_op = \ 51 | self.setup_summary() 52 | self.summary_writer = tf.summary.FileWriter( 53 | 'summary/breakout_dqn', self.sess.graph) 54 | self.sess.run(tf.global_variables_initializer()) 55 | 56 | if self.load_model: 57 | self.model.load_weights("./save_model/breakout_dqn.h5") 58 | 59 | # Huber Loss를 이용하기 위해 최적화 함수를 직접 정의 60 | def optimizer(self): 61 | a = K.placeholder(shape=(None,), dtype='int32') 62 | y = K.placeholder(shape=(None,), dtype='float32') 63 | 64 | prediction = self.model.output 65 | 66 | a_one_hot = K.one_hot(a, self.action_size) 67 | q_value = K.sum(prediction * a_one_hot, axis=1) 68 | error = K.abs(y - q_value) 69 | 70 | quadratic_part = K.clip(error, 0.0, 1.0) 71 | linear_part = error - quadratic_part 72 | loss = K.mean(0.5 * K.square(quadratic_part) + linear_part) 73 | 74 | optimizer = RMSprop(lr=0.00025, epsilon=0.01) 75 | updates = optimizer.get_updates(self.model.trainable_weights, [], loss) 76 | train = K.function([self.model.input, a, y], [loss], updates=updates) 77 | 78 | return train 79 | 80 | # 상태가 입력, 큐함수가 출력인 인공신경망 생성 81 | def build_model(self): 82 | model = Sequential() 83 | model.add(Conv2D(32, (8, 8), strides=(4, 4), activation='relu', 84 | input_shape=self.state_size)) 85 | model.add(Conv2D(64, (4, 4), strides=(2, 2), activation='relu')) 86 | model.add(Conv2D(64, (3, 3), strides=(1, 1), activation='relu')) 87 | model.add(Flatten()) 88 | model.add(Dense(512, activation='relu')) 89 | model.add(Dense(self.action_size)) 90 | model.summary() 91 | return model 92 | 93 | # 타겟 모델을 모델의 가중치로 업데이트 94 | def update_target_model(self): 95 | self.target_model.set_weights(self.model.get_weights()) 96 | 97 | # 입실론 탐욕 정책으로 행동 선택 98 | def get_action(self, history): 99 | history = np.float32(history / 255.0) 100 | if np.random.rand() <= self.epsilon: 101 | return random.randrange(self.action_size) 102 | else: 103 | q_value = self.model.predict(history) 104 | return np.argmax(q_value[0]) 105 | 106 | # 샘플 을 리플레이 메모리에 저장 107 | def append_sample(self, history, action, reward, next_history, dead): 108 | self.memory.append((history, action, reward, next_history, dead)) 109 | 110 | # 리플레이 메모리에서 무작위로 추출한 배치로 모델 학습 111 | def train_model(self): 112 | if self.epsilon > self.epsilon_end: 113 | self.epsilon -= self.epsilon_decay_step 114 | 115 | mini_batch = random.sample(self.memory, self.batch_size) 116 | 117 | history = np.zeros((self.batch_size, self.state_size[0], 118 | self.state_size[1], self.state_size[2])) 119 | next_history = np.zeros((self.batch_size, self.state_size[0], 120 | self.state_size[1], self.state_size[2])) 121 | target = np.zeros((self.batch_size,)) 122 | action, reward, dead = [], [], [] 123 | 124 | for i in range(self.batch_size): 125 | history[i] = np.float32(mini_batch[i][0] / 255.) 126 | next_history[i] = np.float32(mini_batch[i][3] / 255.) 127 | action.append(mini_batch[i][1]) 128 | reward.append(mini_batch[i][2]) 129 | dead.append(mini_batch[i][4]) 130 | 131 | target_value = self.target_model.predict(next_history) 132 | 133 | for i in range(self.batch_size): 134 | if dead[i]: 135 | target[i] = reward[i] 136 | else: 137 | target[i] = reward[i] + self.discount_factor * \ 138 | np.amax(target_value[i]) 139 | 140 | loss = self.optimizer([history, action, target]) 141 | self.avg_loss += loss[0] 142 | 143 | # 각 에피소드 당 학습 정보를 기록 144 | def setup_summary(self): 145 | episode_total_reward = tf.Variable(0.) 146 | episode_avg_max_q = tf.Variable(0.) 147 | episode_duration = tf.Variable(0.) 148 | episode_avg_loss = tf.Variable(0.) 149 | 150 | tf.summary.scalar('Total Reward/Episode', episode_total_reward) 151 | tf.summary.scalar('Average Max Q/Episode', episode_avg_max_q) 152 | tf.summary.scalar('Duration/Episode', episode_duration) 153 | tf.summary.scalar('Average Loss/Episode', episode_avg_loss) 154 | 155 | summary_vars = [episode_total_reward, episode_avg_max_q, 156 | episode_duration, episode_avg_loss] 157 | summary_placeholders = [tf.placeholder(tf.float32) for _ in 158 | range(len(summary_vars))] 159 | update_ops = [summary_vars[i].assign(summary_placeholders[i]) for i in 160 | range(len(summary_vars))] 161 | summary_op = tf.summary.merge_all() 162 | return summary_placeholders, update_ops, summary_op 163 | 164 | 165 | # 학습속도를 높이기 위해 흑백화면으로 전처리 166 | def pre_processing(observe): 167 | processed_observe = np.uint8( 168 | resize(rgb2gray(observe), (84, 84), mode='constant') * 255) 169 | return processed_observe 170 | 171 | 172 | if __name__ == "__main__": 173 | # 환경과 DQN 에이전트 생성 174 | env = gym.make('BreakoutDeterministic-v4') 175 | agent = DQNAgent(action_size=3) 176 | 177 | scores, episodes, global_step = [], [], 0 178 | 179 | for e in range(EPISODES): 180 | done = False 181 | dead = False 182 | 183 | step, score, start_life = 0, 0, 5 184 | observe = env.reset() 185 | 186 | for _ in range(random.randint(1, agent.no_op_steps)): 187 | observe, _, _, _ = env.step(1) 188 | 189 | state = pre_processing(observe) 190 | history = np.stack((state, state, state, state), axis=2) 191 | history = np.reshape([history], (1, 84, 84, 4)) 192 | 193 | while not done: 194 | if agent.render: 195 | env.render() 196 | global_step += 1 197 | step += 1 198 | 199 | # 바로 전 4개의 상태로 행동을 선택 200 | action = agent.get_action(history) 201 | # 1: 정지, 2: 왼쪽, 3: 오른쪽 202 | if action == 0: 203 | real_action = 1 204 | elif action == 1: 205 | real_action = 2 206 | else: 207 | real_action = 3 208 | 209 | # 선택한 행동으로 환경에서 한 타임스텝 진행 210 | observe, reward, done, info = env.step(real_action) 211 | # 각 타임스텝마다 상태 전처리 212 | next_state = pre_processing(observe) 213 | next_state = np.reshape([next_state], (1, 84, 84, 1)) 214 | next_history = np.append(next_state, history[:, :, :, :3], axis=3) 215 | 216 | agent.avg_q_max += np.amax( 217 | agent.model.predict(np.float32(history / 255.))[0]) 218 | 219 | if start_life > info['ale.lives']: 220 | dead = True 221 | start_life = info['ale.lives'] 222 | 223 | reward = np.clip(reward, -1., 1.) 224 | # 샘플 을 리플레이 메모리에 저장 후 학습 225 | agent.append_sample(history, action, reward, next_history, dead) 226 | 227 | if len(agent.memory) >= agent.train_start: 228 | agent.train_model() 229 | 230 | # 일정 시간마다 타겟모델을 모델의 가중치로 업데이트 231 | if global_step % agent.update_target_rate == 0: 232 | agent.update_target_model() 233 | 234 | score += reward 235 | 236 | if dead: 237 | dead = False 238 | else: 239 | history = next_history 240 | 241 | if done: 242 | # 각 에피소드 당 학습 정보를 기록 243 | if global_step > agent.train_start: 244 | stats = [score, agent.avg_q_max / float(step), step, 245 | agent.avg_loss / float(step)] 246 | for i in range(len(stats)): 247 | agent.sess.run(agent.update_ops[i], feed_dict={ 248 | agent.summary_placeholders[i]: float(stats[i]) 249 | }) 250 | summary_str = agent.sess.run(agent.summary_op) 251 | agent.summary_writer.add_summary(summary_str, e + 1) 252 | 253 | print("episode:", e, " score:", score, " memory length:", 254 | len(agent.memory), " epsilon:", agent.epsilon, 255 | " global_step:", global_step, " average_q:", 256 | agent.avg_q_max / float(step), " average loss:", 257 | agent.avg_loss / float(step)) 258 | 259 | agent.avg_q_max, agent.avg_loss = 0, 0 260 | 261 | # 1000 에피소드마다 모델 저장 262 | if e % 1000 == 0: 263 | agent.model.save_weights("./save_model/breakout_dqn.h5") 264 | -------------------------------------------------------------------------------- /3-atari/1-breakout/play_a3c_model.py: -------------------------------------------------------------------------------- 1 | import gym 2 | import random 3 | import numpy as np 4 | from skimage.color import rgb2gray 5 | from skimage.transform import resize 6 | from keras.models import Model 7 | from keras.layers import Dense, Flatten, Input 8 | from keras.layers.convolutional import Conv2D 9 | 10 | global episode 11 | episode = 0 12 | EPISODES = 100 13 | env_name = "BreakoutDeterministic-v4" 14 | 15 | class TestAgent: 16 | def __init__(self, action_size): 17 | self.state_size = (84, 84, 4) 18 | self.action_size = action_size 19 | 20 | self.discount_factor = 0.99 21 | self.no_op_steps = 30 22 | 23 | self.actor, self.critic = self.build_model() 24 | 25 | def build_model(self): 26 | input = Input(shape=self.state_size) 27 | conv = Conv2D(16, (8, 8), strides=(4, 4), activation='relu')(input) 28 | conv = Conv2D(32, (4, 4), strides=(2, 2), activation='relu')(conv) 29 | conv = Flatten()(conv) 30 | fc = Dense(256, activation='relu')(conv) 31 | policy = Dense(self.action_size, activation='softmax')(fc) 32 | value = Dense(1, activation='linear')(fc) 33 | 34 | actor = Model(inputs=input, outputs=policy) 35 | critic = Model(inputs=input, outputs=value) 36 | 37 | actor.summary() 38 | critic.summary() 39 | 40 | return actor, critic 41 | 42 | def get_action(self, history): 43 | history = np.float32(history / 255.) 44 | policy = self.actor.predict(history)[0] 45 | 46 | action_index = np.argmax(policy) 47 | return action_index 48 | 49 | def load_model(self, name): 50 | self.actor.load_weights(name) 51 | 52 | def pre_processing(next_observe, observe): 53 | processed_observe = np.maximum(next_observe, observe) 54 | processed_observe = np.uint8( 55 | resize(rgb2gray(processed_observe), (84, 84), mode='constant') * 255) 56 | return processed_observe 57 | 58 | 59 | if __name__ == "__main__": 60 | env = gym.make(env_name) 61 | agent = TestAgent(action_size=3) 62 | agent.load_model("save_model/breakout_a3c_5_actor.h5") 63 | 64 | step = 0 65 | 66 | while episode < EPISODES: 67 | done = False 68 | dead = False 69 | 70 | score, start_life = 0, 5 71 | observe = env.reset() 72 | next_observe = observe 73 | 74 | for _ in range(random.randint(1, agent.no_op_steps)): 75 | observe = next_observe 76 | next_observe, _, _, _ = env.step(1) 77 | 78 | state = pre_processing(next_observe, observe) 79 | history = np.stack((state, state, state, state), axis=2) 80 | history = np.reshape([history], (1, 84, 84, 4)) 81 | 82 | while not done: 83 | env.render() 84 | step += 1 85 | observe = next_observe 86 | 87 | action = agent.get_action(history) 88 | 89 | if action == 1: 90 | fake_action = 2 91 | elif action == 2: 92 | fake_action = 3 93 | else: 94 | fake_action = 1 95 | 96 | if dead: 97 | fake_action = 1 98 | dead = False 99 | 100 | next_observe, reward, done, info = env.step(fake_action) 101 | 102 | next_state = pre_processing(next_observe, observe) 103 | next_state = np.reshape([next_state], (1, 84, 84, 1)) 104 | next_history = np.append(next_state, history[:, :, :, :3], axis=3) 105 | 106 | if start_life > info['ale.lives']: 107 | dead = True 108 | reward = -1 109 | start_life = info['ale.lives'] 110 | 111 | score += reward 112 | 113 | # if agent is dead, then reset the history 114 | if dead: 115 | history = np.stack( 116 | (next_state, next_state, next_state, next_state), axis=2) 117 | history = np.reshape([history], (1, 84, 84, 4)) 118 | else: 119 | history = next_history 120 | 121 | # if done, plot the score over episodes 122 | if done: 123 | episode += 1 124 | print("episode:", episode, " score:", score, " step:", step) 125 | step = 0 -------------------------------------------------------------------------------- /3-atari/1-breakout/play_dqn_model.py: -------------------------------------------------------------------------------- 1 | import gym 2 | import random 3 | import numpy as np 4 | import tensorflow as tf 5 | from skimage.color import rgb2gray 6 | from skimage.transform import resize 7 | from keras.models import Sequential 8 | from keras.layers import Dense, Flatten 9 | from keras.layers.convolutional import Conv2D 10 | from keras import backend as K 11 | 12 | EPISODES = 50000 13 | 14 | class TestAgent: 15 | def __init__(self, action_size): 16 | self.state_size = (84, 84, 4) 17 | self.action_size = action_size 18 | self.no_op_steps = 20 19 | 20 | self.model = self.build_model() 21 | 22 | self.sess = tf.InteractiveSession() 23 | K.set_session(self.sess) 24 | 25 | self.avg_q_max, self.avg_loss = 0, 0 26 | self.sess.run(tf.global_variables_initializer()) 27 | 28 | def build_model(self): 29 | model = Sequential() 30 | model.add(Conv2D(32, (8, 8), strides=(4, 4), activation='relu', 31 | input_shape=self.state_size)) 32 | model.add(Conv2D(64, (4, 4), strides=(2, 2), activation='relu')) 33 | model.add(Conv2D(64, (3, 3), strides=(1, 1), activation='relu')) 34 | model.add(Flatten()) 35 | model.add(Dense(512, activation='relu')) 36 | model.add(Dense(self.action_size)) 37 | model.summary() 38 | 39 | return model 40 | 41 | def get_action(self, history): 42 | if np.random.random() < 0.01: 43 | return random.randrange(3) 44 | history = np.float32(history / 255.0) 45 | q_value = self.model.predict(history) 46 | return np.argmax(q_value[0]) 47 | 48 | def load_model(self, filename): 49 | self.model.load_weights(filename) 50 | 51 | def pre_processing(observe): 52 | processed_observe = np.uint8( 53 | resize(rgb2gray(observe), (84, 84), mode='constant') * 255) 54 | return processed_observe 55 | 56 | 57 | if __name__ == "__main__": 58 | env = gym.make('BreakoutDeterministic-v4') 59 | agent = TestAgent(action_size=3) 60 | agent.load_model("./save_model/breakout_dqn_5.h5") 61 | 62 | for e in range(EPISODES): 63 | done = False 64 | dead = False 65 | 66 | step, score, start_life = 0, 0, 5 67 | observe = env.reset() 68 | 69 | for _ in range(random.randint(1, agent.no_op_steps)): 70 | observe, _, _, _ = env.step(1) 71 | 72 | state = pre_processing(observe) 73 | history = np.stack((state, state, state, state), axis=2) 74 | history = np.reshape([history], (1, 84, 84, 4)) 75 | 76 | while not done: 77 | env.render() 78 | step += 1 79 | 80 | action = agent.get_action(history) 81 | 82 | if action == 0: 83 | real_action = 1 84 | elif action == 1: 85 | real_action = 2 86 | else: 87 | real_action = 3 88 | 89 | if dead: 90 | real_action = 1 91 | dead = False 92 | 93 | observe, reward, done, info = env.step(real_action) 94 | 95 | next_state = pre_processing(observe) 96 | next_state = np.reshape([next_state], (1, 84, 84, 1)) 97 | next_history = np.append(next_state, history[:, :, :, :3], axis=3) 98 | 99 | if start_life > info['ale.lives']: 100 | dead = True 101 | start_life = info['ale.lives'] 102 | 103 | score += reward 104 | 105 | history = next_history 106 | 107 | if done: 108 | print("episode:", e, " score:", score) 109 | 110 | -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_1_actor.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_1_actor.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_1_critic.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_1_critic.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_2_actor.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_2_actor.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_2_critic.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_2_critic.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_3_actor.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_3_actor.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_3_critic.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_3_critic.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_4_actor.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_4_actor.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_4_critic.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_4_critic.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_5_actor.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_5_actor.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_a3c_5_critic.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_a3c_5_critic.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_dqn.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_dqn.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_dqn_1.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_dqn_1.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_dqn_2.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_dqn_2.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_dqn_3.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_dqn_3.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_dqn_4.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_dqn_4.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/save_model/breakout_dqn_5.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/save_model/breakout_dqn_5.h5 -------------------------------------------------------------------------------- /3-atari/1-breakout/summary/breakout_a3c/events.out.tfevents.1497264638: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/summary/breakout_a3c/events.out.tfevents.1497264638 -------------------------------------------------------------------------------- /3-atari/1-breakout/summary/breakout_dqn/events.out.tfevents.1496968668.young-System-Product-Name: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/3-atari/1-breakout/summary/breakout_dqn/events.out.tfevents.1496968668.young-System-Product-Name -------------------------------------------------------------------------------- /3-atari/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Keon Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 RLCode 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | -------------------------------------------------------------------------------- 4 | 5 | > [RLCode](https://rlcode.github.io)팀이 직접 만든 강화학습 예제들을 모아놓은 Repo 입니다. [영문 (English)](https://github.com/rlcode/reinforcement-learning) 6 | > 7 | > Maintainers - [이웅원](https://github.com/dnddnjs), [이영무](https://github.com/zzing0907), [양혁렬](https://github.com/Hyeokreal), [이의령](https://github.com/wooridle), [김건우](https://github.com/keon) 8 | 9 | [Pull Request](https://github.com/rlcode/reinforcement-learning-kr/pulls)는 언제든 환영입니다. 10 | 문제나 버그, 혹은 궁금한 사항이 있으면 [이슈](https://github.com/rlcode/reinforcement-learning-kr/issues)에 글을 남겨주세요. 11 | 12 | 13 | ## 필요한 라이브러리들 (Dependencies) 14 | 1. Python 3.5 15 | 2. Tensorflow 1.0.0 16 | 3. Keras 17 | 4. numpy 18 | 5. pandas 19 | 6. pillow 20 | 7. matplot 21 | 8. Skimage 22 | 9. h5py 23 | 24 | ### 설치 방법 (Install Requirements) 25 | ``` 26 | pip install -r requirements.txt 27 | ``` 28 | 29 | 30 | ## 목차 (Table of Contents) 31 | 32 | **Grid World** - 비교적 단순한 환경인 그리드월드에서 강화학습의 기초를 쌓기 33 | 34 | - [정책 이터레이션 (Policy Iteration)](./1-grid-world/1-policy-iteration) 35 | - [가치 이터레이션 (Value Iteration)](./1-grid-world/2-value-iteration) 36 | - [몬테카를로 (Monte Carlo)](./1-grid-world/3-monte-carlo) 37 | - [살사 (SARSA)](./1-grid-world/4-sarsa) 38 | - [큐러닝 (Q-Learning)](./1-grid-world/5-q-learning) 39 | - [Deep SARSA](./1-grid-world/6-deep-sarsa) 40 | - [REINFORCE](./1-grid-world/7-reinforce) 41 | 42 | **CartPole** - 카트폴 예제를 이용하여 여러가지 딥러닝을 강화학습에 응용한 알고리즘들을 적용해보기 43 | 44 | - [Deep Q Network](./2-cartpole/1-dqn) 45 | - [Actor Critic (A2C)](./2-cartpole/2-actor-critic) 46 | 47 | **Atari 브레이크아웃** - 딥러닝을 응용하여 좀더 복잡한 Atari 브레이크아웃 게임을 마스터하는 에이전트 만들기 48 | 49 | - [Deep Q Network](./3-atari/1-breakout/breakout_dqn.py) 50 | - [Asynchronous Advantage Actor Critic(A3C)](./3-atari/1-breakout/breakout_a3c.py) -------------------------------------------------------------------------------- /images/Reinforcement-Learning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/images/Reinforcement-Learning.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Keras>=2.0.3 2 | numpy>=1.12.1 3 | pandas>=0.19.2 4 | matplotlib>=2.0.0 5 | tensorflow>=1.0.0 6 | Pillow>=4.1.0 7 | gym>=0.8.1 8 | h5py 9 | scikit-image>=0.13.0 10 | -------------------------------------------------------------------------------- /wiki/README.md: -------------------------------------------------------------------------------- 1 | # Installation guide 2 | 3 | `(도서)파이썬과 케라스로 배우는 강화학습`의 환경 설치 설명을 위한 레포지토리 입니다. 4 | 5 | 다음 세가지의 설치 환경을 설명합니다. 6 | 7 | 해당 링크를 누르면 환경 설치에 대한 상세 가이드를 보실 수 있습니다. 8 | 9 | - **윈도우 [[link]](./install_guide_window.md)** 10 | - **리눅스(우분투) [[link]](./install_guide_ubuntu.md)** 11 | - **맥(osx) [[link]](./install_guide_osx.md)** 12 | 13 | > #### 윈도우는 Openai에서 공식적인 설치 가이드를 제공하고 있지 않습니다. 14 | > #### 그래서 Openai gym 버전에 따라 설치가 안될 수 있습니다. 그리고 다른 환경과 달리 설치방법이 다소 까다롭습니다. 15 | > 현재 윈도우 환경 설치는 다음 링크를 참조하여 작성하였습니다. 16 | > [[link : openai gym window support issue]](https://github.com/openai/gym/issues/11) 17 | 18 | ### IDE(interface Development environment) 19 | 20 | 공통적으로 파이참(pycharm)[[link]](https://www.jetbrains.com/pycharm/)을 IDE로 사용하고 있습니다. 21 | 22 | ### 파이썬 패키지 관리자(package manager) 23 | 24 | - 윈도우는 파이썬 패키지 관리자로 Anaconda를 사용합니다. 25 | 26 | - 리눅스(우분투)와 맥(osx)는 pip를 사용합니다. 27 | -------------------------------------------------------------------------------- /wiki/how-to-windows(english).md: -------------------------------------------------------------------------------- 1 | # How To run examples on windows, step by step. 2 | Traditionally machine learning applications could only run in Linux or MacOS environments. 3 | 4 | In this wiki you will learn how to configure your **windows** environment so you can run the examples. 5 | ![](img/how-to-windows.png) 6 | 7 | # Go for it. 8 | Recommended for greater compatibility 9 | 10 | ## Python Interpreter: 11 | - Download & Install [Anaconda](https://www.continuum.io/downloads), pick Python 3.6 version 64 Bit Installer 12 | Test installation on Windows console 13 | 14 | ``` 15 | python --version 16 | Python 3.6.0 :: Anaconda custom (64-bit) 17 | ``` 18 | ## Set virtual env to run examples 19 | ``` 20 | # Create env, you can pick any version of python, but for run this repo 21 | conda create --name rl python=3.5 22 | 23 | # Activate env 24 | activate rl 25 | 26 | # Install TensorFlow, the easy way 27 | conda install -c conda-forge tensorflow 28 | conda install -c anaconda scipy=0.19.0 29 | 30 | mkdir examples 31 | cd examples 32 | git clone https://github.com/rlcode/reinforcement-learning 33 | cd reinforcement-learning 34 | 35 | # Install Requirements 36 | pip install -r requirements.txt 37 | 38 | # Check 39 | conda list 40 | 41 | # Test the code 42 | cd "Code 1. Grid World\1. Policy Iteration" 43 | python run.py 44 | ``` 45 | 46 | # Next Steps. 47 | - Need a IDE to easy manage the python scripts, Download & Install [PyCharm Community](https://www.jetbrains.com/pycharm/download/#section=windows) its free. 48 | 49 | ## Linking PyCharm with Anaconda Env. 50 | - Open Project with PyCharm IDE: File > Open > Pick Folder (c:\examples\reinforcement-learning) 51 | - File > Settings > Project Interpreter > Add Local 52 | ![](img/link-env-with-pychar.png) 53 | 54 | - Note: Need to pick python environment interpreter i.e located in c:\Anaconda3\envs\rl 55 | ![](img/link-env-with-pychar-1.png) 56 | 57 | - If all is ok. 58 | ![](img/link-env-with-pychar-2.png) 59 | 60 | - Play It with samples (Run). 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /wiki/img/how-to-windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/how-to-windows.png -------------------------------------------------------------------------------- /wiki/img/link-env-with-pychar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/link-env-with-pychar-1.png -------------------------------------------------------------------------------- /wiki/img/link-env-with-pychar-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/link-env-with-pychar-2.png -------------------------------------------------------------------------------- /wiki/img/link-env-with-pychar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/link-env-with-pychar.png -------------------------------------------------------------------------------- /wiki/img/numpy_install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/numpy_install.png -------------------------------------------------------------------------------- /wiki/img/numpy_install2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/numpy_install2.png -------------------------------------------------------------------------------- /wiki/img/numpy_install3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/numpy_install3.png -------------------------------------------------------------------------------- /wiki/img/python3png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/python3png.png -------------------------------------------------------------------------------- /wiki/img/python_install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/python_install.png -------------------------------------------------------------------------------- /wiki/img/win_atari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_atari.png -------------------------------------------------------------------------------- /wiki/img/win_atari.py3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_atari.py3.png -------------------------------------------------------------------------------- /wiki/img/win_breakout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_breakout.png -------------------------------------------------------------------------------- /wiki/img/win_breakout2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_breakout2.png -------------------------------------------------------------------------------- /wiki/img/win_git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_git.png -------------------------------------------------------------------------------- /wiki/img/win_git2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_git2.png -------------------------------------------------------------------------------- /wiki/img/win_gym.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_gym.png -------------------------------------------------------------------------------- /wiki/img/win_make.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_make.png -------------------------------------------------------------------------------- /wiki/img/win_make2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_make2.png -------------------------------------------------------------------------------- /wiki/img/win_msys2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_msys2.png -------------------------------------------------------------------------------- /wiki/img/win_msys2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_msys2_2.png -------------------------------------------------------------------------------- /wiki/img/win_msys2_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_msys2_3.png -------------------------------------------------------------------------------- /wiki/img/win_msys2_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_msys2_4.png -------------------------------------------------------------------------------- /wiki/img/win_msys2_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_msys2_5.png -------------------------------------------------------------------------------- /wiki/img/win_openai_gym.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_openai_gym.png -------------------------------------------------------------------------------- /wiki/img/win_openai_gym2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_openai_gym2.png -------------------------------------------------------------------------------- /wiki/img/win_openai_gym3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_openai_gym3.png -------------------------------------------------------------------------------- /wiki/img/win_openai_gym4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_openai_gym4.png -------------------------------------------------------------------------------- /wiki/img/win_openai_gym5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_openai_gym5.png -------------------------------------------------------------------------------- /wiki/img/win_pycharm_install1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_pycharm_install1.png -------------------------------------------------------------------------------- /wiki/img/win_pycharm_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_pycharm_project.png -------------------------------------------------------------------------------- /wiki/img/win_pycharm_project2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_pycharm_project2.png -------------------------------------------------------------------------------- /wiki/img/win_pycharm_setting2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_pycharm_setting2.png -------------------------------------------------------------------------------- /wiki/img/win_pycharm_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_pycharm_settings.png -------------------------------------------------------------------------------- /wiki/img/win_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_setting.png -------------------------------------------------------------------------------- /wiki/img/win_setting2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_setting2.png -------------------------------------------------------------------------------- /wiki/img/win_setting3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_setting3.png -------------------------------------------------------------------------------- /wiki/img/win_setting4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_setting4.png -------------------------------------------------------------------------------- /wiki/img/win_setup.py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_setup.py.png -------------------------------------------------------------------------------- /wiki/img/win_setup.py2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_setup.py2.png -------------------------------------------------------------------------------- /wiki/img/win_xming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/img/win_xming.png -------------------------------------------------------------------------------- /wiki/install_guide_osx.md: -------------------------------------------------------------------------------- 1 | ## 개발 환경 설정 2: 맥 OS 2 | 3 | 맥 OS에는 기본적으로 파이썬 2.7버전이 설치되어있기 때문에 3.5 버전을 새로 설치를 해야 합니다. 4 | 5 | ### 1.1 파이썬 3.5 설치 및 환경 설정 6 | 7 | 파이썬 다운로드 페이지[[Link]](https://www.python.org/downloads/release/python-350/)로 접속하면 다음과 같은 화면이 나옵니다. 8 | 9 |

10 | 11 | 12 | 13 | 1. 위 화면에서 자신의 맥 OS 버전에 맞는 파일을 선택해서 다운로드합니다. 다운로드가 완료된 파일을 실행 후 안내에 따르면 설치가 완료됩니다. 14 | 15 | ​ 16 | 17 |

18 | 19 | ​ 20 | 21 | 2. 파이썬 설치가 정상적으로 완료됐는지 확인하기 위해서는 터미널을 실행합니다. 터미널 창에 ‘python3’ 명령어를 입력했을 때 다음 화면과 같이 출력된다면 정상적으로 설치된 것입니다. 22 | 23 | ​ 24 | 25 |

26 | 27 | ​ 28 | 29 | ### 1.2 파이참 커뮤니티 설치 및 환경 설정 30 | 31 | 파이참의 설치 및 환경 설정은 다음과 같은 순서로 진행합니다. 32 | 33 | 1. 파이참 홈페이지[[Link]](https://www.jetbrains.com/pycharm/)에 접속하여 커뮤니티버전을 다운로드합니다. 34 | 35 | 2. 다운로드가 완료된 파일을 실행하고아래 그림에서 왼쪽 PyCharm CE 아이콘을 오른쪽 폴더 아이콘으로 드래그하면 설치가 완료됩니다. 36 | 37 |

38 | 39 | 3. 처음 파이참을 실행하게 되면 설정화면이 나오는데 IDE theme을 통해 IDE의 색상과 스타일을 변경할 수 있습니다. Default는 우분투의 개발환경설정에서 봤던 Intellij 테마입니다. 이 책에서는 Default를 사용할 것입니다. 40 | ​ 41 | 42 | 4. 초기 설정을 완료하고 Create New Project 버튼을 클릭합니다. 43 | 44 | ​ 45 | 46 | 5. Create New Project 버튼을 클릭하면 아래 그림과 같은 화면이 나옵니다. Location은 프로젝트가 생성될 경로와 프로젝트 폴더명을 설정하는 곳입니다. 프로젝트의 이름과 경로는 독자가 임의로 지정하면 됩니다. 47 | 48 | Interpreter는 프로젝트에서 어떤 파이썬 Interpreter를 사용할 것인지 고르는 것입니다. 우분투에서와 마찬가지로 VirtualEnv를 통해 가상 환경을 만들고 그것을 Interpreter로 사용할 것입니다. Create VirtualEnv 버튼을 누릅니다. 49 | 50 | ​ 51 | 52 |

53 | 54 | ​ 55 | 56 | 6. 아래 그림은 VirtualEnv의 생성화면입니다. Name과 Location은 여러분이 임의로 설정하면 됩니다. Base Interpreter는 위와 같이 새로 설치한 python3.5 를 선택합니다. OK버튼을 누르면 해당 VirtualEnv가 생성됩니다. 57 | 58 | ​ 59 | 60 |

61 | 62 | ​ 63 | 64 | 7. 처음 New Project 생성화면의 Interpreter에서 방금 생성한 VirtualEnv를 선택해줍니다. 그리고 Create버튼을 누르면 프로젝트 생성이 완료됩니다. 65 | 66 | ​ 67 | 68 |

69 | 70 | ​ 71 | 72 | 8. 프로젝트를 생성하고 나면 다음과 같은 작업 환경이 보입니다. 이 화면에서 최상위 폴더를 우클릭한 후 73 | 74 | New -> Python File을 클릭하면 새로운 파이썬 파일을 생성할 수 있습니다. 75 | 76 | ​ 77 | 78 |

79 | 80 | ​ 81 | 82 | 9. 파이참이 제대로 설치됐는지 확인하기 위해 hello world 예제를 실행해봅니다. 우분투에서와 동일하기 때문에 생략하겠습니다. 83 | 84 | ​ 85 | 86 | ### 1.3 오픈에이아이 설치 87 | 88 | 2016년에 오픈에이아이(OpenAI)라는 회사가 세워졌습니다. 이 회사의 목표는 인공지능 기술을 전 세계에공개해서 더 안전한 인공지능을 만들어가며 더 많은 분야에 인공지능을 도입하는 것입니다. 오픈에이아이 짐(Gym)는 오픈에이아이에서 만든 환경인데여기서 여러가지 인공지능 알고리즘을 테스트 해볼 수 있습니다. 89 | 90 | 오픈에이아이짐의 코드는 모두 오픈에이아이의 깃허브(Github)[[Link]](https://github.com/openai/gym)에업로드되어있습니다. 91 | 92 |

93 | 94 | 95 | 96 | 오픈에이아이 짐의 설치는 공식 홈페이지에 설명되어있습니다. 오픈에이아이짐을 설치하기 위해서는 깃(Git)를 먼저 설치해줘야 합니다. 깃(Git)은 버전 관리 도구로서개발 프로세스에서 버전 관리가 필요할 때 주로 사용합니다. 오픈에이아이는 오픈소스로 깃헙(Github)에 공개되어 있습니다. 깃헙은 버전관리되는 소스 코드들의원격 저장소 역할을 하는 플랫폼입니다. 97 | 98 | 다음과 같은 명령어로 깃를 설치합니다. 99 | 100 | ```shell 101 | $ sudo apt-get install git 102 | ``` 103 | 104 | 105 | 106 | 깃을 설치한 다음에 오픈에이아이 짐을 설치합니다. 터미널 창에서 오픈에이아이 짐을 설치할 디렉토리로 이동한 다음에 다음과 같은 명령어를 실행합니다. 설치할 때는 파이참에서 생성한 VirtualEnv의 파이썬으로 설치해야 합니다. 107 | 108 | ```shell 109 | $ git clone https://github.com/openai/gym 110 | $ cd gym 111 | $ pip install -e . 112 | ``` 113 | 114 | 115 | 116 | 오픈에이아이 짐은 여러가지 다른 설정으로 설치할 수 있는데 pip install -e .은 가장 기본적인 부분들만 설치하는 것입니다. 이후에 아타리 게임 등 오픈에이아이 짐의 모든 게임들을 사용하려면 pip install -e . 대신에 다음과 같이 입력해야 합니다. 117 | 118 | ``` shell 119 | $ pip install -e '.[all]' 120 | ``` 121 | 122 | 123 | 124 | ### 1.4 예제 테스트 125 | 126 | ### 1.4.1 카트폴 127 | 128 | 오픈에이아이 짐이 정상적으로 설치되었는지 확인하기 위해서 간단한 예제를 실행해봅니다. 오픈에이아이 짐의 가장 간단한 예제는 카트폴(CartPole)입니다. 카트폴은 카트에 진자가 달린 형태로 이 문제의 목표는 카트를 움직여서 그 반동으로 진자를 세우는 것입니다. 테스트할 때는 그냥 아무 입력도 카트폴에 주지 않은 상태로 오픈에이아이 짐이 제대로 실행되는지만 확인할 것입니다. 129 | 130 | `CartPole.py` 파일을 생성하고 아래와 같이 입력합니다. 131 | 132 | ```python 133 | import gym 134 | env = gym.make('CartPole-v0') 135 | env.reset() 136 | for _ in range(1000): 137 | env.render() 138 | env.step(env.action_space.sample()) # take a random action 139 | ``` 140 | 141 | ​ 카트폴 예제 실행 코드 142 | 143 | 이 코드를 실행하면 화면에 아무 행동도 하지 않는 카트폴이 실행됩니다. 오픈에이아이 짐은 이와 같은 많은 문제들을 제공하며 사용자들은 오픈에이아이 짐의 여러가지 문제에 자신의 학습 알고리즘을 적용해볼 수 있습니다. 또한 오픈에이아이 짐 사이트에 자신의 알고리즘을 공유하거나 결과를 확인할 수 있습니다. 144 | 145 | 146 | 147 |

148 | 149 | 150 | 151 | ### 1.4.2 아타리 브레이크아웃 152 | 153 | 위에서 오픈에이아이를 전체 설치 했기 때문에 아타리 브레이크 아웃 예제를 테스트 해볼 수 있습니다. 154 | 155 | 브레이크 아웃을 테스트 하기 위한 테스트는 rlcode 깃헙 레포지토리에 있는 ``3-atari/1-breakout/breakout_dqn.py`` 예제를 사용하겠습니다. 156 | 157 | 우선 해당 파이썬 코드가 있는 디렉토리로 이동합니다. 158 | 159 | ```shell 160 | $cd 3-atari/1-breakout 161 | ``` 162 | 163 | ``breakout_dqn.py`` 코드는 카트폴 테스트 예제에 비해 코드량이 많으므로 전체는 생략하겠습니다. 164 | 165 | 다음 명령어로 ``breakout_dqn.py`` 를 실행합니다. 166 | 167 | ```shell 168 | $python breakout_dqn.py 169 | ``` 170 | 171 | dqn알고리즘을 실행하기 때문에 컴퓨터 사양에 따라 렌더링되는 시간이 다를 수 있습니다. 172 | 173 | 아래 그림은 실행화면 입니다. 174 | 175 |

176 | -------------------------------------------------------------------------------- /wiki/install_guide_ubuntu.md: -------------------------------------------------------------------------------- 1 | ## 개발 환경 설정 1: 리눅스 (우분투) 2 | 3 | 리눅스는 소스코드가 공개된 대표적인 오픈소스 운영체제입니다. 리눅스는 모든 소스가 공개되어 있으므로 정말 많은 종류가 있습니다. 그중에서도 우분투(Ubuntu)가 가장 넓은 사용자를 가진 배포판입니다. 매년 상반기 하반기 우분투 재단에서 새로운 버전을 배포하는데 이 책에서는 14년 상반기에 배포한 우분투 14.04 버전을 사용할 것입니다. 우분투 14.04가 설치되어 있다는 가정에 따라 이후의 개발환경 설정을 설명할 것입니다. 4 | 5 | 6 | 7 | ### 1.1 우분투 파이썬의 버전 확인 8 | 9 | 리눅스의 장점은 바로 파이썬(Python)이 설치가 기본적으로 되어 있다는 것입니다. 파이썬은 2.X 버전과 3.X버전이 있는데 이 책에서는 `파이썬 3.5버전`을 사용할 것입니다. 바탕화면에서 `Ctrl+Alt+t`를 누르면 터미널 창이 뜨는데 10 | 여기에 다음 명령어를 치고 엔터를 누르면 설치된 파이썬의 버전을 확인할 수 있습니다. 11 | 12 | ```shell 13 | $ python -V 14 | ``` 15 | 16 | 우분투 14.04 버전에는 `파이썬 2.7버전`과 `3.5버전`이 기본적으로 설치되어 있습니다. 17 | 18 | 19 | 20 | ### 1.2 파이참 커뮤니티 설치 및 환경 설정 21 | 22 | 앞으로 강화학습 에이전트를 만들고 가상 환경에서 에이전트를 학습시킬 것입니다. 그러기 위해 코드를 짜고 편집하는 23 | 환경이 필요한데 그러한 환경을 IDE(interface Development Environment)라고 합니다. IDE에는 많은 종류가 있지만 이 책에서는 파이참(Pycharm)을 파이썬을 위한 IDE로 사용할 것입니다. 24 | 25 | 파이참의 설치는 파이참의 공식 홈페이지[[1\]](#_ftn1)를통해서 할 수 있습니다. 홈페이지에서 윈도우, 리눅스, 맥 OS 버전의 파이참을 다운로드 할 수 있습니다. 파이참은 유료 버전인 `프로페셔녈(PyCharm ProfessionalEdition)`과, 무료 버전인 `커뮤니티(PyCharm Community Edition)`으로 나뉩니다. 앞으로 에이전트를 개발할 때 `파이참 커뮤니티`를 사용할 것이므로 커뮤니티 버전을 기준으로 설치법을 설명할 것입니다. 26 | 27 | 28 | 29 | **설치는 다음과 같은 순서로 진행합니다.** 30 | 31 | 1. 파이참 공식 홈페이지[[Link]](https://www.jetbrains.com/pycharm/download/#section=linux) 링크에서 파이참 커뮤니티버전을 다운로드합니다. 32 | 33 | 34 |

35 | 36 | ​ 37 | 38 | 2. 다운받은 경로로 들어가서 다음 명령어로 압축파일을 풀어줍니다. 39 | 40 | ```shell 41 | $ tar xfz pycharm-community-2016.3.2.tar.gz 42 | ``` 43 | 44 | 45 | 46 | 47 | 3. 압축을 푼 후 아래 경로(bin폴더)로 이동합니다. 48 | 49 | ```shell 50 | $ cd ~/pycharm-community-2016.3.2/bin 51 | ``` 52 | ​ 53 | 54 | 4. 다음 명령어로 파이참을 실행합니다. 55 | 56 | ```shell 57 | $ sh pycharm.sh 58 | ``` 59 | ​ 60 | 61 |

62 | 63 | ​ 64 | 65 | 66 | 5. 명령어가 실행되면 설치가 시작됩니다. 67 | 68 | ​ 69 | 70 | 6. 설치가 완료되면 다음 화면과 같은 초기 환경설정 화면을 볼 수 있습니다. 71 | 72 | ​ 73 | 74 |

75 | 76 | ​ 77 | 78 | IDE theme 항목에서 Intellij는 바탕이 흰색인 테마이고 Darcula 테마는 바탕이 검은색입니다. 이 79 | 책에서는 Intellij를 테마로 사용합니다. 80 | 81 | ​ 82 | 83 | 7. 초기설정이 완료된 후의 화면입니다. 여기서 프로젝트 생성을 해봅니다. 84 | 85 |

86 | 87 | ​ 88 | 89 | ​ 90 | 91 | 8. 프로젝트의 경로와 Interpreter를 설정하는 화면입니다. Home 디렉터리에 PycharmProjects 폴더를 생성하고 그 하위에 프로젝트를 생성합니다. 프로젝트의 이름은 독자가 임의로 정하도록 합니다. “rlcode_book” 이름으로 프로젝트를 생성하는데 Interpreter를 설정해줍니다. Interpreter는 이 프로젝트에서 사용할 언어인데 python 3.5라고 설정합니다. 92 | 93 | ​ 94 | 95 |

96 | ​ 97 | 98 | 9. rlcode_book 프로젝트가 생성되면 아래와 같은 화면이 나옵니다. 99 | 100 | ​ 101 | 102 |

103 | 104 | ​ 105 | 106 | ​ 107 | 108 | 10. 파이참이 정상적으로 설치되었는지 확인하기 위해 파이썬 스크립트 파일을 생성해봅니다. 가장 간단한 예제인 `“Hello World”`를 실행하기 위해 다음과 같이 hello_world.py 파일을 생성합니다. 109 | ​ 110 | 111 |

112 | ​ 113 | 114 | 11. 생성한 파일에 마우스 커서를 놓고 오른쪽 버튼을 누르면 여러 항목이 나옵니다. 그 중에서 “Run ‘hello_world’” 버튼을 누르면 hello_world.py 파일을 실행할 수 있습니다. 115 | ​ 116 | 117 |

118 | 119 | 120 | 121 | 12. hello_world.py 파일 안에 다음 코드를 입력합니다. 122 | ```python 123 | print("hello world") 124 | ``` 125 | 126 | 127 | 128 | 129 | 13. hello_world.py 파일을 실행시키면 아래 화면과 같이 실행 창에 “hello world”가 나옵니다. 이를 통해 파이참이 정상적으로 설치된 것을 확인할 수 있습니다. 130 | 131 | ​ 132 | 133 |

134 | 135 | ​ 136 | 137 | 138 | ### Virtualenv(가상환경) 사용법 139 | 140 | 여기까지가기본적인 파이참의 환경설정입니다. 한 컴퓨터에서 여러가지 프로젝트를 진행할 경우에 프로젝트마다 개발환경이다를 수 있습니다. 서로 다른 프로젝트의 개발환경이 다를 경우에 사용자는 상당한 불편을 겪을 수 있습니다. 따라서 프로젝트별로 개발환경을 분리해서 관리하는 것은 상당한 장점이 있는데 그 기능을 하는 것이 VirtualEnv입니다. VirtualEnv를 사용하면 이 책의 프로젝트만을위한 가상 개발환경을 만들 수 있습니다. 141 | 142 | 파이참은VirtualEnv를 지원하기 때문에 파이참으로 VirtualEnv를사용하는 법을 설명하겠습니다. VirtualEnv의 설치 및 사용 방법은 여러 가지가 있지만 위에서설치한 파이참을 이용하면 GUI(graphic user interface)형식으로 VirtualEnv를 사용할 수 있습니다. 그리고 파이참은 가상 개발환경에설치된 다양한 파이썬 외부 라이브러리들을 관리 할 수 있는 기능을 제공합니다. 143 | 144 | **파이참에서 VirtualEnv 이용방법은 다음과 같습니다.** 145 | 146 | 1. “File” 메뉴에서 “Settings”를 클릭합니다. 147 | 148 | ​ 149 | 150 |

151 | 152 | ​ 153 | 154 | 2. Settings의 왼쪽 목록에서 “Project: 프로젝트명”의 하위 항목인 Project Interpreter 클릭합니다. 그리고 Project Interpreter 탭 오른쪽에서 “Create VirtualEnv”를 클릭합니다. 155 | 156 | ​ 157 | 158 |

159 | 160 | ​ 161 | 162 | 3. 가상환경 이름을 입력하면 /home/brian/rlcode_book 디렉토리가 생성되어 가상환경이 생깁니다. 163 | 164 | ​ 165 | 166 |

167 | 168 | ​ 169 | 170 | 4. 아래와 같이 터미널 창에 (rlcode_book) 표시가 된다면 rlcode_book이름을 가진 가상 환경이 생긴 것입니다. 이제 이 환경을 이 책을 위한 가상환경으로 사용하겠습니다. 171 | 172 | ​ 173 | 174 |

175 | 176 | ​ 177 | 178 | ### 1.3 오픈에이아이 설치 179 | 180 | 2016년에 오픈에이아이(OpenAI)라는 회사가 세워졌습니다. 이 회사의 목표는 인공지능 기술을 전 세계에공개해서 더 안전한 인공지능을 만들어가며 더 많은 분야에 인공지능을 도입하는 것입니다. 오픈에이아이 짐(Gym)는 오픈에이아이에서 만든 환경인데여기서 여러가지 인공지능 알고리즘을 테스트 해볼 수 있습니다. 181 | 182 | 오픈에이아이짐의 코드는 모두 오픈에이아이의 깃허브(Github)[[2\]](#_ftn1)에업로드되어있습니다. 183 | 184 |

185 | 186 | 187 | 188 | 오픈에이아이 짐의 설치는 공식 홈페이지에 설명되어있습니다. 오픈에이아이짐을 설치하기 위해서는 깃(Git)를 먼저 설치해줘야 합니다. 깃(Git)은 버전 관리 도구로서개발 프로세스에서 버전 관리가 필요할 때 주로 사용합니다. 오픈에이아이는 오픈소스로 깃헙(Github)에 공개되어 있습니다. 깃헙은 버전관리되는 소스 코드들의원격 저장소 역할을 하는 플랫폼입니다. 189 | 190 | 다음과 같은 명령어로 깃를 설치합니다. 191 | 192 | ```shell 193 | $ sudo apt-get install git 194 | ``` 195 | 196 | 197 | 198 | 깃을 설치한 다음에 오픈에이아이 짐을 설치합니다. 터미널 창에서 오픈에이아이 짐을 설치할 디렉토리로 이동한 다음에 다음과 같은 명령어를 실행합니다. 199 | 200 | ```shell 201 | $ git clone https://github.com/openai/gym 202 | $ cd gym 203 | $ pip3 install -e 204 | ``` 205 | 206 | 207 | 208 | 오픈에이아이 짐은 여러가지 다른 설정으로 설치할 수 있는데 `pip install -e .`은 가장 기본적인 부분들만 설치하는 것입니다. 이후에 아타리 게임 등 오픈에이아이 짐의 모든 게임들을 사용하려면 `pip install -e .` 대신에 다음과 같이 입력해야 합니다. 209 | 210 | ```shell 211 | $ pip3 install -e .[all] 212 | ``` 213 | 214 | 215 | 216 | ### 1.4 예제 테스트 217 | 218 | ### 1.4.1 카트폴 219 | 220 | 오픈에이아이 짐이 정상적으로 설치되었는지 확인하기 위해서 간단한 예제를 실행해봅니다. 오픈에이아이 짐의 가장 간단한 예제는 카트폴(CartPole)입니다. 카트폴은 카트에 진자가 달린 형태로 이 문제의 목표는 카트를 움직여서 그 반동으로 진자를 세우는 것입니다. 테스트할 때는 그냥 아무 입력도 카트폴에 주지 않은 상태로 오픈에이아이 짐이 제대로 실행되는지만 확인할 것입니다. 221 | 222 | `CartPole.py` 파일을 생성하고 아래와 같이 입력합니다. 223 | 224 | ```python 225 | import gym 226 | env = gym.make('CartPole-v0') 227 | env.reset() 228 | for _ in range(1000): 229 | env.render() 230 | env.step(env.action_space.sample()) # take a random action 231 | ``` 232 | 233 | ​ 카트폴 예제 실행 코드 234 | 235 | 236 | 이 코드를 실행하면 화면에 아무 행동도 하지 않는 카트폴이 실행됩니다. 오픈에이아이 짐은 이와 같은 많은 문제들을 제공하며 사용자들은 오픈에이아이 짐의 여러가지 문제에 자신의 학습 알고리즘을 적용해볼 수 있습니다. 또한 오픈에이아이 짐 사이트에 자신의 알고리즘을 공유하거나 결과를 확인할 수 있습니다. 237 | 238 | 239 | 240 |

241 | 242 | 243 | 244 | ### 1.4.2 아타리 브레이크아웃 245 | 246 | 위에서 오픈에이아이를 전체 설치 했기 때문에 아타리 브레이크 아웃 예제를 테스트 해볼 수 있습니다. 247 | 248 | 브레이크 아웃을 테스트 하기 위한 테스트는 rlcode 깃헙 레포지토리에 있는 ``3-atari/1-breakout/breakout_dqn.py`` 예제를 사용하겠습니다. 249 | 250 | 우선 해당 파이썬 코드가 있는 디렉토리로 이동합니다. 251 | 252 | ```shell 253 | $cd 3-atari/1-breakout 254 | ``` 255 | 256 | ``breakout_dqn.py`` 코드는 카트폴 테스트 예제에 비해 코드량이 많으므로 전체는 생략하겠습니다. 257 | 258 | 다음 명령어로 ``breakout_dqn.py`` 를 실행합니다. 259 | 260 | ```shell 261 | $python breakout_dqn.py 262 | ``` 263 | 264 | dqn알고리즘을 실행하기 때문에 컴퓨터 사양에 따라 렌더링되는 시간이 다를 수 있습니다. 265 | 266 | 아래 그림은 실행화면 입니다. 267 | 268 |

269 | 270 | -------------------------------------------------------------------------------- /wiki/install_guide_window.md: -------------------------------------------------------------------------------- 1 | ## 윈도우 설치(윈도우 10 권장) 2 | 3 | 현재 Open ai gym에서 공식 github의 issue[[link]](https://github.com/openai/gym/issues/11) 에 따르면 Openai gym은 공식적으로 윈도우 환경에 대한 설치를 제공하고 있지 않습니다. 4 | 5 | 그래서 윈도우 사용자는 우분투와 맥 운영체제와 달리 아타리 브레이크 아웃을 실행시키기 위한 추가 환경 설치를 해야합니다. 6 | 7 | 윈도우에서 책에 있는 예제를 실행시키기 위해 다음 항목들을 필요로 합니다. 8 | 9 | - python 3.5 10 | - Numpy, scipy 11 | - Pycharm(IDE) 12 | - Git 13 | - Open ai Gym 14 | - atari.py(github에서 설치) 15 | - MSYS2 16 | - Xming 17 | 18 | ### 1. 파이썬 설치 19 | 20 | - 파이썬은 공식 홈페이지[[link]](https://www.python.org/downloads/windows/)에서 다운로드 할 수 있습니다. 3.5버전의 64bit 설치를 권장합니다. 21 | 22 | 23 | 24 | - 파이썬 인스톨러 실행 화면입니다. 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ### 2. Numpy, spicy 설치 33 | 34 | - Numpy, scipy는 바이너리 파일을 다운로드하여 pip (파이썬 패키지 관리자)를 이용해 설치합니다. 바이너리 파일은 다음 링크에서 다운로드 할 수 있습니다. 35 | 36 | 링크 : [http://www.lfd.uci.edu/~gohlke/pythonlibs/](http://www.lfd.uci.edu/~gohlke/pythonlibs/) 37 | 38 | 39 | 40 | - 바이너리 파일(확장자 whl)을 윈도우 명령어창(cmd)에서 pip를 통해 설치합니다. 41 | 42 | 43 | 44 | 45 | 46 | ### 3. 파이참 설치 47 | 48 | - 파이썬을 좀 더 편리하게 사용하기 위해 IDE(interface development environment)사용을 권장합니다. 파이참은 공식 홈페이지에서 다운로드하여 설치할 수 있습니다. [[link](https://www.jetbrains.com/pycharm/download/#section=windows)] 49 | 50 | - 파이참 설치 화면 입니다. 51 | 52 | 53 | 54 | ​ 55 | 56 | - 프로젝트 생성 화면입니다. 파이참에서 기본으로 제공하는 PycharmProjects 디렉토리에 rl_book이라는 이름으로 프로젝트를 생성하겠습니다. 57 | 58 | 59 | 60 | ​ 61 | 62 | - rl_book 프로젝트가 생성되었습니다. 63 | 64 | 65 | 66 | ​ 67 | 68 | - <옵션 설정> 69 | 70 | settings에서 파이참의 다양한 설정을 할 수 있습니다. 71 | 72 | 현재 파이참 테마는 Darcula로 설정되어있습니다. 사용자에 따라 원하는 테마를 설정할 수 있습니다. 73 | 74 | 75 | 76 | ​ 77 | 78 | - Setting 왼쪽의 Project : rl_book(프로젝트 명)을 클릭하면 현재 프로젝트의 파이썬 버전과 인터프리터를 설정할 수 있습니다. virtualenv(가상환경)을 생성할 수 있고 현재 프로젝트에 설치된 파이썬 패키지들의 버전들을 확인 할 수 있습니다. 79 | 80 | 81 | 82 | 83 | 84 | ### 4. Git 설치 85 | 86 | - Openai gym과 윈도우 환경에서 openai gym설치 시 카트폴은 기본적인 패키지 설치로 실행이 가능하지만 아타리 브레이크 아웃은 별도로 설치를 해줘야 합니다. 아타라 브레이크아웃은 Github 저장소에서 다운로드하여 설치해야 하므로 Git을 설치해야 합니다. 87 | - 링크 : https://git-scm.com/download 88 | 89 | 90 | 91 | ​ 92 | 93 | - Git 설치 화면입니다. Git 설치가 완료되면 뒤에서 설치할 Openai gym과 atari.py등을 다운로드 할 수 있습니다. 94 | 95 | 96 | 97 | ### 5. Openai Gym 설치 98 | 99 | - 우선, Openai gym의 Github 레포지토리에서 다운로드 받습니다. 100 | 101 | Github 레포지토리에서 다운로드하기 위해 윈도우 명령 프롬프트 창에서 실행하거나, Git bash 둘중에 아무거나 이용하셔도 됩니다. 여기서는 명령 프롬프트를 이용해 진행하겠습니다. 102 | 103 | ```shell 104 | git clone https://github.com/openai/gym 105 | ``` 106 | 107 | 설치 화면 입니다. 108 | 109 | 110 | 111 | 112 | 113 | 114 | - Github 저장소를 다운로드 하였으면 해당 디렉토리로 이동하여 설치를 진행합니다. 115 | 116 | ```shell 117 | cd gym 118 | pip install -e . 119 | ``` 120 | 121 | 122 | 123 | 124 | 125 | - Openai gym을 설치한 후 파이참을 이용해 카트폴을 실행해보겠습니다. 126 | 127 | 카트폴을 간단히 실행하기 위한 코드입니다. 128 | 129 | ```python 130 | import gym 131 | env = gym.make('CartPole-v0') 132 | env.reset() 133 | for _ in range(1000): 134 | env.render() 135 | env.step(env.action_space.sample()) 136 | ``` 137 | 138 | 139 | 140 | 141 | 142 | - 카트폴을 실행 성공 하였을 때의 화면입니다. 143 | 144 | 145 | 146 | ​ 147 | 148 | ### 6. MSYS2 설치 149 | 150 | - 아타리 브레이크아웃을 실행시키기 위해 MSYS2를 설치해야 합니다. 151 | 152 | MSYS2는 윈도우 환경에서 GNU 툴을 이용하기 위한 최소한의 환경을 의미합니다. 153 | 154 | 자세한 설명은 다음 링크를 참조하시면 됩니다. [[link]](http://klutzy.nanabi.org/blog/2015/03/05/mingw/) 155 | 156 | - 다운로드 링크 : http://www.msys2.org/ 157 | 158 | 159 | 160 | 161 | 162 | 163 | - 설치 화면 입니다. 164 | 165 | 166 | 167 | 168 | 169 | - MSYS2를 설치하고 MSYS2 터미널을 실행합니다. 170 | 171 | 터미널에서 다음 명령어를 실행합니다. 172 | 173 | ```shell 174 | $ pacman -S base-devel mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake 175 | ``` 176 | 177 | 178 | 179 | ​ 180 | 181 | - 선택 입력 단계가 나오면 아무 입력을 하지 않고 엔터를 치고 실행하시면 됩니다. 182 | 183 | 184 | 185 | 186 | 187 | ### 7. 내컴퓨터 환경설정 188 | 189 | - 환경변수를 추가 해야 합니다. 190 | 191 | 1. <내컴퓨터> 오른쪽 클릭 192 | 2. <시스템 속성> 선택 193 | 3. <고급 탭> 이동 194 | 4. <환경 변수> 클릭 195 | 196 |  

197 | 198 | 199 | 200 | - 환경변수 창 화면입니다. 201 | 202 | 203 | 204 | 205 | 206 | - <시스템 변수>에서 <새로 만들기>를 클릭 합니다. 207 | 208 | <변수 이름>과 <변수 값>에 다음 값을 입력합니다. 209 | 210 | - 변수 이름 : ``DISPLAY`` 211 | - 변수 값 : ``:0`` 212 | 213 | 214 | 215 | 216 | 217 | - 그리고 한번 더 <새로 만들기>를 클릭합니다. 218 | 219 | - 변수 이름 : ``PYTHONPATH`` 220 | 221 | - 변수 값 : ``C:\path\to\atari.py:$PYTHONPATH`` 222 | 223 | 변수 값에 atari.py가 설치한 경로를 넣으면 됩니다. 224 | 225 | 226 | 227 | 228 | 229 | - <시스템 변수>에서 Path 변수에 MSYS2를 추가합니다. 230 | 231 | 232 | 233 | 234 | 235 | ### 8. Xming 설치 236 | 237 | - 다음 경로에서 다운로드 합니다. 238 | 239 | - 링크 : https://sourceforge.net/projects/xming/?source=directory 240 | 241 | Xming 설치화면 입니다. 242 | 243 | 244 | 245 | 246 | 247 | ### 9. atari.py 설치 248 | 249 | - 아타리 브레이크 아웃을 별도로 설치해줘야 합니다. Github 레포지토리에서 다운로드하여 설치합니다.\ 250 | 251 | ```shell 252 | git clone https://github.com/rybskej/atari-py 253 | ``` 254 | 255 | 256 | 257 | 258 | 259 | - atari.py가 설치된 디렉토리로 이동하고 make 명령어를 실행합니다. 260 | 261 | make실행이 안되면 명령 프롬프트 창을 설치하고 다시 시도합니다. 262 | 263 | ```shell 264 | cd atari-py 265 | make 266 | ``` 267 | 268 | 269 | 270 | 271 | - make 실행 화면입니다. 272 | 273 | 274 | 275 | 276 | 277 | - make가 실행이 완료되면 다음 명령어로 setup.py를 실행합니다. 278 | 279 | ```shell 280 | python setup.py install 281 | ``` 282 | 283 | 284 | 285 | ​ 286 | 287 | setup.py 설치 화면 입니다. 288 | 289 | 290 | 291 | 292 | 293 | - 다음 명령어로 atari.py를 설치 합니다. 294 | 295 | ```shell 296 | $pip install -U git+https://github.com/Kojoley/atari-py.git 297 | ``` 298 | 299 | 300 | 301 | 302 | 303 | ### 10. 텐서플로우, 케라스, scikit-image, h5py 등 라이브러리 설치 304 | 305 | - 책 예제를 GIthub 레포지토리에서 다운로드 받은 후 아래 명령어로 설치합니다. 306 | 307 | - Github 레포지토리 : https://github.com/rlcode/reinforcement-learning-kr 308 | 309 | ```shell 310 | pip install -r requirement.txt 311 | ``` 312 | 313 | ### 11. breakout_dqn.py 실행 314 | 315 | - ``reinforcement-learning-kr/3-atari/1-breakout`` 경로에 있는 ``breakout_dqn.py``를 실행합니다. 316 | 317 | ```python 318 | python breakout_dqn.py 319 | ``` 320 | 321 | 322 | 323 | 324 | 325 | - 아타리 브레이크 아웃 실행화면 입니다. 326 | 327 |

328 | -------------------------------------------------------------------------------- /wiki/install_image/atari_breakout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/atari_breakout.png -------------------------------------------------------------------------------- /wiki/install_image/cartpole_exam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/cartpole_exam.png -------------------------------------------------------------------------------- /wiki/install_image/console_hello_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/console_hello_world.png -------------------------------------------------------------------------------- /wiki/install_image/default_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/default_config.png -------------------------------------------------------------------------------- /wiki/install_image/file_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/file_setting.png -------------------------------------------------------------------------------- /wiki/install_image/hello_world_ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/hello_world_ubuntu.png -------------------------------------------------------------------------------- /wiki/install_image/openai_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/openai_github.png -------------------------------------------------------------------------------- /wiki/install_image/project_interpreter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/project_interpreter.png -------------------------------------------------------------------------------- /wiki/install_image/pycham_new_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/pycham_new_project.png -------------------------------------------------------------------------------- /wiki/install_image/pycharm_community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/pycharm_community.png -------------------------------------------------------------------------------- /wiki/install_image/pycharm_drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/pycharm_drag.png -------------------------------------------------------------------------------- /wiki/install_image/pycharm_init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/pycharm_init.png -------------------------------------------------------------------------------- /wiki/install_image/python3_terminal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/python3_terminal.jpg -------------------------------------------------------------------------------- /wiki/install_image/python_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/python_download.png -------------------------------------------------------------------------------- /wiki/install_image/python_installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/python_installed.png -------------------------------------------------------------------------------- /wiki/install_image/python_intalled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/python_intalled.png -------------------------------------------------------------------------------- /wiki/install_image/rl_book_hello_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/rl_book_hello_world.png -------------------------------------------------------------------------------- /wiki/install_image/rl_book_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/rl_book_project.png -------------------------------------------------------------------------------- /wiki/install_image/rl_book_venv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/rl_book_venv.png -------------------------------------------------------------------------------- /wiki/install_image/rl_book_virtualenv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/rl_book_virtualenv.png -------------------------------------------------------------------------------- /wiki/install_image/rlcode_book_directory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/rlcode_book_directory.png -------------------------------------------------------------------------------- /wiki/install_image/rlcode_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/rlcode_project.png -------------------------------------------------------------------------------- /wiki/install_image/run_hello_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/run_hello_world.png -------------------------------------------------------------------------------- /wiki/install_image/sh_pycharm.sh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/sh_pycharm.sh.png -------------------------------------------------------------------------------- /wiki/install_image/terminal_rlcode_book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlcode/reinforcement-learning-kr/c336961d9d67ec9d53694a30c6e28f92f51ea947/wiki/install_image/terminal_rlcode_book.png --------------------------------------------------------------------------------