Data Collection


Для того чтобы обучить модель в нашем тренажере, нам нужно сначала написать простой цикл battle для сбора данных обучения. Мы используем структуру, аналогичную среде тренажера OpenAI, в которой для перехода к следующему временному шагу необходимо вызвать env.step(action).

def run_battle(env, randomize_attributes = False, random_policy = False):
    done = False
    data_collection = {"s": [], "a": [], "r": []}
    your_state, opponent_state = env.reset(randomize_attributes, random_policy)
    your_attributes = env.your_fighter["battle_attributes"]
    opponent_attributes = env.opponent_fighter["battle_attributes"]
    state = get_state(your_state, opponent_state, your_attributes, opponent_attributes)
    while not done:
        action = env.fighters[0]["model"].select_action(state)
        your_new_state, opponent_new_state, done, winner = env.step(action)
        
        reward = get_reward(your_state, your_new_state, opponent_state, opponent_new_state, winner)
        new_state = get_state(your_new_state, opponent_new_state, your_attributes, opponent_attributes)
        
        data_collection["s"].append(state[0])
        data_collection["a"].append(action)
        data_collection["r"].append(reward)
        your_state = your_new_state.copy()
        opponent_state = opponent_new_state.copy()
        state = new_state.copy()

    return winner, data_collection

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

def get_reward(your_state, your_new_state, opponent_state, opponent_new_state, winner):    
    opponent_health_delta = opponent_new_state["health"]- opponent_state["health"]
    your_health_delta = your_new_state["health"] - your_state["health"]
    
    hit_reward = (opponent_health_delta < 0) * 0.3
    get_hit_reward = (your_health_delta < 0) * -0.3
    
    result_reward = 0
    if winner == "You":
        result_reward = 2
    elif winner == "Opponent":
        result_reward = -2
    return result_reward + hit_reward + get_hit_reward

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

GAMMA = 0.95

def training_loop(env, episodes = 100):
    for e in range(episodes):
        winner, gameplay_data = run_battle(env)
        
        states = np.array(gameplay_data["s"])
        actions = np.array(gameplay_data["a"])
        discounted_return = get_discounted_return(gameplay_data["r"], GAMMA)

        env.fighters[0]["model"].train(states, actions, discounted_return)

Вернемся к Стартовые модели чтобы просмотреть как мы определили get_discounted_return .

<aside> ♻️ Цикл тренировки повторяется в следующей последовательности:

Run Battle → Collect Data → Train

</aside>

One-Sided RL


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

Self-Play


При таком методе обучения исследователь отвечает за обучение двух моделей, которые в конечном итоге являются копиями друг друга. Модели периодически обучаются асинхронно и постоянно обновляются. Это означает, что модель постоянно сталкивается с лучшей версией своей предыдущей модели. Чтобы реализовать это, вы просто определяете интервал, через который вы меняете местами модель, которую вы тренируете, с моделью противника. Для получения дополнительной информации см. Self-Play.

SWAP_INTERVAL = 50

if (e + 1) % SWAP_INTERVAL == 0:
		env.swap_fighters()

<aside> ⬅️ Previous

</aside>

<aside> ↩️ Return

</aside>