Посадка ракеты с помощью простого обучения с подкреплением
Что я узнаю?
В этой статье мы собираемся создать простой агент обучения с подкреплением (RL), который сможет успешно приземлить ракету в видеоигре Lunar Lander. RL - обширная тема, и я не собираюсь здесь подробно останавливаться на достигнутом. Вместо этого цель этого проекта - запачкать руки практическим обучением с подкреплением и прочувствовать его. Более подробные статьи по различным темам будут опубликованы в будущем. Этот проект будет охватывать следующее:
- Основные принципы обучения с подкреплением
- Создание простой нейронной сети с помощью pytorch
- Использование метода кросс-энтропии (CEM) и глубокого обучения для безопасной посадки 2D-ракеты
- Использование тренажерного зала OpenAi для обучения интеллектуальных агентов, способных работать в различных средах, от робототехники до видеоигр
Полный код можно найти здесь, на моем гитхабе. Если вы хотите быстро следить за всем, что уже настроено, нажмите кнопку запустить на FloydHub ниже. Это позволит настроить рабочее пространство на удивительной облачной платформе FloydHub со всеми предустановленными зависимостями и требованиями к среде.
вступление
Достижения в области искусственного интеллекта стремительно растут в настоящее время (это не каламбур). Исследователи каждый год разрабатывают новаторские идеи, и мы все еще находимся в зачаточном состоянии этой удивительной области. Одна из самых интересных областей искусственного интеллекта - обучение с подкреплением. RL был ответственен за некоторые из самых крутых примеров ИИ, такие как OpenAI, разработавшего агента, который побеждает лучших профессиональных игроков в киберспорте DOTA 2! Для ИИ возможность генерировать и изучать сложные стратегии в такой сложной игре, как DOTA 2, является огромным достижением, которое еще больше приблизит исследования к достижению общего искусственного интеллекта (AGI). Помимо достижения сверхчеловеческого уровня производительности в играх, RL может применяться в широком спектре областей, включая финансовую торговлю, обработку естественного языка, здравоохранение, производство и образование.
Что такое обучение с подкреплением?
Как и большинство достижений в области искусственного интеллекта, RL основан на изучении интеллекта людей. Основные концепции RL происходят из бихевиоризма, который в основном утверждает, что все, что мы делаем в жизни, является рефлекторной реакцией на нашу текущую среду или следствием наших прошлых действий.
RL использует метод проб и ошибок, чтобы научиться принимать наилучшие возможные решения, получая наилучшее возможное вознаграждение в течение определенного периода времени. Хороший пример этого - дрессировка собаки. Каждый раз, когда собака переворачивается, когда вы говорите ей, она получает угощение (награда +1). Каждый раз, когда они писают на коврик, на них кричат (награда -1). Со временем они учатся делать то, что приносит им самые положительные награды, и избегать вещей, которые приносят самые отрицательные награды.
Поскольку RL использует обучение без учителя, ему не нужно говорить, как чего-то достичь, ему просто нужно знать, чего достичь. Это означает, что он может находить решения проблем, о которых люди, возможно, даже не догадывались.
Компоненты обучения с подкреплением
По мере того, как агент проходит через среду, он проходит своего рода цикл обучения. Это показано выше. Агент определяет, в каком состоянии он сейчас находится, и решает, какое действие лучше всего предпринять с учетом своего текущего состояния. Когда это действие выполняется в среде, агент наблюдает за новым состоянием после выполнения этого действия, а также за вознаграждением, полученным за выполнение действия в этом состоянии. Благодаря этому методу наш агент учится.
Агент
Агент - это наш ИИ, герой нашей истории. Интересный факт: если вы дадите своему агенту имя, он будет тренироваться как минимум в 2 раза быстрее! Позвоним нашему агенту Тиму. Тим содержит алгоритм RL и нейронную сеть, которая позволяет ему принимать решения на основе того, что он уже изучил. В этом проекте мы будем использовать метод кросс-энтропии в качестве алгоритма RL.
Честно предупреждаю, вы можете эмоционально привязаться к своему агенту, пока он тренируется. Вы даже можете обнаружить, что кричите в журналы тренировок на своем мониторе, поскольку маленький Тимми не может улучшаться уже 5-ю эпоху подряд. Это также даст вам хорошее представление о том, каким родителем вы будете (скорее всего, стационарным и чрезмерно критичным).
Окружение
Среда - это место, где наш агент живет и выполняет свои задачи. В этом проекте окружение - игра Lunar Lander. Все, что вам нужно знать, это то, что среда дает нам состояния в качестве наблюдений за агентом и вознаграждения, которые получает агент, пытаясь превзойти среду. В будущем вы, возможно, захотите создать свою собственную среду, чтобы попытаться решить определенные задачи, но это большая работа. Итак, пока мы собираемся использовать тренажерный зал OpenAI. Это дает нам огромный выбор учебных сред, из которых можно выбирать. Если вы запускаете этот проект локально, ознакомьтесь с документацией OpenAI, чтобы настроить тренажерный зал здесь. Если вы не хотите мучиться с настройкой, я бы посоветовал использовать кнопку запустить на floydhub в начале статьи.
Состояние
Состояние / наблюдение - это просто текущее состояние окружающей среды. Например, в Tic-Tac-Toe текущим состоянием окружающей среды будет то, какие фигуры на каких квадратах. Эта простая среда может представлять свое состояние с помощью простой матрицы, но для более сложных сред мы используем данные пикселей с экрана в качестве текущего состояния. Это использует компьютерное зрение, чтобы понять, что происходит в текущем состоянии. Это более продвинутая функция, и здесь мы не будем ее рассматривать.
Действие
Как и состояние, это говорит само за себя. Для каждого шага в среде агент выполняет действие, основанное на текущем состоянии, в котором он находится. В этом проекте у лунного посадочного модуля есть 4 возможных действия, которые он может предпринять. ничего не делать, запускать двигатель с левой ориентацией, запускать основной двигатель, запускать двигатель с правой ориентацией.
Награда
Награда - это просто обратная связь, которую агент получает от взаимодействия с окружающей средой. Это может быть как положительное, так и отрицательное, и это очень важный фактор в том, как агент учится. В примере Lunar Lander агент получает положительную награду за приземление ближе к целевой зоне. Агент получает отрицательное вознаграждение за дальнейшее удаление от зоны приземления. Также агент получает небольшую отрицательную награду каждый раз, когда выполняет действие. Это делается в попытке научить агента садить ракету как можно быстрее и эффективнее. Если бы мы просто наградили его за посадку ракеты, агент смог бы это сделать, но это могло бы занять гораздо больше времени, чем следовало бы, и израсходовать излишки топлива. Это потому, что в этом нет недостатков.
Назначение правильной функции вознаграждения очень важно и является ключевым фактором в работе агента. Определить правильное вознаграждение за задачу не всегда легко или просто, и это может иметь огромное влияние на агента. Помните, что мы хотим указывать агенту что делать, а не как это делать. В этом примере мы говорим агенту посадить ракету в заданном месте как можно эффективнее. Как агент это делает, полностью зависит от него самого.
Метод кросс-энтропии
Теперь, когда мы ознакомились с основами того, что такое RL, давайте погрузимся в метод, который наш агент будет использовать для изучения. Наш агент будет проходить сотни эпизодов окружения и записывать выполненные действия и состояние, в котором агент находился на каждом этапе эпизода. Также записывается общая сумма вознаграждения, полученного за этот эпизод. Мы сгенерируем партию этих серий, ~ 100 серий на партию. После того, как мы собрали данные из нашей серии эпизодов, мы выбираем эпизоды, которые показали лучшие результаты в этой серии. Это похоже на то, как работают эволюционные алгоритмы, поскольку они обеспечивают соблюдение методологии «выживания наиболее приспособленных».
Затем мы берем эти элитные эпизоды и пропускаем их через нашу нейронную сеть. Состояния используются в качестве входных данных, а предпринятые действия являются целевыми выходными данными. Делая это, сеть узнает, какие действия следует предпринять в определенном состоянии.
Есть много разных типов моделей RL, которые имеют разные методы обучения. На данный момент все, что вам нужно знать, это то, что CEM определяется следующими 3 метками. Свободное от моделей, основанное на политике обучение и обучение на основе политик. Ниже приводится краткое объяснение каждого
- Бесплатные модели и основанные на модели: Методы на основе модели пытаются создать модель окружающей среды и предсказать, что произойдет дальше, чтобы принять наилучшие решения. Бесплатные методы модели напрямую связывают наблюдения и действия для принятия оптимальных решений [1]
- На основе политик и на основе значений: агенты на основе политик выстраивают политику с течением времени, которая определяет вероятность выполнения определенного действия в заданном состоянии. Агенты, основанные на ценностях, вычисляют ценность каждого действия и используют это значение для выбора наилучшего действия. [1]
- Off Policy vs On Policy: определяет, как наш агент учится на собственном опыте. Off Policy учится на старых данных, ранее собранных агентом с другой политикой, чем наша текущая. где as On Policy учится на новых данных при использовании текущей политики [2].
Зачем использовать CEM?
Если вы провели какое-либо исследование RL, вы быстро увидите, что CEM на самом деле не пользуется большой любовью и уступает место более популярным методам, таким как Deep Q Learning (DQN) и Advantageous Asynchronous Actor Crtic (A3C). Так почему мы не используем один из них? CEM - отличный метод для новичков, поскольку это простой и интуитивно понятный метод, который можно написать примерно в 100 строк кода. За ним не только легко следить, но и он работает достаточно хорошо и обеспечивает отличную основу для сравнения с будущими проектами.
Строительные блоки CEM
Чтобы реализовать метод глубокой кросс-энтропии, нам нужно выполнить 4 шага
1. Создание сеансов:
Пройдите несколько эпизодов игровой среды с нашим текущим агентом и сохраните действия, состояния и награды, используемые для каждого эпизода.
2. Получить элитные сеансы:
Мы хотим изучать только те эпизоды, которые получили высокий балл в этой серии. Мы определяем наш элитный порог, беря некоторый процентиль всех наград за серию сгенерированных сеансов.
3. Тренируйтесь на элитных занятиях
Теперь, когда у нас есть верхние X% нашей партии, мы обучаем нашу модель на этом опыте. Мы используем записанные состояния в качестве входных данных, а выполняемые действия - в качестве целевых выходных данных.
4. Промыть и повторить
Мы продолжаем повторять этот процесс, пока наша модель не приблизится к успешной политике.
Теперь, когда у нас есть план создания агента, последнее, что нам нужно сделать, это применить глубокое обучение к CEM.
Глубокое обучение
Традиционный CEM использует матрицу или таблицу для хранения политики. Эта матрица содержит все состояния в среде и отслеживает вероятность выполнения каждого возможного действия в этом состоянии. Как вы понимаете, этот метод подходит только для сред с небольшими пространствами конечных состояний. Чтобы создать агентов, которые могут научиться преодолевать более крупные и сложные среды, мы не можем использовать матрицу для хранения нашей политики.
Здесь в игру вступает глубокое обучение. Вместо матрицы мы собираемся использовать нейронную сеть, которая учится приблизительно определять, какое действие предпринимать в зависимости от состояния, которое было задано в качестве входных данных для сети. Если вы не знакомы с нейронными сетями, ознакомьтесь с моей предыдущей статьей о построении нейронной сети с нуля здесь. В этом проекте мы не будем строить всю сеть с нуля, вместо этого мы будем использовать популярную библиотеку глубокого обучения pytorch. Полный код нашей сети можно увидеть здесь
import gym import numpy as np import torch import torch.nn as nn import torch.optim as optim class Net(nn.Module): def __init__(self, obs_size, hidden_size, n_actions): super(Net, self).__init__() self.fc1 = nn.Linear(obs_size, hidden_size) self.fc2 = nn.Linear(hidden_size, n_actions) def forward(self, x): x = F.relu(self.fc1(x)) return self.fc2(x)
Pytorch имеет стандартное соглашение для построения своих сетей. Сначала мы создаем новый класс с именем Net, который наследуется от класса nn.Module. Здесь мы инициализируем два полностью связанных слоя, которые составляют ядро нашей нейронной сети. Первый полностью связанный слой (fc1) - это наш входной слой, который принимает тензор того же размера, что и размер нашего состояния, и выводит тензор, который является размером наших скрытых узлов (в данном случае его 200). Второй полностью связанный слой (fc2) - это наш скрытый слой, он принимает выходные данные из нашего предыдущего слоя и выводит тензор, который является размером нашего пространства действий (в данном случае 4), он будет выводить число для каждого возможного действия нашего агент может взять.
def __init__(self, obs_size, hidden_size, n_actions): super(Net, self).__init__() self.fc1 = nn.Linear(obs_size, hidden_size) self.fc2 = nn.Linear(hidden_size, n_actions)
Далее нам нужно написать наш метод продвижения вперед. Этого требует класс nn.Model. Этот метод автоматически используется, когда мы передаем данные в наш сетевой объект. Вы можете видеть ниже, что мы берем тензор x, который является игровым состоянием, которое наблюдает агент. Мы передаем это состояние через первый уровень нашей нейронной сети и применяем функцию активации ReLU к выходу fc1. Затем мы берем этот результат и пропускаем его через наши вторые слои. Это значение затем возвращается как результат всей сети.
def forward(self, x): x = F.relu(self.fc1(x)) return self.fc2(x)
Обычно мы добавляем слой активации после последнего выходного слоя, такой как функция softmax. Функция softmax берет числа, которые были вычислены для каждого возможного действия, и нормализует их так, чтобы все они в сумме равнялись 1. Делая это, мы знаем правильную вероятность выполнения каждого действия.
Затем мы вычислили бы потерю перекрестной энтропии, чтобы узнать, насколько далекими оказались наши прогнозы. Вместо этого мы используем класс pytorch nn.CrossEntropyLoss позже в проекте. Этот класс выполняет как активацию softmax, так и потерю кросс-энтропии одновременно, чтобы обеспечить более стабильную функцию [1]. Единственное, что вам нужно помнить, это то, что нам нужно применить функцию активации softmax, когда мы хотим увидеть вероятность выполнения действия с учетом нашего текущего состояния.
Создать сеансы
Здесь мы создаем нашу серию эпизодов. Агент будет проходить N эпизодов и собирать действия / состояния для каждого шага, чтобы мы могли обучить нашего агента. Вот полный код метода
def generate_batch(env,batch_size, t_max=1000): activation = nn.Softmax(dim=1) batch_actions,batch_states, batch_rewards = [],[],[] for b in range(batch_size): states,actions = [],[] total_reward = 0 s = env.reset() for t in range(t_max): s_v = torch.FloatTensor([s]) act_probs_v = activation(net(s_v)) act_probs = act_probs_v.data.numpy()[0] a = np.random.choice(len(act_probs), p=act_probs) new_s, r, done, info = env.step(a) states.append(s) actions.append(a) total_reward += r s = new_s if done: batch_actions.append(actions) batch_states.append(states) batch_rewards.append(total_reward) break return batch_states, batch_actions, batch_rewards
Сначала мы выполняем нашу функцию активации, как мы описали ранее. Далее нам нужны три списка для хранения данных о наших эпизодах. Первые два - это batch_actions и batch_states. На самом деле это список списков. Каждый индекс хранит все действия / состояния для определенного эпизода. Затем batch_rewards сохраняет общую награду, полученную за каждый эпизод.
activation = nn.Softmax(dim=1) batch_actions,batch_states, batch_rewards = [],[],[]
Затем мы перебираем размер нашего пакета, запуская эпизод для каждой итерации. В нашем первом цикле мы инициализируем два пустых списка для хранения наших действий / состояний для этого эпизода. Мы также создаем переменную для подсчета общей награды за эпизод. Это наши переменные данных. Наконец, мы инициализируем нашу переменную состояния s новым эпизодом, вызывая env.reset (), это запустит новую игру.
for b in range(batch_size): states,actions = [],[] total_reward = 0 s = env.reset()
Теперь мы вызываем второй цикл, который выполняет один шаг в игровой среде до тех пор, пока мы не достигнем лимита времени для этого эпизода. Сначала нам нужно получить наше текущее состояние и передать его через нашу сеть. Для этого нам нужно превратить наше состояние в тензор с плавающей точкой факела, чтобы мы могли передать его в сеть. Затем мы получаем вероятность действия из нашей сети. Помните, что мы должны применить нашу функцию активации к предсказанию, чтобы все вероятности действий в сумме равнялись единице и были пригодны для использования. После того, как мы получили наше распределение вероятностей, мы можем решить, какие действия предпринять. Это делается с помощью функции numpys random.choice. Он выберет «случайное» действие на основе заданных вероятностей. Таким образом, если в нашей политике указано, что действие 1 имеет значение 0,7, а у нас есть три других действия с вероятностью 0,1, гораздо более вероятно, что наше действие будет действием 1.
for t in range(t_max): s_v = torch.FloatTensor([s]) act_probs_v = activation(net(s_v)) act_probs = act_probs_v.data.numpy()[0] a = np.random.choice(len(act_probs), p=act_probs)
Как только мы решили, какое действие предпринять, действие выполняется в среде. Это вернет новое состояние - награду, полученную за выполнение этого действия, независимо от того, завершен ли эпизод, и любую дополнительную информацию, которую может предоставить среда. Теперь, когда у нас есть информация о нашей обновленной среде, нам нужно добавить состояние, действие и награду к нашим переменным данных. Наконец, мы обновляем наше текущее состояние.
new_s, r, done, info = env.step(a) states.append(s) actions.append(a) total_reward += r s = new_s
Последнее, что нам нужно сделать перед этим, - это проверить, завершился ли эпизод на этом этапе. Если done имеет значение True, мы просто добавляем наши действия, состояния и награды в соответствующие списки пакетов. Тогда перерыв
if done: batch_actions.append(actions) batch_states.append(states) batch_rewards.append(total_reward) break
Как только это будет сделано, просто верните наши пакетные данные
return batch_states, batch_actions, batch_rewards
Фильтр элитных сеансов
Этот метод используется для выбора только лучших серий из последнего пакета. Найдите порог вознаграждения, в нашем случае это верхние 20% или 80-й процентиль, но не стесняйтесь поиграть с этим числом, а затем просто возьмите данные эпизодов из эпизодов с вознаграждением ≥ нашего порога вознаграждения. Для этого мы используем удобный метод числового процентиля. Просто дайте ему наш список наград за нашу серию эпизодов и наш выбранный процентиль, и он сделает за нас все ужасающие математические вычисления!
def filter_batch( states_batch,actions_batch,rewards_batch,percentile=50): reward_threshold = np.percentile(rewards_batch, percentile) elite_states = [] elite_actions = [] for i in range(len(rewards_batch)): if rewards_batch[i] > reward_threshold: for j in range(len(states_batch[i])): elite_states.append(states_batch[i][j]) elite_actions.append(actions_batch[i][j]) return elite_states,elite_actions
Обучение
Итак, ядро нашей Deep CEM завершено. Теперь нам просто нужно использовать наш код и обучить агента.
batch_size = 100 session_size = 100 percentile = 80 hidden_size = 200 learning_rate = 0.0025 completion_score = 200 env = gym.make("LunarLander-v2") n_states = env.observation_space.shape[0] n_actions = env.action_space.n #neural network net = Net(n_states, hidden_size, n_actions) #loss function objective = nn.CrossEntropyLoss() #optimisation function optimizer = optim.Adam(params=net.parameters(), lr=learning_rate) for i in range(session_size): #generate new sessions batch_states,batch_actions,batch_rewards = generate_batch(env, batch_size, t_max=5000) elite_states, elite_actions = filter_batch(batch_states,batch_actions,batch_rewards,percentile) optimizer.zero_grad() tensor_states = torch.FloatTensor(elite_states) tensor_actions = torch.LongTensor(elite_actions) action_scores_v = net(tensor_states) loss_v = objective(action_scores_v, tensor_actions) loss_v.backward() optimizer.step() #show results mean_reward, threshold = np.mean(batch_rewards), np.percentile(batch_rewards, percentile) print("%d: loss=%.3f, reward_mean=%.1f, reward_threshold=%.1f" % (i, loss_v.item(), mean_reward, threshold)) #check if if np.mean(batch_rewards)> completion_score: print("Environment has been successfullly completed!")
Это может выглядеть как длинный блок кода, но на самом деле это не так страшно. Перво-наперво нам нужно инициализировать наши параметры.
batch_size = 100 session_size = 500 percentile = 80 hidden_size = 200 learning_rate = 0.01 completion_score = 200
batch_size: сколько серий запускать одновременно
session_size: сколько эпох обучения. каждая эпоха запускает одну партию
процентиль: используется для определения порога элитного вознаграждения.
Learning_rate: обозначает, насколько мы обновляем нашу сеть на каждом этапе обучения (для этого необходимо найти золотую середину).
Complete_score: средняя награда за более чем 100 эпизодов, которые считаются решенными.
Со всем этим можно поиграться. Следующая часть просто инициализирует нашу среду обучения.
env = gym.make("LunarLander-v2") n_states = env.observation_space.shape[0] n_actions = env.action_space.n
Далее нам нужно настроить нашу нейронную сеть pytorch. Это включает в себя три вещи.
- Инициализируем сеть, которую мы создали ранее
- Выберите функцию потерь
- Выберите оптимизатор.
Как видите, мы используем CrossEntropyLoss и функцию оптимизации Adam.
#neural network net = Net(n_states, hidden_size, n_actions) #loss function objective = nn.CrossEntropyLoss() #optimisation function optimizer = optim.Adam(params=net.parameters(), lr=learning_rate)
Теперь мы переходим к нашему циклу обучения. Мы запускаем цикл для заданного количества сеансов. В течение каждой эпохи (итерации) мы запускаем наш метод generate_batch, чтобы получить наш пакет данных эпизода.
for i in range(session_size): #generate new sessions batch_states,batch_actions,batch_rewards = generate_batch(env, batch_size, t_max=5000)
Как только это будет сделано, мы отфильтровываем плохие эпизоды и оставляем элитные, вызывая наш метод пакетной фильтрации.
elite_states, elite_actions = filter_batch(batch_states,batch_actions,batch_rewards,percentile)
Когда у нас есть элитные эпизоды, на которых мы хотим тренироваться, мы проходим процесс передачи данных через нашу нейронную сеть.
optimizer.zero_grad() tensor_states = torch.FloatTensor(elite_states) tensor_actions = torch.LongTensor(elite_actions) action_scores_v = net(tensor_states) loss_v = objective(action_scores_v, tensor_actions) loss_v.backward() optimizer.step()
Перед каждым шагом обучения нам нужно обнулить градиенты нашего оптимизатора. На данный момент все, что вам нужно знать, это то, что мы сбрасываем оптимизатор. Затем мы превращаем наши списки elite_states и elite_actions в тензоры torch, чтобы их можно было использовать в нашей сети.
Затем мы передаем в нашу сеть все состояния элитных эпизодов. Он просматривает все собранные состояния и предсказывает, как должно выглядеть распределение политик. Затем мы сравниваем эти прогнозы с действиями, которые проводились в наших элитных эпизодах. В идеале мы хотим, чтобы прогнозы наших сетей были близки к этим.
Чтобы узнать, насколько далеко была наша сеть (убыток), мы используем целевую функцию (CrossEntropyLoss). После того, как мы вычислили убыток, мы используем обратный метод, чтобы вычислить градиенты наших потерь (обратное распространение). Наконец, наш оптимизатор обновляет нашу сеть, вызывая метод step.
Последнее, что нужно сделать, это показать результаты и проверить, достигли ли мы среднего балла выше, чем балл завершения.
#show results mean_reward, threshold = np.mean(batch_rewards), np.percentile(batch_rewards, percentile) print("%d: loss=%.3f, reward_mean=%.1f, reward_threshold=%.1f" % (i, loss_v.item(), mean_reward, threshold)) #check if if np.mean(batch_rewards)> completion_score: print("Environment has been successfullly completed!")
Полученные результаты
Полное обучение этой модели (получение 200 баллов) на обычном процессоре может занять некоторое время, в зависимости от вашей машины. Если вы не хотите обучать агента до конца, вы можете просто тренировать его, пока он не достигнет среднего балла 50. Это обеспечит безопасную посадку ракеты, хотя она может и не находиться в целевой зоне. Если вы не хотите ждать этого, вы всегда можете использовать более простую среду, такую как CartPole. Просто замените «LunarLander-v2» на «CartPole-v0».
Если вы хотите увидеть свой агент в действии и запускаете этот проект на локальном компьютере, добавьте в этот раздел кода. Это сгенерирует пакет из одного эпизода и запишет видео, на котором играет агент. Он создаст новую папку с именем «видео» в том же каталоге, что и ваш код.
import gym.wrappers env = gym.wrappers.Monitor(gym.make("LunarLander-v2"), directory="videos", force=True) generate_batch(env, 1, t_max=5000) env.close()
Что теперь?
Поздравляем с созданием вашего первого агента глубокого обучения с подкреплением! В этой статье мы рассмотрели некоторые сложные вещи, которые заслуживают больше времени и понимания, но я хотел, чтобы это был хороший проект, чтобы просто испачкать руки с RL. Если вам нужна дополнительная информация о RL, я перечислил несколько ресурсов ниже, которые предоставят вам все необходимое для продолжения вашего собственного обучения.
Я рекомендую вам вернуться к проекту еще раз, если что-то неясно. Если вы чувствуете, что хорошо понимаете это на бумаге, попробуйте воссоздать его с нуля, это отличное упражнение для реального понимания темы. Как только вы действительно поймете, что происходит, начните играть с этим. Первоначально можно попробовать несколько простых вещей - это изменить гиперпараметры или добавить больше слоев в нашу сеть. Однако будьте осторожны: чем сложнее вы сделаете сеть и параметры, тем больше времени потребуется агенту на обучение.
Другие источники
Практика глубокого обучения с подкреплением: Это фантастическая книга, которую я очень рекомендую. Максим объясняет все, что вам нужно знать о RL, четко, кратко и увлекательно, используя отличные примеры проектов.
Практическое обучение с подкреплением (Coursera): Это отличный курс по RL. Он охватывает все, от основ до более сложных алгоритмов и концепций. Фрагменты этой статьи основаны на том, что я здесь узнал.
Канал Сираджа Раваля: Этот парень - один из моих любимых источников информации по машинному обучению. Его канал охватывает практически все, что вы хотели бы знать, и в то же время очень занимательный!
использованная литература
[1] Лапан, Максим - Практическое занятие по глубокому обучению с подкреплением, Packt Publishing, 2018 г.
[2] Саттон Р. и Барто А. - Обучение с подкреплением: Введение, MIT Press, 1998