Ray / Rllib QMIX ничего не изучает - PullRequest
0 голосов
/ 30 апреля 2020

Я хотел попробовать QMIX-реализацию библиотеки Ray / Rllib, но должно быть что-то не так в том, как я ее использую, потому что она, кажется, ничего не изучает. Поскольку я новичок в Ray / Rllib, я начал с примера «TwoStepGame», который библиотека предоставляет в качестве примера на репозитории github (https://github.com/ray-project/ray/blob/master/rllib/examples/twostep_game.py), пытаясь понять, как его использовать. Поскольку для начала этот пример был немного сложным для меня, я настроил его так, чтобы сделать пример максимально простым. Проблема: Qmix, кажется, не учится, означает, что полученное вознаграждение в значительной степени соответствует ожидаемому значению случайной политики.

Позвольте мне объяснить идею моего очень простого эксперимента. У нас есть 2 агента. Каждый агент может совершить 3 действия (Discrete(3)). Если он выполняет действие 0, он получает вознаграждение 0,5, а не 0. Так что это должно быть очень простым заданием, поскольку лучшая политика - это просто выполнение действия 0.

Вот моя реализация:

from gym.spaces import Tuple, MultiDiscrete, Dict, Discrete
import numpy as np

import ray
from ray import tune
from ray.tune import register_env, grid_search
from ray.rllib.env.multi_agent_env import MultiAgentEnv
from ray.rllib.agents.qmix.qmix_policy import ENV_STATE


class TwoStepGame(MultiAgentEnv):
    action_space = Discrete(3)

    def __init__(self, env_config):
        self.counter = 0

    def reset(self):
        return {0: {'obs': np.array([0]), 'state': np.array([0])},
                1: {'obs': np.array([0]), 'state': np.array([0])}}

    def step(self, action_dict):
        self.counter += 1
        move1 = action_dict[0]
        move2 = action_dict[1]
        reward_1 = 0
        reward_2 = 0
        if move1 == 0:
            reward_1 = 0.5
        if move2 == 0:
            reward_2 = 0.5

        obs = {0: {'obs': np.array([0]), 'state': np.array([0])},
               1: {'obs': np.array([0]), 'state': np.array([0])}}
        done = False
        if self.counter > 100:
            self.counter = 0
            done = True

        return obs, {0: reward_1, 1: reward_2}, {"__all__": done}, {}


if __name__ == "__main__":

    grouping = {"group_1": [0, 1]}

    obs_space = Tuple([
        Dict({
            "obs": MultiDiscrete([2]),
            ENV_STATE: MultiDiscrete([3])
        }),
        Dict({
            "obs": MultiDiscrete([2]),
            ENV_STATE: MultiDiscrete([3])
        }),
    ])

    act_space = Tuple([
        TwoStepGame.action_space,
        TwoStepGame.action_space,
    ])

    register_env("grouped_twostep",
        lambda config: TwoStepGame(config).with_agent_groups(
            grouping, obs_space=obs_space, act_space=act_space))

    config = {
        "mixer": grid_search(["qmix"]),
        "env_config": {
            "separate_state_space": True,
            "one_hot_state_encoding": True
        },
    }

    ray.init(num_cpus=1)
    tune.run(
        "QMIX",
        stop={
            "timesteps_total": 100000,
        },
        config=dict(config, **{
            "env": "grouped_twostep",
        }),
    )

и вот результат вывода, когда я запускаю его для 100 000 временных шагов

+----------------------------+------------+-------+---------+--------+------------------+--------+----------+
| Trial name                 | status     | loc   | mixer   |   iter |   total time (s) |     ts |   reward |
|----------------------------+------------+-------+---------+--------+------------------+--------+----------|
| QMIX_grouped_twostep_00000 | TERMINATED |       | qmix    |    100 |          276.796 | 101000 |   33.505 |
+----------------------------+------------+-------+---------+--------+------------------+--------+----------+



Process finished with exit code 0

Как видите, политика кажется случайной, поскольку ожидаемое значение равно 1/3, а итоговое вознаграждение составляет 33.505 (потому что я перезагружаю среду каждые 100 шагов). Мой вопрос: что я не понимаю? Должно быть что-то не так с моей конфигурацией или, возможно, моим пониманием того, как работает rllib. Но поскольку лучшая политика очень проста (просто всегда выполняйте действие 0), мне кажется, что этот алгоритм не может выучить.

...