AWS DeepRacer - автономный гоночный автомобиль в масштабе 1/18. Он использует камеру (и датчик LIDAR в более новой версии) в качестве входных данных, чтобы определить, с какой скоростью должна двигаться машина и насколько крутым должен быть поворот. Мы можем использовать обучение с подкреплением, чтобы обучить модель в смоделированном виртуальном мире и загрузить модель в реальный автомобиль, чтобы протестировать ее.

Обучение с подкреплением

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

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

Сложность написания функции вознаграждения

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

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

Но точно так же, как когда мы играем в GTA, если побочная миссия (удержание машины внутри трассы) слишком привлекательна, мы можем быстро забыть основную миссию (завершение круга).

В обучении DeepRacer награда выдается функцией каждые 1/15 секунды. Если модель хочет получить как можно больше наград, она просто остается на правильном пути до тех пор, пока может. Однако наша цель - как можно быстрее завершить круг.

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

Мои функции вознаграждения

1. Наказывать медленную скорость

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

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

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

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

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

Быстро бегая по внешней полосе, модель может выполнить 4 шага с более высокой наградой (чем выше скорость, тем выше награда). Если он решит замедлиться и использовать внутреннюю полосу, он сможет выполнить только 3 шага и получит меньшее вознаграждение за эти шаги.

2. Награждение в зависимости от прогресса

Еще одна идея, которую я придумал, - дать модели знать, что именно я хочу. Итак, я также реализовал следующую функцию вознаграждения:

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

Давайте посмотрим на эту картинку. Вы можете подумать, что человек, на которого я указал, медлителен, поскольку он идет позади.

Но если вы посмотрите видео, то увидите, что он выигрывает гонку. Причина, по которой он отставал, в том, что его товарищ по команде бежит медленно.

То же самое происходит и с моей функцией вознаграждения.

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

Я должен наградить модель за ее прямолинейность. Но поскольку он плохо начался перед поворотом, он уже отстает после поворота, поэтому моя функция вознаграждения вместо этого дает ему плохую оценку. Также как когда мы смотрим на картинку, мы думаем, что человек бежит медленно.

Моя модель может подумать: «Почему у меня такой низкий балл? Я слишком быстро бегаю? Я что-то делаю не так? » Без знания прошлых действий модель не может судить, насколько хорошо текущее действие.

Комбинируя 2 метода

Я имею в виду не объединение двух методов в одну функцию вознаграждения, это только сбивает модель с толку. Вместо этого я использую эти две функции вознаграждения в качестве альтернативы.

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

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

Мониторинг прогресса

Как решить, когда переключить функцию вознаграждения?

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

На этом изображении мы видим, что награда увеличивается вместе с прогрессом на шаг. Это означает, что модель учится получать больше вознаграждения и одновременно работать быстрее. Мы можем продолжить обучение.

Однако эти 2 показателя не всегда совпадают.

На этом изображении мы видим, что корреляция между двумя элементами очень незначительна или даже отсутствует. Мы даже можем увидеть расхождение в одной итерации обучения (одна идет вверх, а другая - вниз).

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

Запоздалая мысль

Хотя моя модель хорошо себя чувствует после того, как я использовал эти методы для обучения. Но я все еще не могу найти одноразового метода быстрого обучения модели. Одна из причин - DeepRacer использует Марковский процесс принятия решений (MDP). Идея MDP заключается в том, что каждое решение принимается только текущим состоянием; никакой предыдущий опыт не задействован.

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

CNN против RNN

DeepRacer использует сверточную нейронную сеть (CNN) для построения модели, которая хорошо анализирует закономерности в пространстве, например изображения. В DeepRacer на вход поступают изображения, снятые фронтальной камерой, и имеет смысл использовать CNN.

Однако гонки - это непрерывный процесс, поэтому анализ закономерностей во времени также важен, и именно в этом Рекуррентная нейронная сеть (RNN) хороша.

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

Объединив RNN в DeepRacer, возможно, мы сможем изучить какой-нибудь новый метод обучения, чтобы сделать нашу модель более интеллектуальной.

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

Хотя у меня так мало знаний, чтобы сказать, работает ли моя идея, DeepRacer все же открывает мне дверь в мир машинного обучения. И это то, чего намеревалась достичь DeepRacer.

Если вы еще не начали играть в DeepRacer, присоединяйтесь сейчас, и у вас может быть возможность выиграть поездку на AWS re: Invent. Кроме того, у нас есть канал Slack, состоящий из множества замечательных участников DeepRacer, не стесняйтесь присоединяться и поздороваться со мной!