Среды Gymnasium: обзор API
Урок знакомит со стандартным интерфейсом сред RL — библиотекой Gymnasium.
Gymnasium (продолжение OpenAI Gym) — это библиотека и стандарт интерфейса для сред RL: единый способ сбросить среду, сделать шаг и узнать пространства наблюдений и действий.
Зачем нужен общий стандарт
Если каждая среда устроена по-своему, алгоритм приходится переписывать под неё. Gymnasium задаёт единый контракт: любой агент, написанный под этот интерфейс, работает с любой совместимой средой — от CartPole до Atari и роботов в MuJoCo. Это превратило сравнение алгоритмов в честное и воспроизводимое.
Два главных метода
Весь цикл взаимодействия держится на двух функциях, которые мы уже встречали в нашем gridworld.
reset()— начинает новый эпизод, возвращает начальное наблюдение (и словарь info).step(action)— принимает действие и возвращает пять значений:observation, reward, terminated, truncated, info.
Здесь terminated — эпизод завершился естественно (цель/проигрыш), а truncated — прерван по лимиту времени. Их разделение важно для корректного бутстрэппинга: по truncated обрывать оценку будущего не следует.
Пространства наблюдений и действий
Каждая среда объявляет observation_space и action_space. Они бывают дискретными (Discrete(4) — 4 действия) или непрерывными (Box — вектор вещественных чисел). По ним агент понимает, какие действия допустимы и как выглядит состояние, не зная деталей среды.
// Типичный цикл работы с Gymnasium (требует пакет gymnasium, не запускается)
import gymnasium as gym
env = gym.make("CartPole-v1")
obs, info = env.reset(seed=0)
done = False
while not done:
action = env.action_space.sample() // здесь была бы политика агента
obs, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
env.close()Этот API намеренно совпадает по духу с нашим gridworld: функция step возвращает новое состояние, награду и флаг конца. Освоив табличный пример, вы уже понимаете интерфейс Gymnasium.
Воспроизведём интерфейс на чистом Python
Чтобы почувствовать API, обернём наш gridworld в gym-подобный класс — без всяких библиотек.
import random
random.seed(0)
class GridEnv:
action_space = [0, 1, 2, 3] # вверх/вниз/влево/вправо
def reset(self):
self.s = 0
return self.s, {}
def step(self, a):
r, c = divmod(self.s, 4)
if a == 0: r = max(0, r - 1)
elif a == 1: r = min(3, r + 1)
elif a == 2: c = max(0, c - 1)
elif a == 3: c = min(3, c + 1)
self.s = r * 4 + c
terminated = (self.s == 15)
reward = 10.0 if terminated else -1.0
return self.s, reward, terminated, False, {}
env = GridEnv()
obs, info = env.reset()
total = 0.0
for _ in range(8):
a = random.choice(env.action_space) # случайная политика
obs, reward, terminated, truncated, info = env.step(a)
total += reward
if terminated:
break
print("Сумма награды за случайный эпизод:", round(total, 1))
print("Достигнута ли цель:", obs == 15)Вывод:
Сумма награды за случайный эпизод: -8.0 Достигнута ли цель: False
Случайная политика бродит и набирает отрицательную сумму штрафов — ровно поэтому и нужно обучение. Зато API теперь знаком: reset, step, пять возвращаемых значений.
Частые ошибки
- Путать terminated и truncated. По truncated (лимит времени) нельзя обнулять будущую ценность — иначе агент решит, что мир «кончился».
- Игнорировать пространства. Отправка недопустимого действия (вне action_space) ломает среду.
- Не закрывать среду. Для сред с рендером забытый
env.close()оставляет ресурсы открытыми.
Итоги
- Gymnasium — стандартный интерфейс сред RL:
reset()иstep(action). stepвозвращает observation, reward, terminated, truncated, info.- Пространства observation_space и action_space описывают формат состояний и действий.