/
GraphTreeHeap
/
NeuroFighter
Обзор
Документация
Войти
/
GraphTreeHeap
/
NeuroFighter
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/stats.py
279 строк
11 KB
FedMam
more updates!
12 окт 2025, 23:45
12 окт 2025, 23:45
e25bf29
Код
Авторство
О чём код?
import random import numpy as np import torch # DEBUG # import graphics # graphics.init_graphics() import tqdm import sys import matplotlib.pyplot as plt from util import hold_fight_universal from mechanics import * import robotics import neural_ppo_singlehead import neural_ppolstm_singlehead import stable_baselines3 import sb3_contrib from typing import * def win_rate(network1: Any, network2: Any, character1: CharacterDescription, character2: CharacterDescription, iterations: int, verbose: bool=False) -> tuple[tuple[int, int], tuple[int, int]]: f1_win_rate_1vs2 = 0 f2_win_rate_1vs2 = 0 f1_win_rate_2vs1 = 0 f2_win_rate_2vs1 = 0 for it in tqdm.tqdm(range(iterations * 2), 'Collecting Win Rate stats') if verbose else range(iterations * 2): result = hold_fight_universal(visual=False, player_character=character1, opponent_character=character2, player_network=network1, opponent_network=network2, player_opponent_reversed=it >= iterations, round=0, logging=False) if result == 1: if it < iterations: f1_win_rate_1vs2 += 1 else: f1_win_rate_2vs1 += 1 elif result == -1: if it < iterations: f2_win_rate_1vs2 += 1 else: f2_win_rate_2vs1 += 1 return ((f1_win_rate_1vs2, f1_win_rate_2vs1), (f2_win_rate_1vs2, f2_win_rate_2vs1)) def win_rate_all_characters(network1: Any, network2: Any, iterations: int, verbose: bool=False, seed: int | None=None) -> list[list[int]]: all_characters = CHARACTERS[:] + BOSS_CHARACTERS[:] rand = random.Random(seed) win_rt = [[[0, 0, 0] for _ in range(len(all_characters))] for _ in range(len(all_characters))] character_matchpairs = character_matchpairs = [(i, j) for i in range(len(all_characters)) for j in range(len(all_characters))] for it in tqdm.tqdm(range(iterations), 'Collecting Win Rate stats (all characters)...') if verbose else range(iterations): if it % len(character_matchpairs) == 0: rand.shuffle(character_matchpairs) char1_id, char2_id = character_matchpairs[it % len(character_matchpairs)] character1 = all_characters[char1_id] character2 = all_characters[char2_id] player_opponent_reversed = rand.randint(0, 1) == 1 result = hold_fight_universal(visual=False, player_character=character1, opponent_character=character2, player_network=network1, opponent_network=network2, player_opponent_reversed=player_opponent_reversed, round=0, logging=False) win_rt_cell = win_rt[character1.character_id][character2.character_id] win_rt_cell[0] += 1 # total if result == 1: win_rt_cell[1] += 1 elif result == -1: win_rt_cell[2] += 1 return win_rt def prob_dist_mean(network_tested: Any, network_opponent: Any, character1: CharacterDescription, character2: CharacterDescription, matches: int, frame_chunk_size: int, verbose: bool=False, seed: int | None=None) -> np.ndarray: dist_data = [] rand = random.Random(seed) for match_i in tqdm.tqdm(range(matches), 'Collecting action prob. dist. stats') if verbose else range(matches): result, logs = hold_fight_universal(visual=False, player_character=character1, opponent_character=character2, player_network=network_tested, opponent_network=network_opponent, player_opponent_reversed=False, round=0, logging=True) dist_data_curr = logs['action_dist'][0] while len(dist_data) < math.ceil(len(dist_data_curr) / frame_chunk_size): dist_data.append([]) for i in range(len(dist_data_curr)): dist_data[i // frame_chunk_size].append(dist_data_curr[i]) for i in range(len(dist_data)): dist_data[i] = np.array(dist_data[i], dtype=np.float32).mean(axis=0) dist_data = np.array(dist_data, dtype=np.float32) return dist_data if __name__ == '__main__': torch.set_num_threads(16) GAME_OPPONENTS = [] # PPO for id, ppo_file in [ ('PPO ', 'trained/ppo/agent.pth'), ('PPO:n', 'trained/ppo/agent_before_self_play.pth'), ('PPO:O', 'trained/ppo-objective/agent.pth'), ('PPO:A', 'trained/ppo-aggressive/agent.pth'), ('PPO:D', 'trained/ppo-defensive/agent.pth'), ('PPO:M', 'trained/ppo-master/agent.pth'), ('PPO:m', 'trained/ppo-master/agent_before_self_play.pth'), ('PPO:R', 'trained/ppo-retired-champion/agent.pth'), ]: agent = neural_ppo_singlehead.PPOAgentWrapper(logging=False) agent.load_model(ppo_file) GAME_OPPONENTS.append((id, agent.agent)) # LSTM lstm_agent = neural_ppolstm_singlehead.PPOAgentWrapperLSTM(logging=False) lstm_agent.load_model('trained/lstm/agent.pth') lstmr_agent = neural_ppolstm_singlehead.PPOAgentWrapperLSTM(logging=False, agent_class=neural_ppolstm_singlehead.PPOAgentLSTMResidual) lstmr_agent.load_model('trained/lstmr/agent.pth') GAME_OPPONENTS.append( ('LSTM ', lstm_agent.agent) ) GAME_OPPONENTS.append( ('LSTMr', lstmr_agent.agent) ) # X ppo_l = neural_ppo_singlehead.PPOAgentWrapper(logging=False) ppo_l.load_model('trained/ppo-long-episodes/agent.pth') BOTS = [] # bots for id, bot in [ ('B:DUM', robotics.Dumbot()), ('B:RND', robotics.Randominator()), ('B:AVO', robotics.Randominator()), ('B:RM ', robotics.Rammer()), ('B:RM2', robotics.RammerMkII()), ('B:MJ ', robotics.MadJumper()), ('B:DG ', robotics.Dodgetron()), ('B:DG2', robotics.DodgetronMkII()), ('B:STI', robotics.Stinger()) ]: BOTS.append((id, bot)) print(' |' + '|'.join([id for id, _ in (GAME_OPPONENTS + BOTS)]) + '|') print('-----+' * (len(GAME_OPPONENTS) + len(BOTS) + 1)) for id1, network1 in [('PPO:L', ppo_l.agent)]: print(id1, end='|') sys.stdout.flush() for id2, network2 in (GAME_OPPONENTS + BOTS): """ win_rt_1vs2, debug = win_rate(network1, network2, CHARACTERS[0], CHARACTERS[0], 100, verbose=False) rate = (win_rt_1vs2[0] + win_rt_1vs2[1]) / 200 print(str(round(rate * 100)).rjust(4, ' '), end='%|') sys.stdout.flush() """ win_rt = win_rate_all_characters(network1, network2, iterations=(14 * 14), verbose=False) rate = sum([it[1] for row in win_rt for it in row]) / (14 * 14) print(str(round(rate * 100)).rjust(4, ' '), end='%|') sys.stdout.flush() print() ''' all_characters = CHARACTERS[:] + BOSS_CHARACTERS[:] agent1 = neural_ppo_singlehead.PPOAgentWrapper(logging=False) agent1.load_model('trained/ppo/agent.pth') agent2 = neural_ppolstm_singlehead.PPOAgentWrapperLSTM(logging=False) agent2.load_model('trained/lstm/agent.pth') agent3 = neural_ppolstm_singlehead.PPOAgentWrapperLSTM(logging=False, agent_class=neural_ppolstm_singlehead.PPOAgentLSTMResidual) agent3.load_model('trained/lstmr/agent.pth') bots = ((robotics.Rammer(), (0xff, 0xc0, 0x00)), (robotics.MadJumper(), (0xff, 0x40, 0x40)), (robotics.Dodgetron(), (0x40, 0x80, 0xff))) action_names = ['None', 'Left', 'Right', 'Jump', 'Left+Jump', 'Right+Jump', 'Shoot', 'Left+Shoot', 'Right+Shoot', 'Jump+Shoot', 'Left+Jump+Shoot', 'Right+Jump+Shoot'] for agent in (agent3.agent,): # (agent1.agent, agent2.agent): for bot, color in bots: print(f'Competing: {agent.__class__.__name__} vs. {bot.__class__.__name__}') dist_data = prob_dist_mean(agent, bot, character1=all_characters[0], character2=all_characters[0], matches=500, frame_chunk_size=FPS * 4, verbose=True) fig, axs = plt.subplots(nrows=4, ncols=3, figsize=(12, 8)) for row in range(4): for col in range(3): action = row * 3 + col action_name = action_names[action] action_clr = tuple(map(lambda rgb: round(rgb / 2 + rgb / 2 * action / (ACTION_DIM_S - 1)) / 0xff, color)) axs[row, col].bar(np.arange(min(dist_data.shape[0], 8)), dist_data[:8, action], color=action_clr) axs[row, col].set_title(action_name) axs[row, col].grid(True) plt.tight_layout() plt.savefig(f'stats_{agent.__class__.__name__.lower()}_{bot.__class__.__name__.lower()}.png', dpi=300) ''' ''' agent2 = neural_ppo_singlehead.PPOAgentWrapper(logging=False) agent2.load_model('trained/ppo/agent_before_self_play.pth') win_rt = win_rate_all_characters(agent1.agent, agent2.agent, 100000, verbose=True) print(' |' + '|'.join([char.name[:4].upper() for char in all_characters]) + '|') print('----+' * (len(all_characters) + 1)) for char1 in all_characters: print(char1.name[:4].upper(), end='|') for char2 in all_characters: win_rt_cell = win_rt[char1.character_id][char2.character_id] if win_rt_cell[0] == 0: print(' - |', end='') else: print(str(round(win_rt_cell[1] / win_rt_cell[0] * 100)).rjust(3, ' '), end='%|') print() '''