Skip to content

Commit

Permalink
Stable experiments edge
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeratt committed Oct 30, 2024
1 parent 89f1f03 commit deebe69
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 60 deletions.
97 changes: 59 additions & 38 deletions experiments/EAttack_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def test():
my_device = device('cpu')

# Load dataset
# full_name = ("single-graph", "Planetoid", 'Cora')
full_name = ("single-graph", "Planetoid", "CiteSeer")
full_name = ("single-graph", "Planetoid", 'Cora')
# full_name = ("single-graph", "Planetoid", "CiteSeer")
# full_name = ('single-graph', 'pytorch-geometric-other', 'KarateClub')
dataset, data, results_dataset_path = DatasetManager.get_by_full_name(
full_name=full_name,
Expand Down Expand Up @@ -68,28 +68,28 @@ def test():
gnn_model_manager.gnn.to(my_device)

num_steps = 200
gnn_model_manager.train_model(gen_dataset=dataset,
steps=num_steps,
save_model_flag=False)
# gnn_model_manager.train_model(gen_dataset=dataset,
# steps=num_steps,
# save_model_flag=False)

# Evaluate model

acc_train = gnn_model_manager.evaluate_model(gen_dataset=dataset,
metrics=[Metric("Accuracy", mask='train')])['train']['Accuracy']


acc_test = gnn_model_manager.evaluate_model(gen_dataset=dataset,
metrics=[Metric("Accuracy", mask='test')])['test']['Accuracy']
print(f"BEFORE ATTACK\nAccuracy on train: {acc_train}. Accuracy on test: {acc_test}")
# acc_train = gnn_model_manager.evaluate_model(gen_dataset=dataset,
# metrics=[Metric("Accuracy", mask='train')])['train']['Accuracy']
#
#
# acc_test = gnn_model_manager.evaluate_model(gen_dataset=dataset,
# metrics=[Metric("Accuracy", mask='test')])['test']['Accuracy']
# print(f"BEFORE ATTACK\nAccuracy on train: {acc_train}. Accuracy on test: {acc_test}")
# print(f"Accuracy on test: {acc_test}")

explainer_init_config = ConfigPattern(
_class_name="GNNExplainer(torch-geom)",
_import_path=EXPLAINERS_INIT_PARAMETERS_PATH,
_config_class="ExplainerInitConfig",
_config_kwargs={
"node_mask_type": "common_attributes",
"edge_mask_type": None
# "node_mask_type": "common_attributes",
# "edge_mask_type": None
}
)
explainer_run_config = ConfigPattern(
Expand Down Expand Up @@ -174,12 +174,17 @@ def test():
if u not in adj_list[v]:
adj_list[v].append(u)
node_inds = [n for n in adj_list.keys() if len(adj_list[n]) > 1]
attacked_node_size = int((0.04 * len(node_inds)))
# attacked_node_size = int((0.04 * len(node_inds)))
attacked_node_size = 100
# attacked_node_size = int((0.002 * len(node_inds)))
attack_inds = np.random.choice(node_inds, attacked_node_size)
# with open('/home/sazonovg/PycharmProjects/GNN-AID/experiments/inds.npy', 'wb') as fin:
# np.save(fin, attack_inds)
with open('/home/sazonovg/PycharmProjects/GNN-AID/experiments/inds.npy', 'rb') as fin:
attack_inds = np.load(fin)

evasion_attack_config = ConfigPattern(
_class_name="EAttack",
_class_name="EAttackRandom",
_import_path=EVASION_ATTACK_PARAMETERS_PATH,
_config_class="EvasionAttackConfig",
_config_kwargs={
Expand All @@ -193,35 +198,51 @@ def test():

dataset_copy = copy.deepcopy(dataset)

succ_attack = 0
with open('/home/sazonovg/PycharmProjects/GNN-AID/experiments/results', 'w') as fout:
for j in tqdm(range(5)):
gcn_gcn = model_configs_zoo(dataset=dataset, model_name='gcn_gcn')

for i in tqdm(attack_inds):
gnn_model_manager = FrameworkGNNModelManager(
gnn=gcn_gcn,
dataset_path=results_dataset_path,
manager_config=manager_config,
modification=ModelModificationConfig(model_ver_ind=0, epochs=0)
)

mask = Metric.create_mask_by_target_list(y_true=dataset.labels, target_list=[i])
gnn_model_manager.train_model(gen_dataset=dataset,
steps=num_steps,
save_model_flag=False)

evasion_attack_config = ConfigPattern(
_class_name="EAttack",
_import_path=EVASION_ATTACK_PARAMETERS_PATH,
_config_class="EvasionAttackConfig",
_config_kwargs={
'explainer': explainer,
'run_config': explainer_run_config,
'mode': 'local',
'attack_inds': [i],
'random_rewire': True
}
)
succ_attack = 0

for i in tqdm(attack_inds):

mask = Metric.create_mask_by_target_list(y_true=dataset.labels, target_list=[i])

evasion_attack_config = ConfigPattern(
_class_name="EAttackRandom",
_import_path=EVASION_ATTACK_PARAMETERS_PATH,
_config_class="EvasionAttackConfig",
_config_kwargs={
'explainer': explainer,
'run_config': explainer_run_config,
'mode': 'local',
'attack_inds': [i],
'random_rewire': True
}
)

gnn_model_manager.set_evasion_attacker(evasion_attack_config=evasion_attack_config)
gnn_model_manager.set_evasion_attacker(evasion_attack_config=evasion_attack_config)

acc_attack = gnn_model_manager.evaluate_model(gen_dataset=dataset,
metrics=[Metric("Accuracy", mask=mask)])[mask]['Accuracy']
acc_attack = gnn_model_manager.evaluate_model(gen_dataset=dataset,
metrics=[Metric("Accuracy", mask=mask)])[mask]['Accuracy']

succ_attack += acc_attack
# print(f"AFTER ATTACK\nAccuracy: {acc_attack}")
succ_attack += acc_attack
# print(f"AFTER ATTACK\nAccuracy: {acc_attack}")

dataset = copy.deepcopy(dataset_copy)
print(f"ACCURACY ON ATTACKED: {succ_attack / len(attack_inds)}")
dataset = copy.deepcopy(dataset_copy)
fout.write(f"{succ_attack / len(attack_inds)}\n")
print(f"ACCURACY ON ATTACKED: {succ_attack / len(attack_inds)}")



Expand Down
20 changes: 17 additions & 3 deletions metainfo/evasion_attack_parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,24 @@
"targeted": ["Targeted attack", "bool", true, {}, "Whether attack targeted or not"],
"max_rewire": ["Max 2-hop node to rewire for target", "int", 20, {"min": 1, "step": 1}, "Not more than this amount of node from 2-hop neighbourhood will be rewired"],
"random_rewire": ["Random rewire", "bool", false, {}, "Rewire based on random, not on explanation (for comparison)"],
"attack_features": ["Attack features", "bool", true, {}, "Whether features to be attacked or not"],
"attack_edges": ["Attack edges", "bool", false, {}, "Whether edges to be attacked or not"],
"attack_features": ["Attack features", "bool", false, {}, "Whether features to be attacked or not"],
"attack_edges": ["Attack edges", "bool", true, {}, "Whether edges to be attacked or not"],
"edge_mode": ["Edge attack type", "string", "rewire", ["remove", "add", "rewire"], "What to do with edges: remove or add or rewire (add one and remove another)"],
"features_mode": ["Feature attack type", "string", "reverse", ["reverse","drop"], "What to do with features: drop or reverse (binary)"]
"features_mode": ["Feature attack type", "string", "reverse", ["reverse","drop"], "What to do with features: drop or reverse (binary)"],
"edge_prob": ["Probability to attack edge", "float", 0.3, {"min": 0, "max": 1, "step": 0.01}, "Probability of drop/add/rewire edge"],
"features_prob": ["Probability to attack feature", 0.15, {"min": 0, "max": 1, "step": 0.01}, "Probability of reverse/drop feature"]
},
"EAttackRandom": {
"attack_size": ["Attack size (edge)", "float", 0.15, {"min": 0, "max": 1, "step": 0.01}, "Percent of nodes to be rewired"],
"targeted": ["Targeted attack", "bool", true, {}, "Whether attack targeted or not"],
"max_rewire": ["Max 2-hop node to rewire for target", "int", 20, {"min": 1, "step": 1}, "Not more than this amount of node from 2-hop neighbourhood will be rewired"],
"random_rewire": ["Random rewire", "bool", true, {}, "Rewire based on random, not on explanation (for comparison)"],
"attack_features": ["Attack features", "bool", false, {}, "Whether features to be attacked or not"],
"attack_edges": ["Attack edges", "bool", true, {}, "Whether edges to be attacked or not"],
"edge_mode": ["Edge attack type", "string", "rewire", ["remove", "add", "rewire"], "What to do with edges: remove or add or rewire (add one and remove another)"],
"features_mode": ["Feature attack type", "string", "reverse", ["reverse","drop"], "What to do with features: drop or reverse (binary)"],
"edge_prob": ["Probability to attack", "float", 0.3, {"min": 0, "max": 1, "step": 0.01}, "Probability of drop/add/rewire edge"],
"features_prob": ["Probability to attack feature", 0.15, {"min": 0, "max": 1, "step": 0.01}, "Probability of reverse/drop feature"]
},
"QAttack": {
"population_size": ["Population size", "int", 50, {"min": 1, "step": 1}, "Number of genes in population"],
Expand Down
Loading

0 comments on commit deebe69

Please sign in to comment.