-
Notifications
You must be signed in to change notification settings - Fork 21
/
run.py
206 lines (184 loc) · 9.58 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
import os
import time
import sys
import glob
from gym_idsgame.config.runner_mode import RunnerMode
from gym_idsgame.agents.training_agents.policy_gradient.pg_agent_config import PolicyGradientAgentConfig
from gym_idsgame.agents.dao.agent_type import AgentType
from gym_idsgame.config.client_config import ClientConfig
from gym_idsgame.config.hp_tuning_config import HpTuningConfig
from gym_idsgame.runnner import Runner
from experiments.util import plotting_util, util, hp_tuning
def get_script_path():
"""
:return: the script path
"""
return os.path.dirname(os.path.realpath(sys.argv[0]))
def default_output_dir() -> str:
"""
:return: the default output dir
"""
script_dir = get_script_path()
return script_dir
def default_config_path() -> str:
"""
:return: the default path to configuration file
"""
config_path = os.path.join(default_output_dir(), './config.json')
return config_path
def hp_tuning_config(client_config: ClientConfig) -> ClientConfig:
"""
Setup config for hparam tuning
:param client_config: the client config
:return: the updated client config
"""
client_config.hp_tuning = True
client_config.hp_tuning_config = HpTuningConfig(param_1="alpha", param_2="num_hidden_layers",
alpha=[0.000001, 0.00001, 0.0001, 0.001, 0.01],
num_hidden_layers=[1, 2, 4, 8, 16])
client_config.run_many = False
return client_config
def default_config() -> ClientConfig:
"""
:return: Default configuration for the experiment
"""
pg_agent_config = PolicyGradientAgentConfig(gamma=0.999, alpha_attacker=0.00001, epsilon=1, render=False, eval_sleep=0.9,
min_epsilon=0.01, eval_episodes=100, train_log_frequency=100,
epsilon_decay=0.9999, video=True, eval_log_frequency=1,
video_fps=5, video_dir=default_output_dir() + "/results/videos",
num_episodes=350001,
eval_render=False, gifs=True,
gif_dir=default_output_dir() + "/results/gifs",
eval_frequency=10000, attacker=True, defender=False, video_frequency=101,
save_dir=default_output_dir() + "/results/data",
checkpoint_freq=5000, input_dim_attacker=44 * 4, output_dim_attacker=40, hidden_dim=64,
num_hidden_layers=1, batch_size=32,
gpu=False, tensorboard=True,
tensorboard_dir=default_output_dir() + "/results/tensorboard",
optimizer="Adam", lr_exp_decay=False, lr_decay_rate=0.999,
state_length=4)
env_name = "idsgame-random_defense-v9"
client_config = ClientConfig(env_name=env_name, attacker_type=AgentType.ACTOR_CRITIC_AGENT.value,
mode=RunnerMode.TRAIN_ATTACKER.value,
pg_agent_config=pg_agent_config, output_dir=default_output_dir(),
title="Actor-Critic vs Random Defender",
run_many=False, random_seeds=[0, 999, 299, 399, 499])
#client_config = hp_tuning_config(client_config)
return client_config
def write_default_config(path:str = None) -> None:
"""
Writes the default configuration to a json file
:param path: the path to write the configuration to
:return: None
"""
if path is None:
path = default_config_path()
config = default_config()
util.write_config_file(config, path)
def plot_csv(config: ClientConfig, eval_csv_path:str, train_csv_path: str, random_seed : int = 0) -> None:
"""
Plot results from csv files
:param config: client config
:param eval_csv_path: path to the csv file with evaluation results
:param train_csv_path: path to the csv file with training results
:param random_seed: the random seed of the experiment
:return: None
"""
plotting_util.read_and_plot_results(train_csv_path, eval_csv_path, config.pg_agent_config.train_log_frequency,
config.pg_agent_config.eval_frequency, config.pg_agent_config.eval_log_frequency,
config.pg_agent_config.eval_episodes, config.output_dir, sim=False,
random_seed = random_seed)
def plot_average_results(experiment_title :str, config: ClientConfig, eval_csv_paths:list,
train_csv_paths: str) -> None:
"""
Plots average results after training with different seeds
:param experiment_title: title of the experiment
:param config: experiment config
:param eval_csv_paths: paths to csv files with evaluation data
:param train_csv_paths: path to csv files with training data
:return: None
"""
plotting_util.read_and_plot_average_results(experiment_title, train_csv_paths, eval_csv_paths,
config.pg_agent_config.train_log_frequency,
config.pg_agent_config.eval_frequency,
config.output_dir,
plot_attacker_loss = True, plot_defender_loss = False)
def run_experiment(configpath: str, random_seed: int, noconfig: bool):
"""
Runs one experiment and saves results and plots
:param configpath: path to configfile
:param noconfig: whether to override config
:return: (train_csv_path, eval_csv_path)
"""
if configpath is not None and not noconfig:
if not os.path.exists(args.configpath):
write_default_config()
config = util.read_config(args.configpath)
else:
config = default_config()
time_str = str(time.time())
util.create_artefact_dirs(config.output_dir, random_seed)
logger = util.setup_logger("actor_critic_vs_random_defense-v8", config.output_dir + "/results/logs/" +
str(random_seed) + "/",
time_str=time_str)
config.pg_agent_config.save_dir = default_output_dir() + "/results/data/" + str(random_seed) + "/"
config.pg_agent_config.video_dir= default_output_dir() + "/results/videos/" + str(random_seed) + "/"
config.pg_agent_config.gif_dir= default_output_dir() + "/results/gifs/" + str(random_seed) + "/"
config.pg_agent_config.tensorboard_dir = default_output_dir() + "/results/tensorboard/" \
+ str(random_seed) + "/"
config.logger = logger
config.pg_agent_config.logger = logger
config.pg_agent_config.random_seed = random_seed
config.random_seed = random_seed
config.pg_agent_config.to_csv(config.output_dir + "/results/hyperparameters/" + str(random_seed) + "/" + time_str + ".csv")
train_csv_path = ""
eval_csv_path = ""
if config.hp_tuning:
hp_tuning.hype_grid(config)
else:
train_result, eval_result = Runner.run(config)
if len(train_result.avg_episode_steps) > 0 and len(eval_result.avg_episode_steps) > 0:
train_csv_path = config.output_dir + "/results/data/" + str(random_seed) + "/" + time_str + "_train" + ".csv"
train_result.to_csv(train_csv_path)
eval_csv_path = config.output_dir + "/results/data/" + str(random_seed) + "/" + time_str + "_eval" + ".csv"
eval_result.to_csv(eval_csv_path)
plot_csv(config, eval_csv_path, train_csv_path, random_seed)
return train_csv_path, eval_csv_path
# Program entrypoint
if __name__ == '__main__':
args = util.parse_args(default_config_path())
experiment_title = "Actor-Critic vs random defense"
if args.configpath is not None and not args.noconfig:
if not os.path.exists(args.configpath):
write_default_config()
config = util.read_config(args.configpath)
else:
config = default_config()
if args.plotonly:
base_dir = default_output_dir() + "/results/data/"
train_csv_paths = []
eval_csv_paths = []
for seed in config.random_seeds:
train_csv_path = glob.glob(base_dir + str(seed) + "/*_train.csv")[0]
eval_csv_path = glob.glob(base_dir + str(seed) + "/*_eval.csv")[0]
train_csv_paths.append(train_csv_path)
eval_csv_paths.append(eval_csv_path)
plot_csv(config, eval_csv_path, train_csv_path, random_seed=seed)
try:
plot_average_results(experiment_title, config, eval_csv_paths, train_csv_paths)
except Exception as e:
print("Error when trying to plot summary: " + str(e))
else:
if not config.run_many:
run_experiment(args.configpath, 0, args.noconfig)
else:
train_csv_paths = []
eval_csv_paths = []
for seed in config.random_seeds:
train_csv_path, eval_csv_path = run_experiment(args.configpath, seed, args.noconfig)
train_csv_paths.append(train_csv_path)
eval_csv_paths.append(eval_csv_path)
try:
plot_average_results(experiment_title, config, eval_csv_paths, train_csv_paths)
except Exception as e:
print("Error when trying to plot summary: " + str(e))