Как я должен определить состояние для моего gridworld, как среда? - PullRequest
1 голос
/ 12 апреля 2020

Проблема, которую я хочу решить, на самом деле не так проста, но это своего рода игрушечная игра, которая поможет мне решить большую проблему.

, поэтому у меня есть матрица 5x5 со значениями, равными 0:

structure = np.zeros(25).reshape(5, 5)

, и цель в том, чтобы агент превратил все значения в 1, поэтому у меня есть:

goal_structure = np.ones(25).reshape(5, 5)

Я создал класс Player с 5 действиями для go влево , вправо, вверх, вниз или отразить (поверните значение от 0 до 1 или от 1 до 0). За вознаграждение, если агент меняет значение 0 на 1, он получает +1 вознаграждение. если он превращает 1 в 0, получает отрицательное вознаграждение (я пробовал много значений от -1 до 0 или даже -0.1). и если он просто идет влево, вправо, вверх или вниз, он получает вознаграждение 0.

Поскольку я хочу передать состояние в свой нейронный net, я изменил состояние, как показано ниже:

reshaped_structure = np.reshape(structure, (1, 25))

и затем я добавляю нормализованную позицию агента в конец этого массива (потому что я полагаю, что агент должен иметь представление о том, где он находится):

reshaped_state = np.append(reshaped_structure, (np.float64(self.x/4), np.float64(self.y/4)))
state = reshaped_state

но я не получаю любые хорошие результаты! это так же, как случайное! Я пробовал разные функции вознаграждения, разные алгоритмы оптимизации, такие как воспроизведение Exeperience, цель net, Double DQN, дуэли, но ни одна из них, похоже, не работает! и я думаю, что проблема с определением государства. Может ли кто-нибудь помочь мне с определением хорошего состояния?

Большое спасибо!

ps: это моя пошаговая функция:

class Player:

def __init__(self):
    self.x = 0
    self.y = 0

    self.max_time_step = 50
    self.time_step = 0
    self.reward_list = []
    self.sum_reward_list = []
    self.sum_rewards = []

    self.gather_positions = []
    # self.dict = {}

    self.action_space = spaces.Discrete(5)
    self.observation_space = 27

def get_done(self, time_step):

    if time_step == self.max_time_step:
        done = True

    else:
        done = False

    return done

def flip_pixel(self):

    if structure[self.x][self.y] == 1:
        structure[self.x][self.y] = 0.0

    elif structure[self.x][self.y] == 0:
        structure[self.x][self.y] = 1

def step(self, action, time_step):

    reward = 0

    if action == right:

        if self.y < y_threshold:
            self.y = self.y + 1
        else:
            self.y = y_threshold

    if action == left:

        if self.y > y_min:
            self.y = self.y - 1
        else:
            self.y = y_min

    if action == up:

        if self.x > x_min:
            self.x = self.x - 1
        else:
            self.x = x_min

    if action == down:

        if self.x < x_threshold:
            self.x = self.x + 1
        else:
            self.x = x_threshold

    if action == flip:
        self.flip_pixel()

        if structure[self.x][self.y] == 1:
            reward = 1
        else:
            reward = -0.1



    self.reward_list.append(reward)

    done = self.get_done(time_step)

    reshaped_structure = np.reshape(structure, (1, 25))
    reshaped_state = np.append(reshaped_structure, (np.float64(self.x/4), np.float64(self.y/4)))
    state = reshaped_state

    return state, reward, done

def reset(self):

    structure = np.zeros(25).reshape(5, 5)

    reset_reshaped_structure = np.reshape(structure, (1, 25))
    reset_reshaped_state = np.append(reset_reshaped_structure, (0, 0))
    state = reset_reshaped_state

    self.x = 0
    self.y = 0
    self.reward_list = []

    self.gather_positions = []
    # self.dict.clear()

    return state

1 Ответ

0 голосов
/ 12 апреля 2020

Я бы закодировал позицию агента как матрицу, подобную этой:

0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0

(где агент находится посередине). Конечно, вы должны сгладить это тоже для сети. Таким образом, ваше общее состояние составляет 50 входных значений, 25 для состояний ячеек и 25 для позиции агента.

Когда вы кодируете позицию как два числа с плавающей запятой, то сеть должна выполнить работу, декодирующую точное значение поплавки. Если вы используете явную схему, подобную приведенной выше, для сети очень ясно, где именно находится агент. Это «горячая» кодировка для позиции.

Если вы посмотрите, например, на документы atari DQN, позиция агента всегда явно кодируется нейроном для каждой возможной позиции.

Обратите внимание, что очень хорошая политика для вашего агента - стоять на месте и постоянно менять состояние, за это он получает 0,45 вознаграждения за шаг (+1 за 0 к 1, -0.1 для 1 к 0, разделить на 2 шага). Предполагая совершенную политику, она может заработать только 25, но эта политика принесет 22,5 награды и ее будет очень трудно отучить. Я бы предположил, что агент получает -1 за то, что получил хорошее вознаграждение.


Вы упоминаете, что агент не учится. Могу ли я предложить вам попытаться максимально упростить. Первое предложение - уменьшите длину эпизода до 2 или 3 шагов и уменьшите размер сетки до 1. Посмотрите, может ли агент научиться последовательно устанавливать ячейку в 1. В то же время, упростите мозг вашего агента, так как насколько это возможно. Сократите его до одного выходного слоя - линейной модели с активацией. Это должно быть очень быстро и легко выучить. Если агент не узнает об этом в течение 100 эпизодов, я подозреваю, что в вашей реализации RL есть ошибка. Если это работает, вы можете начать увеличивать размер сетки и размер сети.

...