В этом посте я расскажу о том как создать простую среду для обучения искусственного интеллекта при помощи библиотеки Gym от OpenAI.
OpenAi Gym — это библиотека Python с открытым исходным кодом для разработки и сравнения алгоритмов обучения с подкреплением. Она предоставляет стандартный API для взаимодействия между алгоритмами обучения и средами, а также стандартный набор сред, совместимых с этим API.
Чтобы было проще, мы будем работать сразу на примере. Давайте представим: мы мэр города N, у нас есть один парк, в котором по регламенту должно быть 500 деревьев, но деревья там случайным образом вырастают и умирают. Давайте сделаем среду для агента, который будет: либо вырубать деревья, если их слишком много, либо сажать, если их мало.
Итак, приступим:
Устанавливаем библиотеку
Gym устанавливается стандартно через python pip.
!pip install gym
Импортируем
from gym import Env
from gym.spaces import Discrete, Box, Dict, Tuple, MultiBinary, MultiDiscrete
import numpy as np
import random
Env — класс который позволит нам создать свою собственную среду
Импортируем пространства из gym.spaces для определения действий, которые будут совершаться в среде и состояний среды.
numpy для создания массивов
random для случайной генерации деревьев
Создаем класс для нашей среды
Класс будет иметь 3 функции: Инициализация , функция шага и функция сброса.
Инициализация
Здесь мы пропишем: пространство действий, которые сможет выполнять агент; пространство наблюдения (Возможное количество деревьев); состояние (количество деревьев в данный момент); количество лет нашего правления (один год будет равен одному шагу агента и после окончания всех шагов будет запускаться новый эпизод).
def __init__(self):
#пространство действий дискретно. Три действия: 0-бездействие, 1-высадка дерева, 2-срубить дерево
self.action_space = Discrete(3)
# пространство наблюдения. Возможное количество деревьев от 0 до 1000
self.observation_space = Box(low=np.array([0]), high=np.array([1000]))
# количество деревьев
self.state = 500
# срок нашего правления
self.pravlen_srok = 60
Функция шага
Здесь мы пропишем возможные действия агента, вознаграждение, проверку на окончание нашего срока правления, прибавление и убавление деревьев в парке.
def step(self, action):
#бездействие
if action == 0:
self.state += 0
#сажаем дерево
if action == 1:
self.state += 1
#срубаем дерево
if action == 2:
self.state -= 1
#вычетаем шаг
self.pravlen_srok -= 1
# Награда если количество деревьев равно 500 и штрав если это не так
if self.state == 500:
reward = 100
else:
reward = -100
# проверяем не закончился ли срок правления
if self.pravlen_srok <= 0:
done = True
else:
done = False
# либо умирает одно дерево, либо взростает
self.state += random.randint(-1,1)
info = {}
return self.state, reward, done, info
Сброс
Теперь деревьев в парке снова 500 и наш срок пошел заново
def reset(self):
# Восстанавливаем количество деревьев
self.state = 500
# Восстанавливаем срок правления
self.pravlen_srok = 100
return self.state
Весь наш класс:
class Park(Env):
def __init__(self):
#пространство действий дискретно. Три действия: 0-бездействие, 1-высадка дерева, 2-срубить дерево
self.action_space = Discrete(3)
# пространство наблюдения. Возможное количество деревьев от 0 до 1000
self.observation_space = Box(low=np.array([0]), high=np.array([1000]))
# количество деревьев
self.state = 500
# срок нашего правления
self.pravlen_srok = 60
def step(self, action):
#бездействие
if action == 0:
self.state += 0
#сажаем дерево
if action == 1:
self.state += 1
#срубаем дерево
if action == 2:
self.state -= 1
#вычетаем шаг
self.pravlen_srok -= 1
# Награда если количество деревьев равно 500 и штрав если это не так
if self.state == 500:
reward = 100
else:
reward = -100
# проверяем не закончился ли срок правления
if self.pravlen_srok <= 0:
done = True
else:
done = False
# либо умирает одно дерево, либо взростает
self.state += random.randint(-1,1)
info = {}
return self.state, reward, done, info
def reset(self):
# Восстанавливаем количество деревьев
self.state = 500
# Восстанавливаем срок правления
self.pravlen_srok = 100
return self.state
Все! среда готова! Осталось только ее обучить. Для этого вы можете создать нейросеть с помощью TensorFlow или PyTorch (работать с этой средой можно будет также, как и с встроенными средами от OpenAI Gym, как это сделать вы можете спокойно найти в интернете).
Можем проверить работает ли среда, при помощи случайных действий:
episodes = 12
for episode in range(1, episodes+1):
state = env.reset()
done = False
Schet = 0
while not done:
action = env.action_space.sample()
n_state, reward, done, info = env.step(action)
Schet+=reward
print('Эпизод:{} Счет:{}'.format(episode, Schet))
Полный код:
!pip install gym
from gym import Env
from gym.spaces import Discrete, Box, Dict, Tuple, MultiBinary, MultiDiscrete
import numpy as np
import random
class Park(Env):
def __init__(self):
#пространство действий дискретно. Три действия: 0-бездействие, 1-высадка дерева, 2-срубить дерево
self.action_space = Discrete(3)
# пространство наблюдения. Возможное количество деревьев от 0 до 1000
self.observation_space = Box(low=np.array([0]), high=np.array([1000]))
#
self.state = 500
#
self.pravlen_srok = 60
def step(self, action):
#бездействие
if action == 0:
self.state += 0
#сажаем дерево
if action == 1:
self.state += 1
#срубаем дерево
if action == 2:
self.state -= 1
#вычетаем шаг
self.pravlen_srok -= 1
# Награда если количество деревьев равно 500 и штрав если это не так
if self.state == 500:
reward = 100
else:
reward = -100
# проверяем не закончился ли срок правления
if self.pravlen_srok <= 0:
done = True
else:
done = False
# либо умирает одно дерево, либо взростает
self.state += random.randint(-1,1)
info = {}
return self.state, reward, done, info
def reset(self):
# Восстанавливаем количество деревьев
self.state = 500
# Восстанавливаем срок правления
self.pravlen_srok = 100
return self.state
env = Park()
episodes = 12
for episode in range(1, episodes+1):
state = env.reset()
done = False
Schet = 0
while not done:
action = env.action_space.sample()
n_state, reward, done, info = env.step(action)
Schet+=reward
print('Эпизод:{} Счет:{}'.format(episode, Schet))
'''
Вот что у меня получилось на выходе
Эпизод:1 Счет:-8400
Эпизод:2 Счет:-9200
Эпизод:3 Счет:-8800
Эпизод:4 Счет:-10000
Эпизод:5 Счет:-7200
Эпизод:6 Счет:-9800
Эпизод:7 Счет:-9600
Эпизод:8 Счет:-9000
Эпизод:9 Счет:-9400
Эпизод:10 Счет:-6600
Эпизод:11 Счет:-9200
Эпизод:12 Счет:-9200
'''
Ссылки
Для более сложных сред воспользуйтесь подробным туториалом от OpenAI Gym
Туториалы для обучения сетей в средах OpenAI Gym
Всем спасибо за внимание!