Подкрепление — это ветвь машинного обучения, в которой мы обучаем агента выполнять некоторые действия, основанные на действии, которое он предпринял, и в результате другая ситуация. От того, благоприятна эта ситуация или нет, зависит, получит ли агент вознаграждение или наказание (скажем, отрицательное вознаграждение). Если ситуация такова, какой мы на самом деле хотим ее видеть, мы вознаграждаем агента, и задача агента состоит в том, чтобы максимизировать его вознаграждение.

Теперь, чтобы лучше понять приведенную выше терминологию, давайте рассмотрим пример. Допустим, вы учите свою собаку играть с вами, бросаете мяч на расстояние 50 м и просите собаку вернуть его вам. Здесь ваша собака является вашим агентом, инаучить вашу собаку, что именно она должна делать, когда вы бросаете мяч, является задачей. Теперь, предположим, что собака поднимается на 35 метров и возвращается без мяча, это было действие, которое предприняла ваша собака, поэтому вы ругаете ее, что является ее отрицательной наградой, она понимает, что это не то, что я должен делать,поэтому в следующий раз, когда вы бросаете мяч, он идет и выполняет другое действие и возвращает мяч вам, а вы в ответ угостите его печеньем, это станет его положительной наградойиэто и есть ситуация(или также называемаясостоянием) мы желали. Таким образом, ваш агент, то есть ваша собака, учится играть.

Отрицательное вознаграждение позволяет нам думать, что это конкретное действие было неправильным, поэтому в следующий раз, когда мы предпримем другое действие, и если мы получим положительное вознаграждение мы следуем этому действию и в то же время пытаемся улучшить его, чтобы найти лучшие способы его выполнения .

Итак, поскольку эта статья посвящена созданию пользовательских сред с помощью OpenAI gym, я предполагаю, что вы знакомы с основными терминами, такими как пространство действий, пространство состояний, пространство наблюдения, задача. Хотя я постараюсь осветить их при построении нашей среды, базовое понимание этого поможет вам лучше понять концепцию.

Допустим, мы создаем индивидуальную среду для дрессировки нашей собаки. Базовая структура среды с использованием тренажерного зала openAI приведена ниже:

from gym import Env
class DogTrain(Env):
    def __init__(self):
        # define your environment
        # action space, observation space
    def step(self, action):
        # take some action
    def render(self, mode="dog"):
        # render your environment (can be a visualisation/print)
    def reset(self):
        # reset your environment

Как правило, это структура пользовательской среды, здесь мы создаем подкласс, который наследуется от класса Env тренажерного зала OpenAI. Четыре метода, которые мы будем использовать (упомянутые выше), один из которых является нашим конструктором def __init__(self), а остальные 3 метода переопределяются из родительского класса, есть и другие методы, которые можно переопределить, но это те, которые определены как @abstractmethods, поэтому мы должны их реализовать, иначе мы получим ошибку NotImplemented, мы можем создать и другие функции в соответствии с нашими потребностями. Вы можете посетить страницу Open AI gym на github, чтобы подробно ознакомиться со структурой. https://github.com/openai/gym/blob/master/gym/core.py

Теперь давайте сформулируем нашу задачу, допустим, вы бросаете мяч на расстояние 50 м, поэтому вашей собаке нужно пройти 50 м, чтобы взять мяч, и еще 50 м, чтобы вернуться, то есть всего 100 м. Итак, здесь наше пространство наблюдения представляет собой непрерывное значение от 0 до 100, пространство наблюдения – это не что иное, как состояние, в котором находится ваш агент после совершаете действие, скажем, например, у вас есть печенье в шкафу, и ваша мать просила вас не есть его, но вы все равно решаете его съесть, и в результате вы получаете хорошую взбучку от своей матери, так что здесь вы получаете треш — это награда (хотя и негативная), а ситуация, в которой вы оказались, — это ваше наблюдение .

Итак, теперь для нашей задачи мы определяем вознаграждение как -1 для расстояния ‹ 50 и 1 для расстояния ==100 и 0 для чего-то среднего (должен сказать, владелец довольно суров). Таким образом, диапазон вознаграждения становится [-1, 0, 1] .

Теперь последняя задача — определить наше пространство действия. Пространство действий — это не что иное, как совокупность всех действий, которые ваш агент может или может выполнять. Для нашей задачи наши действия также непрерывны (могут быть дискретными и т. д.), как и пространство наблюдения, то есть количество пройденного собакой расстояния.

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

Теперь давайте напишем код и выполним случайное действие, чтобы посмотреть, как это работает:

from gym import Env
from gym.spaces import Box, Discrete
import random
class DogTrain(Env):
    def __init__(self):
        # dog runs from 0 to 50, returns from 50 to 0
        self.obs_space = Box(low=0, high=100, shape=(1,))
        
        # amount of distance travelled 
        self.action_space = Box(low=0, high=100, shape=(1,))
        
        # current state 
        self.state = random.randint(0, 10)
        
        # no. of rounds
        self.rounds = 20
        
        # reward collected
        self.collected_reward = -1

Здесь, в приведенном выше фрагменте кода, мы определяем конструктор для определения нашего пространства наблюдения, пространства действия, начального состояния, количества раундов и общего вознаграждения. self.obs_space устанавливается на постоянное значение от 0 до 100, как и self.action_space, так как здесь, в нашем случае, они одинаковы. Количество раундов, которые мы собираемся сыграть, равно 20, а общее вознаграждение равно -1 (также может быть установлено любое значение 0 или 1), чтобы начать с (self.collected_reward), а self.state просто инициализируется случайным числом от 0 до 10 (при условии, что что собака бродит вокруг своего хозяина, прежде чем они начнут играть).

from gym import Env
from gym.spaces import Box, Discrete
import random
class DogTrain(Env):
    def __init__(self):
        # dog runs from 0 to 50, returns from 50 to 0
        self.obs_space = Box(low=0, high=100, shape=(1,))
        
        # amount of distance travelled 
        self.action_space = Box(low=0, high=100, shape=(1,))
        
        # current state 
        self.state = random.randint(0, 10)
        
        # no. of rounds
        self.rounds = 20
        
        # reward collected
        self.collected_reward = -1 
    
    def step(self, action):
        done = False
        info = {}
        rw = 0
        self.rounds -= 1
        
        obs = self.state + action
        
        if obs < 50:
            self.collected_reward += -1
            rw = -1
        elif obs > 50 and obs < 100:
            self.collected_reward += 0
            rw = 0
        else:
            self.collected_reward += 1
            rw = 1
            
        if self.rounds == 0:
            done = True
        
        self.render(action, rw)
            
        return obs, self.collected_reward, done, info

Это основная часть нашего кода, метод step, здесь мы уменьшаем значение раунда на 1 каждый раз, когда вызывается метод, который отслеживает количество сыгранных раундов, obs = self.state + action определяет наше текущее состояние в зависимости от нашего действие, которое, в свою очередь, определяет, получим ли мы положительное,отрицательноеили отсутствие вознаграждения. Затем мы просто проверяем, все ли раунды закончились, и, наконец, вызываем метод render, чтобы увидеть наш статус обучения.

from gym import Env
from gym.spaces import Box, Discrete
import random
class DogTrain(Env):
    def __init__(self):
        # dog runs from 0 to 50, returns from 50 to 0
        self.obs_space = Box(low=0, high=100, shape=(1,))
        
        # amount of distance travelled 
        self.action_space = Box(low=0, high=100, shape=(1,))
        
        # current state 
        self.state = random.randint(0, 10)
        
        # no. of rounds
        self.rounds = 20
        
        # reward collected
        self.collected_reward = -1 
    
    def step(self, action):
        done = False
        info = {}
        rw = 0
        self.rounds -= 1
        
        obs = self.state + action
        
        if obs < 50:
            self.collected_reward += -1
            rw = -1
        elif obs > 50 and obs < 100:
            self.collected_reward += 0
            rw = 0
        else:
            self.collected_reward += 1
            rw = 1
            
        if self.rounds == 0:
            done = True
        
        self.render(action, rw)
            
        return obs, self.collected_reward, done, info
    
    def reset(self):
        self.state = 0
        return self.state  
    def render(self, action, rw):
        print(f"Round : {self.rounds}\nDistance Travelled : {action[0]}\nReward Received: {rw}")
        print(f"Total Reward : {self.collected_reward}")
        print("=============================================================================")

Метод reset просто сбрасывает положение собаки на 0, а метод render, как указано выше, выводит наш статус.

Итак, наше окружение готово, давайте запустим его:

env = DogTrain()
done = False
while not done:
    state = env.reset()
    action = env.action_space.sample()
    state, reward, done, info = env.step(action)
Round : 19
Distance Travelled : 55.819583892822266
Reward Received: 0
Total Reward : -1
====================================================================
Round : 18
Distance Travelled : 35.046104431152344
Reward Received: -1
Total Reward : -2
====================================================================
Round : 17
Distance Travelled : 97.6022720336914
Reward Received: 0
Total Reward : -2
====================================================================
Round : 16
Distance Travelled : 30.057842254638672
Reward Received: -1
Total Reward : -3
====================================================================
Round : 15
Distance Travelled : 84.2916259765625
Reward Received: 0
Total Reward : -3
====================================================================
Round : 14
Distance Travelled : 76.2624282836914
Reward Received: 0
Total Reward : -3
====================================================================
Round : 13
Distance Travelled : 12.343267440795898
Reward Received: -1
Total Reward : -4
====================================================================
Round : 12
Distance Travelled : 7.887747764587402
Reward Received: -1
Total Reward : -5
====================================================================
Round : 11
Distance Travelled : 80.17852020263672
Reward Received: 0
Total Reward : -5
====================================================================
Round : 10
Distance Travelled : 15.843735694885254
Reward Received: -1
Total Reward : -6
====================================================================
Round : 9
Distance Travelled : 10.751422882080078
Reward Received: -1
Total Reward : -7
====================================================================
Round : 8
Distance Travelled : 22.644573211669922
Reward Received: -1
Total Reward : -8
====================================================================
Round : 7
Distance Travelled : 89.17772674560547
Reward Received: 0
Total Reward : -8
====================================================================
Round : 6
Distance Travelled : 93.87255859375
Reward Received: 0
Total Reward : -8
====================================================================
Round : 5
Distance Travelled : 82.16167449951172
Reward Received: 0
Total Reward : -8
====================================================================
Round : 4
Distance Travelled : 33.99330139160156
Reward Received: -1
Total Reward : -9
====================================================================
Round : 3
Distance Travelled : 91.62501525878906
Reward Received: 0
Total Reward : -9
====================================================================
Round : 2
Distance Travelled : 20.960491180419922
Reward Received: -1
Total Reward : -10
====================================================================
Round : 1
Distance Travelled : 25.36622428894043
Reward Received: -1
Total Reward : -11
====================================================================
Round : 0
Distance Travelled : 4.896814823150635
Reward Received: -1
Total Reward : -12
====================================================================

Примечание. Функция сброса всегда должна иметь оператор возврата, который является нашим начальным состоянием.

Здесь я просто предпринял некоторые случайные действия, в результате общая награда не очень хорошая, но как только мы обучим ее с помощью алгоритма обучения, такого как A2C, DDPG и т. д., мы получим гораздо больше. реалистичный результат.

Итак, сегодня вы узнали, как создать свою собственную среду с помощью тренажерного зала OpenAI, попробуйте создать свою собственную среду, сначала простую, а затем со сложной логикой.

Увидимся, выродки!! , не забудьте аплодировать, если считаете это полезным.

Кредиты: (Кто помог мне в создании этой статьи)
1. Набоджиоти Панди (мой коллега в Cloudcraftz Solutions Pvt. Ltd.)
2. Амрит Кумар Саркар (мой коллега в Cloudcraftz Solutions Pvt. Ltd.)