как мне определить состояние для моей среды, подобной сетке?

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

поэтому у меня есть матрица 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

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

Другие вопросы по тегам