Exemple #1
0
 def setModelWrapper(self, gnn_type):
     self.model_wrapper = ModelWrapper(node_model=self.mode.isNodeModel(),
                                       gnn_type=gnn_type,
                                       num_layers=self.num_layers,
                                       dataset=self.dataset,
                                       patience=self.patience,
                                       device=self.device,
                                       seed=self.seed)
     print(
         f'######################## LOADING MODEL {self.model_wrapper.model.name} ########################'
     )
     self.model_wrapper.train(self.dataset)
Exemple #2
0
    def setModelWrapper(self, gnn_type: GNN_TYPE):
        """
            Sets a ModelWrapper object and trains said ModelWrapper

            Parameters
            ----------
            gnn_type: GNN_TYPE - the type of the gnn
                                 more information at classes.basic_classes.GNN_TYPE
        """
        dataset = self.getDataset()
        self.model_wrapper = ModelWrapper(node_model=self.mode.isNodeModel(), gnn_type=gnn_type,
                                          num_layers=self.num_layers, dataset=dataset, patience=self.patience,
                                          device=self.device, seed=self.seed)
        print(f'######################## LOADING MODEL {self.model_wrapper.model.name} ########################')
        self.model_wrapper.train(dataset)
Exemple #3
0
    def setModelWrapper(self, gnn_type: GNN_TYPE):
        """
            Sets a ModelWrapper object adversarially trained, according to the requested Ktrain

            Parameters
            ----------
            gnn_type: GNN_TYPE - the type of the gnn
                                 more information at classes.basic_classes.GNN_TYPE
        """
        dataset = self.getDataset()
        if self.Ktrain != 0:
            self.model_wrapper = AdversarialModelWrapper(node_model=True, gnn_type=gnn_type, num_layers=self.num_layers,
                                                         dataset=dataset, patience=self.patience, device=self.device,
                                                         seed=self.seed)
        else:
            self.model_wrapper = ModelWrapper(node_model=True, gnn_type=gnn_type, num_layers=self.num_layers,
                                              dataset=dataset, patience=self.patience, device=self.device,
                                              seed=self.seed)
        printAttackHeader(attack=self, approach=self.approach)
        print('######################## Creating/Loading an Adversarial Model with Ktrain: {:02d}'.format(self.Ktrain) +
              ' ########################', flush=True)
        self.model_wrapper.train(dataset=dataset, attack=self)
Exemple #4
0
 def setModelWrapper(self, gnn_type):
     if self.Ktrain != 0:
         self.model_wrapper = AdversarialModelWrapper(
             node_model=True,
             gnn_type=gnn_type,
             num_layers=self.num_layers,
             dataset=self.dataset,
             patience=self.patience,
             device=self.device,
             seed=self.seed)
     else:
         self.model_wrapper = ModelWrapper(node_model=True,
                                           gnn_type=gnn_type,
                                           num_layers=self.num_layers,
                                           dataset=self.dataset,
                                           patience=self.patience,
                                           device=self.device,
                                           seed=self.seed)
     printAttackHeader(attack=self, approach=self.approach)
     print(
         '######################## Creating/Loading an Adversarial Model with Ktrain: {:02d}'
         .format(self.Ktrain) + ' ########################',
         flush=True)
     self.model_wrapper.train(dataset=self.dataset, attack=self)
Exemple #5
0
class oneGNNAttack(object):
    """
        Generic attack class

        Parameters
        ----------
        args: ArgumentParser - command line inputs
        start_to_file: str - string to insert at the start of the saved file
        print_answer: Print - the type of output print
                              more information at classes.basic_classes.Print
    """
    def __init__(self, args: ArgumentParser, start_to_file: str,
                 print_answer: Print):
        self.start_to_file = start_to_file
        self.print_answer = print_answer
        self.end_to_file = '.csv'
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        seed = args.seed

        self.mode = args.attMode
        self.dataset_name = args.dataset
        dataset = GraphDataset(args.dataset, device)
        self.__dataset = dataset
        self.dataset_type = args.dataset.get_type()

        self.singleGNN = args.singleGNN
        if args.singleGNN is None:
            self.gnn_types = args.attMode.getGNN_TYPES()
        else:
            self.gnn_types = [args.singleGNN]

        self.num_layers = args.num_layers if args.num_layers is not None else 2
        self.patience = args.patience

        if dataset.type is DatasetType.CONTINUOUS:
            self.continuous_epochs = args.continuous_epochs
        self.lr = args.lr

        if args.l_inf is None:
            args.l_inf = args.dataset.get_l_inf()
        self.l_inf = args.l_inf
        if args.l_0 is None:
            args.l_0 = args.dataset.get_l_0()
        self.l_0 = args.l_0
        self.targeted = args.targeted

        self.max_distance = args.distance

        torch.manual_seed(seed)
        np.random.seed(seed)
        random.seed(seed)
        self.seed = seed
        self.device = device

        print(
            f'######################## STARTING ATTACK ########################'
        )
        self.print_args(args)

        # use set functions
        self.setFileName(dataset, args)

        # *PARTLY* checking correctness of the inputs
        self.checkDistanceFlag(args)

    def setDataset(self, dataset: torch_geometric.data.Data):
        """
            Sets a dataset
            
            Parameters
            ----------
            dataset: torch_geometric.data.Data
        """
        self.__dataset = dataset

    def getDataset(self):
        """
            get a copy of the dataset
            
            Returns
            -------
            dataset: torch_geometric.data.Data
        """
        return copy.deepcopy(self.__dataset)

    def checkDistanceFlag(self, args: ArgumentParser):
        """
            Validates that the distance argument is not requested
            
            Parameters
            ----------
            args: ArgumentParser - command line inputs
        """
        if args.distance is not None:
            exit("This attack doesn't requires the distance flag")

    def setModelWrapper(self, gnn_type: GNN_TYPE):
        """
            Sets a ModelWrapper object and trains said ModelWrapper
            
            Parameters
            ----------
            gnn_type: GNN_TYPE - the type of the gnn
                                 more information at classes.basic_classes.GNN_TYPE
        """
        dataset = self.getDataset()
        self.model_wrapper = ModelWrapper(node_model=self.mode.isNodeModel(),
                                          gnn_type=gnn_type,
                                          num_layers=self.num_layers,
                                          dataset=dataset,
                                          patience=self.patience,
                                          device=self.device,
                                          seed=self.seed)
        print(
            f'######################## LOADING MODEL {self.model_wrapper.model.name} ########################'
        )
        self.model_wrapper.train(dataset)

    def print_args(self, args: ArgumentParser):
        """
            a print of the arguments passed to the main.py
            
            Parameters
            ----------
            args: ArgumentParser - command line inputs
        """
        for arg in vars(args):
            print(f"{arg}: {getattr(args, arg)}")
        print()

    def run(self):
        """
            executes the requested attack for all gnn_types and approaches
        """
        defence, attributes = [], []
        for gnn_type in self.gnn_types:
            self.setModelWrapper(gnn_type)
            tmp_defence, tmp_attributes = self.attackPerGNN()
            defence.append(tmp_defence)
            attributes.append(tmp_attributes)

        defence = torch.cat(defence).to(self.device)
        attributes = torch.cat(attributes).to(self.device)
        self.saveResults(defence=defence, attributes=attributes)

    def attackPerApproachWrapper(self,
                                 approach: Approach) -> Tuple[torch.Tensor]:
        """
            sets seeds before the execution of the requested attack
            (for a specific approach on a specific gnn_type)
            
            Parameters
            ----------
            approach: Approach - the type of attack approach
                                 more information at classes.approach_classes.Approach
        """
        seed = self.seed
        torch.manual_seed(seed)
        np.random.seed(seed)
        random.seed(seed)
        return self.attackPerApproach(approach=approach)

    def setFileName(self, dataset: GraphDataset, args: ArgumentParser):
        """
            sets the generic name for the output file
            
            Parameters
            ----------
            dataset: GraphDataset
            args: ArgumentParser - command line inputs
        """
        if self.singleGNN is None:
            self.file_name = fileNamer(
                dataset_name=dataset.name,
                l_inf=args.l_inf,
                l_0=args.l_0,
                num_layers=args.num_layers,
                seed=args.seed,
                targeted=args.targeted,
                continuous_epochs=args.continuous_epochs,
                start=self.start_to_file,
                end=self.end_to_file)
        else:
            self.file_name = fileNamer(
                dataset_name=dataset.name,
                model_name=args.singleGNN.string(),
                l_inf=args.l_inf,
                l_0=args.l_0,
                num_layers=args.num_layers,
                seed=args.seed,
                targeted=args.targeted,
                continuous_epochs=args.continuous_epochs,
                start=self.start_to_file,
                end=self.end_to_file)

    def extendLog(self, log_start: str, log_end: str) -> str:
        """
            sets the generic output log format
            
            Parameters
            ----------
            log_start: str - prefix of the log format
            log_end: str -  suffix of the log format
            
            Returns
            -------
            log: str - output log format
        """
        if self.mode.isDistance():
            log = log_start + ' Distance: {:02d}'.format(
                self.current_distance) + log_end
        else:
            log = log_start + log_end
        return log

    def setModel(self, model: Model):
        """
            sets the requested model in the ModeWrapper
            
            Parameters
            ----------
            model: Model - the requested model
        """
        self.model_wrapper.setModel(model)

    def saveResults(self, defence: torch.Tensor, attributes: torch.Tensor):
        """
            saves the results of the attack
            
            Parameters
            ----------
            defence: torch.Tensor - the defence %
            attributes: torch.Tensor - the % of attributes used for a *successful attack*
        """
        raise NotImplementedError

    def attackPerGNN(self) -> Tuple[torch.Tensor]:
        """
            executes the requested attack for all approaches on a specific gnn_type
        """
        raise NotImplementedError

    def attackPerApproach(self, approach) -> Tuple[torch.Tensor]:
        """
            executes the requested attack for a specific approach on a specific gnn_type
            
            Parameters
            ----------
            approach: Approach - the type of attack approach
                                 more information at classes.approach_classes.Approach
            Returns
            -------
            defence: torch.Tensor - the defence %
            attributes: torch.Tensor - the % of attributes used for a *successful attack*
        """
        raise NotImplementedError
Exemple #6
0
class NodeGNNSAdversarialAttack(NodeGNNSAttack):
    """
        a Node-based-attack class that tests different train epochs (Ktrain) and different tesst epochs (Ktest)

        Parameters
        ----------
        args: ArgumentParser - command line inputs
    """
    def __init__(self, args: ArgumentParser):
        super(NodeGNNSAdversarialAttack, self).__init__(args, start_to_file='NodeAdversarialAttack',
                                                        print_answer=Print.NO)
        self.Ktrain = self.attack_epochs
        self.Ktests = [1] + list(range(5, 30, 5))
        self.approach = self.approaches[0]

    # a must-create / overriding Node
    def saveResults(self, results: torch.Tensor):
        """
            information at the generic base class oneGNNSAttack
        """
        test_string = [str(k) for k in self.Ktests]
        header = ['', 'clean'] + test_string
        defence_df = pd.DataFrame(results.to('cpu').numpy())
        defence_df.insert(0, " ", str(self.Ktrain))
        defence_df.to_csv(self.file_name, float_format='%.3f', header=header, index=False, na_rep='')

    # overriding
    def run(self):
        """
            executes the requested attack for all Ktests and Ktrains
            (on a single gnn_type and a single approach)
        """
        self.setModelWrapper(gnn_type=self.gnn_types[0])
        tmp_mode = self.mode
        self.mode = self.mode.getModeNode()

        results = torch.zeros(len(self.Ktests) + 1).to(self.device)
        for idx, Ktest in enumerate(self.Ktests):
            print('######################## Attacking Adversarial Model with Ktrain: {:02d},'.format(self.Ktrain) +
                  ' Ktest: {:02d} ########################'.format(Ktest), flush=True)
            tmp_result = self.attackOneApproachAndSetAttackEpochs(approach=self.approach, Ktest=Ktest)
            results[idx + 1] = tmp_result

        results[0] = self.model_wrapper.clean
        self.mode = tmp_mode
        self.saveResults(results.unsqueeze(0))

    def setModelWrapper(self, gnn_type: GNN_TYPE):
        """
            Sets a ModelWrapper object adversarially trained, according to the requested Ktrain

            Parameters
            ----------
            gnn_type: GNN_TYPE - the type of the gnn
                                 more information at classes.basic_classes.GNN_TYPE
        """
        dataset = self.getDataset()
        if self.Ktrain != 0:
            self.model_wrapper = AdversarialModelWrapper(node_model=True, gnn_type=gnn_type, num_layers=self.num_layers,
                                                         dataset=dataset, patience=self.patience, device=self.device,
                                                         seed=self.seed)
        else:
            self.model_wrapper = ModelWrapper(node_model=True, gnn_type=gnn_type, num_layers=self.num_layers,
                                              dataset=dataset, patience=self.patience, device=self.device,
                                              seed=self.seed)
        printAttackHeader(attack=self, approach=self.approach)
        print('######################## Creating/Loading an Adversarial Model with Ktrain: {:02d}'.format(self.Ktrain) +
              ' ########################', flush=True)
        self.model_wrapper.train(dataset=dataset, attack=self)

    # creating
    def attackOneApproachAndSetAttackEpochs(self, approach: Approach, Ktest: int) -> Tuple[torch.Tensor]:
        """
            sets the requested Ktest before
            executing the requested attack for a specific approach on a specific gnn_type

            Parameters
            ----------
            approach: Approach - the type of attack approach
                                 more information at classes.approach_classes.Approach
            Ktest: int - number of attack epochs for the test

            Returns
            -------
            defence: torch.Tensor - the defence %
        """
        self.setAttackEpochs(Ktest)
        results, _, _ = attackSet(self, approach=approach, trainset=False)
        mean_results = getDefenceResultsMean(attack=self, approach=approach, attack_results=results)
        return mean_results[0]

    def setAttackEpochs(self, K: int):
        """
            sets attack_epochs

            Parameters
            ----------
            K: int
        """
        self.attack_epochs = K

    def setIdx(self, idx: int):
        """
            sets the idx

            Parameters
            ----------
            idx: int
        """
        self.idx = idx
Exemple #7
0
class NodeGNNSAdversarialAttack(NodeGNNSAttack):
    def __init__(self, args):
        super(NodeGNNSAdversarialAttack,
              self).__init__(args,
                             start_to_file='NodeAdversarialAttack',
                             print_answer=Print.NO)
        self.Ktrain = self.attack_epochs
        self.Ktests = [1] + list(range(10, 110, 10))
        self.approach = self.approaches[0]

    # a must-create / overriding Node
    def saveResults(self, results):
        test_string = [str(k) for k in self.Ktests]
        header = ['', 'clean'] + test_string
        defence_df = pd.DataFrame(results.to('cpu').numpy())
        defence_df.insert(0, " ", str(self.Ktrain))
        defence_df.to_csv(self.file_name,
                          float_format='%.3f',
                          header=header,
                          index=False,
                          na_rep='')

    # overriding
    def run(self):
        self.setModelWrapper(gnn_type=self.gnn_types[0])
        tmp_mode = self.mode
        self.mode = self.mode.getModeNode()

        results = torch.zeros(len(self.Ktests) + 1).to(self.device)
        for idx, Ktest in enumerate(self.Ktests):
            print(
                '######################## Attacking Adversarial Model with Ktrain: {:02d},'
                .format(self.Ktrain) +
                ' Ktest: {:02d} ########################'.format(Ktest),
                flush=True)
            tmp_result = self.attackOneApproachAndSetAttackEpochs(
                approach=self.approach, Ktest=Ktest)
            results[idx + 1] = tmp_result

        results[0] = self.model_wrapper.clean
        self.mode = tmp_mode
        self.saveResults(results.unsqueeze(0))

    def setModelWrapper(self, gnn_type):
        if self.Ktrain != 0:
            self.model_wrapper = AdversarialModelWrapper(
                node_model=True,
                gnn_type=gnn_type,
                num_layers=self.num_layers,
                dataset=self.dataset,
                patience=self.patience,
                device=self.device,
                seed=self.seed)
        else:
            self.model_wrapper = ModelWrapper(node_model=True,
                                              gnn_type=gnn_type,
                                              num_layers=self.num_layers,
                                              dataset=self.dataset,
                                              patience=self.patience,
                                              device=self.device,
                                              seed=self.seed)
        printAttackHeader(attack=self, approach=self.approach)
        print(
            '######################## Creating/Loading an Adversarial Model with Ktrain: {:02d}'
            .format(self.Ktrain) + ' ########################',
            flush=True)
        self.model_wrapper.train(dataset=self.dataset, attack=self)

    # creating
    def attackOneApproachAndSetAttackEpochs(self, approach, Ktest):
        self.setAttackEpochs(Ktest)
        results, _, _ = attackSet(self,
                                  approach=approach,
                                  print_answer=self.print_answer,
                                  trainset=False)
        return results[0]

    def setAttackEpochs(self, K):
        self.attack_epochs = K

    def setIdx(self, idx):
        self.idx = idx
Exemple #8
0
class oneGNNAttack(object):
    def __init__(self, args, start_to_file, print_answer):
        self.start_to_file = start_to_file
        self.print_answer = print_answer
        self.end_to_file = '.csv'
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        seed = args.seed

        self.mode = args.attMode
        dataset = GraphDataset(args.dataset, device)
        self.dataset = dataset

        self.singleGNN = args.singleGNN
        if args.singleGNN is None:
            self.gnn_types = args.attMode.getGNN_TYPES()
        else:
            self.gnn_types = [args.singleGNN]

        self.num_layers = args.num_layers if args.num_layers is not None else 2
        self.patience = args.patience

        self.attack_epochs = args.attEpochs if args.attEpochs is not None else 20
        self.lr = args.lr
        if args.l_inf is None and dataset.type is DatasetType.CONTINUOUS:
            self.l_inf = 0.1
        else:
            self.l_inf = args.l_inf
        self.targeted = args.targeted

        self.max_distance = args.distance

        torch.manual_seed(seed)
        np.random.seed(seed)
        random.seed(seed)
        self.seed = seed
        self.device = device

        self.approaches = args.attMode.getApproaches()
        print(
            f'######################## STARTING ATTACK ########################'
        )
        self.print_args(args)

        # use set functions
        self.setFileName(dataset, args)

        # *PARTLY* checking correctness of the inputs
        self.checkDistanceFlag(args)

    def checkDistanceFlag(self, args):
        if args.distance is not None:
            quit("This attack doesn't requires the distance flag")

    def setModelWrapper(self, gnn_type):
        self.model_wrapper = ModelWrapper(node_model=self.mode.isNodeModel(),
                                          gnn_type=gnn_type,
                                          num_layers=self.num_layers,
                                          dataset=self.dataset,
                                          patience=self.patience,
                                          device=self.device,
                                          seed=self.seed)
        print(
            f'######################## LOADING MODEL {self.model_wrapper.model.name} ########################'
        )
        self.model_wrapper.train(self.dataset)

    def print_args(self, args):
        for arg in vars(args):
            print(f"{arg}: {getattr(args, arg)}")
        print()

    def attackPerGNN(self, add_clean=True):
        increment = 1 if add_clean else 0

        results = torch.zeros(len(self.approaches) + increment).to(self.device)
        for approach_idx, approach in enumerate(self.approaches):
            tmp_result = self.attackOneApproach(approach)
            results[approach_idx + increment] = tmp_result

        if add_clean:
            results[0] = self.model_wrapper.clean
        return results.unsqueeze(0)

    def setFileName(self, dataset, args):
        if self.singleGNN is None:
            self.file_name = fileNamer(dataset_name=dataset.name,
                                       l_inf=args.l_inf,
                                       num_layers=args.num_layers,
                                       seed=args.seed,
                                       targeted=args.targeted,
                                       attack_epochs=args.attEpochs,
                                       start=self.start_to_file,
                                       end=self.end_to_file)
        else:
            self.file_name = fileNamer(dataset_name=dataset.name,
                                       model_name=args.singleGNN.string(),
                                       l_inf=args.l_inf,
                                       num_layers=args.num_layers,
                                       seed=args.seed,
                                       targeted=args.targeted,
                                       attack_epochs=args.attEpochs,
                                       start=self.start_to_file,
                                       end=self.end_to_file)

    def extendLog(self, log_start, log_end):
        if self.mode.isAdversarial():
            log = 'Adv Epoch: {:02d}, '.format(self.idx) + log_start + log_end
        elif self.mode.isDistance():
            log = log_start + 'Distance: {:02d}, '.format(
                self.current_distance) + log_end
        else:
            log = log_start + log_end
        return log

    def setModel(self, model):
        self.model_wrapper.setModel(model)

    def saveResults(self, results):
        raise NotImplementedError

    def run(self):
        raise NotImplementedError

    def attackOneApproach(self, approach):
        raise NotImplementedError