как мне определить состояние для моего gridworld, такого как среда?

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

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

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

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

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

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

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

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

но я не получаю никаких хороших результатов! это так же, как его случайное! Я пробовал разные функции вознаграждения, разные алгоритмы оптимизации, такие как воспроизведение опыта, целевая сеть, двойное 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

person hosseinoj    schedule 12.04.2020    source источник


Ответы (1)


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

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 есть ошибка. Если это сработает, вы можете начать увеличивать размер сетки и размер сети.

person dilaudid    schedule 12.04.2020
comment
Большое спасибо за помощь! я попробовал то, что вы рекомендовали. поэтому я назначил матрицу для позиции, как вы упомянули, сгладил ее и добавил к сглаженной матрице конфигурации. подал его в сеть, и я все еще не получил никаких хороших результатов. по-прежнему кажется случайным и даже ухудшается после многих итераций. :( - person hosseinoj; 13.04.2020
comment
Если агент не учится, на это может быть много причин - может быть, вы недостаточно долго ждете (обычно агенту требуется около тысячи игр, чтобы выучить даже самую простую вещь), это может быть будь то ваша скорость обучения слишком высока или слишком низка, или это может быть ошибка в вашей реализации алгоритма обучения. Если хотите, вы можете опубликовать более подробную информацию о том, что вы делаете - это SARSA или Q-learning, какую модель вы используете (глубокая нейронная сеть? Сколько слоев/узлов). Я добавил к основному ответу два общих пункта - tl: dr максимально упростить. - person dilaudid; 13.04.2020
comment
Я попытался немного изменить свои гиперпараметры, и для случая 3x3 это сработало! моя гамма была 0,9999, и я изменил ее на 0,8. я надеюсь, что та же самая стратегия может помочь мне с реальным проектом! это было большим подспорьем! большое спасибо! - person hosseinoj; 13.04.2020
comment
Спасибо - если вас это устраивает, примите мой ответ! Также эпсилон 0,9999 очень высок, обычно 0,95-0,99 являются более обычными значениями. - person dilaudid; 13.04.2020
comment
да конечно я сделал! извините, это был мой первый вопрос о stackoverflow, я даже не знал, что это такое, ха-ха! - person hosseinoj; 14.04.2020