Skip to content

Commit

Permalink
+
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeratt committed Oct 29, 2024
1 parent 84bad82 commit 89f1f03
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
13 changes: 8 additions & 5 deletions experiments/EAttack_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,17 @@ def test():
my_device = device('cpu')

# Load dataset
full_name = ("single-graph", "Planetoid", 'Cora')
# 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,
dataset_ver_ind=0
)

# Train model on original dataset and remember the model metric and node predicted probability
# gcn_gcn = model_configs_zoo(dataset=dataset, model_name='gcn_gcn')
gcn_gcn_gcn = model_configs_zoo(dataset=dataset, model_name='gcn_gcn_gcn')
gcn_gcn = model_configs_zoo(dataset=dataset, model_name='gcn_gcn')
# gcn_gcn_gcn = model_configs_zoo(dataset=dataset, model_name='gcn_gcn_gcn')

manager_config = ConfigPattern(
_config_class="ModelManagerConfig",
Expand All @@ -58,7 +59,7 @@ def test():
)

gnn_model_manager = FrameworkGNNModelManager(
gnn=gcn_gcn_gcn,
gnn=gcn_gcn,
dataset_path=results_dataset_path,
manager_config=manager_config,
modification=ModelModificationConfig(model_ver_ind=0, epochs=0)
Expand Down Expand Up @@ -87,7 +88,8 @@ def test():
_import_path=EXPLAINERS_INIT_PARAMETERS_PATH,
_config_class="ExplainerInitConfig",
_config_kwargs={
"node_mask_type": "attributes"
"node_mask_type": "common_attributes",
"edge_mask_type": None
}
)
explainer_run_config = ConfigPattern(
Expand Down Expand Up @@ -173,6 +175,7 @@ def test():
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.002 * len(node_inds)))
attack_inds = np.random.choice(node_inds, attacked_node_size)

evasion_attack_config = ConfigPattern(
Expand Down
4 changes: 2 additions & 2 deletions metainfo/evasion_attack_parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"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", false, {}, "Whether features to be attacked or not"],
"attack_edges": ["Attack edges", "bool", true, {}, "Whether edges to be attacked or not"],
"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"],
"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)"]
},
Expand Down
44 changes: 40 additions & 4 deletions src/attacks/EAttack/experimental_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def __init__(self, explainer, run_config, attack_size, attack_inds, targeted, ma


def attack(self, model_manager, gen_dataset, mask_tensor):
"""
Now edge modification designed in order to get list of attacked nodes that consist of one specific node TODO - refactor
Feature attack to be developed in order to attack targetted node
"""

assert self.attack_edges or self.attack_features

Expand Down Expand Up @@ -134,9 +138,41 @@ def attack(self, model_manager, gen_dataset, mask_tensor):
print(cnt)

if self.attack_features:
if self.features_mode == 'reverse':
pass
elif self.features_mode == 'drop':
pass
cnt = 0
for i, n in enumerate(self.attack_inds):
if self.features_mode == 'reverse':
# get 2-hop
hop_1 = set()
hop_2 = set()
for (u, v) in edge_index_set:
if u == n:
hop_1.add(v)
elif v == n:
hop_1.add(u)
for (u, v) in edge_index_set:
if u in hop_1 and v != n and v not in hop_1:
hop_2.add(v)
elif v in hop_1 and u != n and u not in hop_1:
hop_2.add(u)

#get features to be reversed
#f_mask = torch.zeros_like(gen_dataset.dataset.data.x.shape[0])
f_inds = []
for f, v in explanations[i]['nodes'].items():
if v:
f_inds.append(int(f))
cnt += 1
f_inds = torch.tensor(f_inds)

if not f_inds.numel():
continue

xor_mask = torch.ones_like(f_inds)

for i in hop_2.union(hop_1).union(set([int(n)])):
gen_dataset.dataset.data.x[i, f_inds] = torch.logical_xor(gen_dataset.dataset.data.x[i, f_inds], xor_mask).float()
elif self.features_mode == 'drop':
pass
print(cnt)

return gen_dataset
4 changes: 2 additions & 2 deletions src/explainers/GNNExplainer/torch_geom_our/out.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def _finalize(self):
mode = self._run_mode
assert mode == "local"

edge_mask = self.raw_explanation.edge_mask
edge_mask = self.raw_explanation.edge_mask if hasattr(self.raw_explanation, 'edge_mask') else None
node_mask = self.raw_explanation.node_mask

self.explanation = AttributionExplanation(
Expand Down Expand Up @@ -137,7 +137,7 @@ def _finalize(self):

# Nodes
num_nodes = node_mask.size(0)
assert num_nodes == self.x.size(0)
# assert num_nodes == self.x.size(0)

for i in range(num_nodes):
imp = float(node_mask[i][0])
Expand Down

0 comments on commit 89f1f03

Please sign in to comment.