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

Создайте мощную функцию вознаграждения для студенческой лиги AWS DeepRacer

Доминируйте в студенческой лиге AWS DeepRacer, часть 2

Чтобы понять основы, посетите часть-1:- https://medium.com/@anshml/top-tips-for-students-to-dominate-the-aws-deepracer-student-league-eaecde6e3d33

Хотя большинство статей посвящено виртуальным каналам, я здесь, чтобы упростить вам жизнь в студенческой лиге и поделиться некоторыми советами, которые я почерпнул из сообщества Discord и других ресурсов, доступных в Интернете. Эти методы помогли мне занять впечатляющее 8-е место в предыдущем сезоне и 5-е место в глобальном рейтинге в этом сезоне.🏁

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

    "all_wheels_on_track": Boolean,        # flag to indicate if the agent is on the track
    "x": float,                            # agent's x-coordinate in meters
    "y": float,                            # agent's y-coordinate in meters
    "closest_objects": [int, int],         # zero-based indices of the two closest objects to the agent's current position of (x, y).
    "closest_waypoints": [int, int],       # indices of the two nearest waypoints.
    "distance_from_center": float,         # distance in meters from the track center 
    "is_crashed": Boolean,                 # Boolean flag to indicate whether the agent has crashed.
    "is_left_of_center": Boolean,          # Flag to indicate if the agent is on the left side to the track center or not. 
    "is_offtrack": Boolean,                # Boolean flag to indicate whether the agent has gone off track.
    "is_reversed": Boolean,                # flag to indicate if the agent is driving clockwise (True) or counter clockwise (False).
    "heading": float,                      # agent's yaw in degrees
    "objects_distance": [float, ],         # list of the objects' distances in meters between 0 and track_length in relation to the starting line.
    "objects_heading": [float, ],          # list of the objects' headings in degrees between -180 and 180.
    "objects_left_of_center": [Boolean, ], # list of Boolean flags indicating whether elements' objects are left of the center (True) or not (False).
    "objects_location": [(float, float),], # list of object locations [(x,y), ...].
    "objects_speed": [float, ],            # list of the objects' speeds in meters per second.
    "progress": float,                     # percentage of track completed
    "speed": float,                        # agent's speed in meters per second (m/s)
    "steering_angle": float,               # agent's steering angle in degrees
    "steps": int,                          # number steps completed
    "track_length": float,                 # track length in meters.
    "track_width": float,                  # width of the track
    "waypoints": [(float, float), ]        # list of (x,y) as milestones along the track center

}

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

ссылка -> Входные параметры функции вознаграждения AWS DeepRacer — AWS DeepRacer (amazon.com)

Сначала я расскажу вам об одной из стандартных функций вознаграждения, предоставляемых AWS, и покажу, как шаг за шагом анализировать, улучшать и оптимизировать ее. Вы также узнаете несколько советов и рекомендаций о том, как увеличить скорость вашего автомобиля и избежать распространенных ошибок. К концу этой статьи у вас будет четкое представление о том, как разработать собственную функцию вознаграждения и добиться высоких результатов в лиге AWS DeepRacer. Начнем!😊

'''
Example 3: Prevent zig-zag in time trials
This example incentivizes the agent to follow the center line but penalizes 
with lower reward if it steers too much, which helps prevent zig-zag behavior.
The agent learns to drive smoothly in the simulator and likely keeps 
the same behavior when deployed to the physical vehicle.
'''

def reward_function(params):
    '''
    Example of penalize steering, which helps mitigate zig-zag behaviors
    '''
    
    # Read input parameters
    distance_from_center = params['distance_from_center']
    track_width = params['track_width']
    abs_steering = abs(params['steering_angle']) # Only need the absolute steering angle

    # Calculate 3 marks that are farther and father away from the center line
    marker_1 = 0.1 * track_width
    marker_2 = 0.25 * track_width
    marker_3 = 0.5 * track_width

    # Give higher reward if the car is closer to center line and vice versa
    if distance_from_center <= marker_1:  # REGION 1
        distance_reward= 1.0 
    elif distance_from_center <= marker_2: # REGION 2
        distance_reward= 0.5
    elif distance_from_center <= marker_3: # REGION 3
        distance_reward= 0.1
    else:
        distance_reward= 1e-3  # likely crashed/ close to off track
                                #never set negative or zero rewards

    # Steering penality threshold, change the number based on your action space setting
    ABS_STEERING_THRESHOLD = 15 

    # Penalize reward if the car is steering too much
    if abs_steering > ABS_STEERING_THRESHOLD:
        distance_reward*= 0.8

    return float(reward)

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

  • marker_1 установлено на 10% ширины дорожки.
  • marker_2 установлено на 25% ширины дорожки.
  • marker_3 установлено на 50% ширины дорожки.

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

Давайте давать непрерывное вознаграждение вместо дискретного создания.

#continous reward
distance_reward = 1- (distance_from_center/track_width*0.5)

y= вознаграждение
x = расстояние от центра, где 0,0 ‹ x ‹ 0,5 м

возьмем для простоты track_width = 1,0 м.

Функция вознаграждения является линейной функцией расстояния от центра дорожки. Чем ближе машина к центру, тем выше награда. Автомобиль получает нулевую награду, если он съезжает с трассы (расстояние от центра › 0,5 м).

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

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

distance_reward = 1- (distance_from_center/track_width*0.5)**0.4  
#we haveraised to the power 0.4
#to make the curve more step lower the value 

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

#Example 
final_reward = distance_reward*2 + speed_reward*10 + ......

ПОДДЕРЖАНИЕ СКОРОСТИ 1 М/С

Одна из ключевых задач в AWS DeepRacer — поддерживать скорость 1,0 м/с на протяжении всей гонки. Это может дать вам значительное преимущество перед вашими конкурентами и помочь вам достичь лучших результатов. Итак, давайте углубимся, чтобы оптимизировать наши скоростные характеристики.

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

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

def reward_function(params):
    #############################################################################
    '''
    Example of using all_wheels_on_track and speed
    '''

    # Read input variables
    all_wheels_on_track = params['all_wheels_on_track']
    speed = params['speed']

    # Set the speed threshold based your action space
    SPEED_THRESHOLD = 1.0

    if not all_wheels_on_track:
        # Penalize if the car goes off track
        reward = 1e-3
    elif speed < SPEED_THRESHOLD:
        # Penalize if the car goes too slow
        reward = 0.5
    else:
        # High reward if the car stays on track and goes fast
        reward = 1.0

    return float(reward)

Посмотрите эту функцию в документации Входные параметры функции вознаграждения AWS DeepRacer — AWS DeepRacer (amazon.com)

Давайте больше награждать и наказывать нашего агента.

if not all_wheels_on_track:
        # Penalize if the car goes off track
        reward = 1e-3 #never set negative or zero rewards
    elif speed < SPEED_THRESHOLD:
        # Penalize more
        reward = 0.1
    else:
        # reward more
        reward = 10.0

'''

The SPEED_THRESHOLD is fixed to 1.0.
This is the maximum speed of the car.
One thing we can try is to change the reward values.

Range to give the rewards [1e-3,1e+3]
keep the scale similar to other subcomponents in your function
The final reward in end can be normalized 

'''

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

Давайте рассмотрим функции вознаграждения за непрерывную скорость

speed_diff = abs(1.0-speed)
max_speed_diff = 0.2#set it carefully in range [0.01,0.3]

if speed_diff < maximum_speed_diff:
  speed_reward = 1-(speed_diff/max_speed_diff)**1 
else:
  speed_reward = 0.001 #never set negative or zero rewards
  


'''

lets assume max_speed_diff = 0.2 
y=speed_reward
x=speed_difference 0<x<1.0

'''
speed_reward = 1-(speed_diff/max_speed_diff)**0.5

# changing the shape of the curve from linear to exponential helps a lot

Обратите внимание, сколько вознаграждения получает агент за обе фигуры/наклоны:

разность скоростей (1,0 — скорость автомобиля) = 0,1, 0,05 и 0,01, т.е.

скорость автомобиля = 0,9 и 0,95 м/с и 0,99 м/с

Другой способ изменить приведенную выше функцию вознаграждения — использовать max(), потому что мы не используем никаких условий if и не хотим, чтобы наше вознаграждение опускалось ниже 0,001.

max_speed_diff = 0.2
speed_diff = abs(1.0-speed) 
    speed_reward = max(1e-3, 1-((speed_diff/max_speed_diff)**0.5 ))

Компоненты «Шаги» и «Прогресс» также очень важны для поддержания скорости 1 м/с.

давайте посмотрим на пример, приведенный в документации.

def reward_function(params):
    #############################################################################
    '''
    Example of using steps and progress
    '''

    # Read input variable
    steps = params['steps']
    progress = params['progress']

    # Total num of steps we want the car to finish the lap, it will vary depends on the track length
    TOTAL_NUM_STEPS = 300

    # Initialize the reward with typical value
    reward = 1.0

    # Give additional reward if the car pass every 100 steps faster than expected
    if (steps % 100) == 0 and progress > (steps / TOTAL_NUM_STEPS) * 100 :
        reward += 10.0

    return float(reward)

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

Но как их объединить, чтобы создать единую функцию вознаграждения?

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

'''
->  Dont set a global reward variable which you are updating everywhere, 
instead set different rewards for each part like speed_reward, steps_reward etc 

->  Keep their scale almost same, normalizing them helps sometimes

->  Simply adding them together in final_reward variable usually works

->  you can experiment with a lot of methods here that I will strongly 
recommend to watch youtube video- https://www.youtube.com/watch?v=vnz579lSGto&ab_channel=BoltronRacingTeam
'''

КРАТКОЕ СОДЕРЖАНИЕ

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

Я надеюсь, что вы нашли эту статью полезной и информативной.

Если вам понравилась эта статья, похлопайте 👏👏👏 и поделитесь ею со своими друзьями, которые интересуются AWS DeepRacer. Это помогло бы мне привлечь больше людей.

Кроме того, не забудьте подписаться на мои статьи об AWS DeepRacer и других темах, связанных с машинным обучением и наукой о данных.

Спасибо за чтение и удачных гонок!😊

Обязательно посетите:

https://medium.com/@anshml/top-tips-for-students-to-dominate-the-aws-deepracer-student-league-eaecde6e3d33

«Лучшие формы функции вознаграждения для успеха! - YouTube"

Входные параметры функции вознаграждения AWS DeepRacer — AWS DeepRacer (amazon.com)

«Подробно о параметрах: Руководство студенческой лиги DeepRacer | Александр Березовский | Середина"

«Результаты и уроки: Студенческая лига DeepRacer, март 2023 г. | Александр Березовский | Середина"

Если у вас есть какие-либо сомнения, пожалуйста, прокомментируйте.