Как я могу изменить это, чтобы использовать таблицу q для обучения подкрепления - PullRequest
2 голосов
/ 21 июня 2019

Я работаю над изучением q-таблиц и пробежался по простой версии, в которой использовался только одномерный массив для перемещения вперед и назад. сейчас я пробую движение в 4 направлениях и застрял в управлении человеком.

Теперь я получил случайное движение, и оно в итоге найдет цель. но я хочу, чтобы он научился добираться до цели, а не случайно наткнулся на нее. Поэтому я был бы признателен за любые советы по добавлению qlearning в этот код. Спасибо.

Вот мой полный код, так как он прямо сейчас глуп.

import numpy as np
import random
import math

world = np.zeros((5,5))
print(world)
# Make sure that it can never be 0 i.e the start point
goal_x = random.randint(1,4)
goal_y = random.randint(1,4)
goal = (goal_x, goal_y)
print(goal)
world[goal] = 1
print(world)

LEFT = 0
RIGHT = 1
UP = 2
DOWN = 3
map_range_min = 0
map_range_max = 5

class Agent:
    def __init__(self, current_position, my_goal, world):
        self.current_position = current_position
        self.last_postion = current_position
        self.visited_positions = []
        self.goal = my_goal
        self.last_reward = 0
        self.totalReward = 0
        self.q_table = world


    # Update the totoal reward by the reward        
    def updateReward(self, extra_reward):
        # This will either increase or decrese the total reward for the episode
        x = (self.goal[0] - self.current_position[0]) **2
        y = (self.goal[1] - self.current_position[1]) **2
        dist = math.sqrt(x + y)
        complet_reward = dist + extra_reward
        self.totalReward += complet_reward 

    def validate_move(self):
        valid_move_set = []
        # Check for x ranges
        if map_range_min < self.current_position[0] < map_range_max:
            valid_move_set.append(LEFT)
            valid_move_set.append(RIGHT)
        elif map_range_min == self.current_position[0]:
            valid_move_set.append(RIGHT)
        else:
            valid_move_set.append(LEFT)
        # Check for Y ranges
        if map_range_min < self.current_position[1] < map_range_max:
            valid_move_set.append(UP)
            valid_move_set.append(DOWN)
        elif map_range_min == self.current_position[1]:
            valid_move_set.append(DOWN)
        else:
            valid_move_set.append(UP)
        return valid_move_set

    # Make the agent move
    def move_right(self):
        self.last_postion = self.current_position
        x = self.current_position[0]
        x += 1
        y = self.current_position[1]
        return (x, y)
    def move_left(self):
        self.last_postion = self.current_position
        x = self.current_position[0]
        x -= 1
        y = self.current_position[1]
        return (x, y)
    def move_down(self):
        self.last_postion = self.current_position
        x = self.current_position[0]
        y = self.current_position[1]
        y += 1
        return (x, y)
    def move_up(self):
        self.last_postion = self.current_position
        x = self.current_position[0]
        y = self.current_position[1]
        y -= 1
        return (x, y)

    def move_agent(self):
        move_set = self.validate_move()
        randChoice = random.randint(0, len(move_set)-1)
        move = move_set[randChoice]
        if move == UP:
            return self.move_up()
        elif move == DOWN:
            return self.move_down()
        elif move == RIGHT:
            return self.move_right()
        else:
            return self.move_left()

    # Update the rewards
    # Return True to kill the episode
    def checkPosition(self):
        if self.current_position == self.goal:
            print("Found Goal")
            self.updateReward(10)
            return False
        else:
            #Chose new direction
            self.current_position = self.move_agent()
            self.visited_positions.append(self.current_position)
            # Currently get nothing for not reaching the goal
            self.updateReward(0)
            return True


gus = Agent((0, 0) , goal)
play = gus.checkPosition()
while play:
    play = gus.checkPosition()

print(gus.totalReward)

1 Ответ

2 голосов
/ 21 июня 2019

У меня есть несколько предложений, основанных на вашем примере кода:

  1. отделить среду от агента. Среда должна иметь метод вида new_state, reward = env.step(old_state, action). Этот метод говорит, как действие превращает ваше старое состояние в новое состояние. Это хорошая идея, чтобы закодировать ваши состояния и действия в виде простых целых чисел. Я настоятельно рекомендую настроить юнит-тесты для этого метода.

  2. агент должен иметь эквивалентный метод action = agent.policy(state, reward). В качестве первого шага вы должны вручную кодировать агента, который делает то, что вы считаете правильным. например, он может просто попытаться направиться к цели.

  3. рассмотрим вопрос о том, является ли государственное представительство марковским. Если бы вы справились с этой задачей лучше, если бы у вас была память обо всех прошлых состояниях, которые вы посетили, то у этого состояния нет свойства Markov. Предпочтительно представление состояния должно быть компактным (наименьшее множество, все еще марковское).

  4. как только эта структура настроена, вы можете подумать о том, чтобы действительно изучить таблицу Q. Одним из возможных методов (который легко понять, но не обязательно, что он эффективен) является метод Монте-Карло, включающий либо исследования старта, либо эпсилон-мягкую жадность. Хорошая книга по RL должна содержать псевдокод для любого варианта.

Если вы чувствуете себя уверенно, отправляйтесь в тренажерный зал openai https://gym.openai.com/, чтобы получить более подробные сведения о классах. Здесь есть несколько советов по созданию собственной среды: https://gym.openai.com/docs/#environments

...