Exemplo n.º 1
0
    def detect(self, **kwargs):
        super().detect(**kwargs)
        target_class = self.attack.target_class
        self.attack.mark.random_pos = False
        self.attack.mark.height_offset = 0
        self.attack.mark.width_offest = 0
        if not self.random_pos:
            self.real_mask = self.attack.mark.mask
        mark_list, mask_list, loss_list = self.get_potential_triggers()
        mask_norms = mask_list.flatten(start_dim=1).norm(p=1, dim=1)
        print('mask norms: ', mask_norms)
        print('mask MAD: ', normalize_mad(mask_norms))
        print('loss: ', loss_list)
        print('loss MAD: ', normalize_mad(loss_list))

        if not self.random_pos:
            overlap = jaccard_idx(mask_list[self.attack.target_class],
                                  self.real_mask,
                                  select_num=self.attack.mark.mark_height *
                                  self.attack.mark.mark_width)
            print(f'Jaccard index: {overlap:.3f}')

        if not os.path.exists(self.folder_path):
            os.makedirs(self.folder_path)
        mark_list = [to_numpy(i) for i in mark_list]
        mask_list = [to_numpy(i) for i in mask_list]
        loss_list = [to_numpy(i) for i in loss_list]
        np.savez(self.folder_path +
                 self.get_filename(target_class=target_class) + '.npz',
                 mark_list=mark_list,
                 mask_list=mask_list,
                 loss_list=loss_list)
        print('Defense results saved at: ' + self.folder_path +
              self.get_filename(target_class=target_class) + '.npz')
Exemplo n.º 2
0
    def grad_cam(self, _input: torch.FloatTensor,
                 _class: list[int]) -> np.ndarray:
        if isinstance(_class, int):
            _class = [_class] * len(_input)
        _class = torch.tensor(_class).to(_input.device)
        feats = self._model.get_fm(_input).detach()  # (N,C,H,W)
        feats.requires_grad_()
        _output: torch.FloatTensor = self._model.pool(feats)
        _output: torch.FloatTensor = self._model.flatten(_output)
        _output: torch.FloatTensor = self._model.classifier(_output)
        _output: torch.FloatTensor = _output.gather(
            dim=1, index=_class.unsqueeze(1)).sum()
        grad: torch.FloatTensor = torch.autograd.grad(_output,
                                                      feats)[0]  # (N,C,H,W)
        feats.requires_grad_(False)

        weights: torch.FloatTensor = grad.mean(dim=-2, keepdim=True).mean(
            dim=-1, keepdim=True)  # (N,C,1,1)
        heatmap: torch.FloatTensor = (feats * weights).sum(dim=1).clamp(
            0)  # (N,H,W)
        heatmap.sub_(
            heatmap.min(dim=-2, keepdim=True)[0].min(dim=-1, keepdim=True)[0])
        heatmap.div_(
            heatmap.max(dim=-2, keepdim=True)[0].max(dim=-1, keepdim=True)[0])
        heatmap = (to_numpy(heatmap).transpose(1, 2, 0) * 255).astype(np.uint8)
        heatmap = Image.fromarray(heatmap).resize(_input.shape[-2:],
                                                  resample=Image.BICUBIC)
        heatmap = np.array(heatmap)
        if len(heatmap.shape) == 2:
            heatmap = heatmap.reshape(heatmap.shape[0], heatmap.shape[1], 1)
        heatmap = heatmap.transpose(2, 0, 1).astype(float) / 255  # (N, H, W)
        return heatmap
Exemplo n.º 3
0
 def poly_fit(x: np.ndarray,
              y: np.ndarray,
              x_grid: np.ndarray,
              degree: int = 1) -> np.ndarray:
     fit_data = to_numpy(y)
     z = np.polyfit(x, fit_data, degree)
     y_grid = np.polyval(z, x_grid)
     return y_grid
Exemplo n.º 4
0
 def atan_fit(x: np.ndarray,
              y: np.ndarray,
              x_grid: np.ndarray,
              degree: int = 1,
              mean_bias: float = 0.0,
              scale_multiplier: float = 1.0) -> np.ndarray:
     mean = (max(y) + min(y)) / 2 + mean_bias
     scale = max(abs(y - mean)) * scale_multiplier
     fit_data = to_numpy(torch.as_tensor((y - mean) / scale).tan())
     z = np.polyfit(x, fit_data, degree)
     y_grid = np.tanh(np.polyval(z, x_grid)) * scale + mean
     return y_grid
Exemplo n.º 5
0
 def normalize(x: np.ndarray,
               _min: float = None,
               _max: float = None,
               tgt_min: float = 0.0,
               tgt_max: float = 1.0) -> np.ndarray:
     x = to_numpy(x)
     if _min is None:
         _min = x.min()
     if _max is None:
         _max = x.max()
     x = (x - _min) / (_max - _min) * (tgt_max - tgt_min) + tgt_min
     return x
Exemplo n.º 6
0
 def avg_smooth(x: np.ndarray, window: int = 3) -> np.ndarray:
     _x = torch.as_tensor(x)
     new_x = torch.zeros_like(_x)
     for i in range(len(_x)):
         if i < window // 2:
             new_x[i] = (_x[0] * (window // 2 - i) +
                         _x[:i + (window + 1) // 2].sum()) / window
         elif i >= len(_x) - (window - 1) // 2:
             new_x[i] = (_x[-1] * ((window + 1) // 2 - len(_x) + i) +
                         _x[i - window // 2:].sum()) / window
         else:
             new_x[i] = _x[i - window // 2:i + 1 + (window - 1) // 2].mean()
     return to_numpy(new_x) if isinstance(x, np.ndarray) else new_x
Exemplo n.º 7
0
    def detect(self, **kwargs):
        super().detect(**kwargs)
        clean_entropy = []
        poison_entropy = []
        loader = self.dataset.loader['valid']
        if env['tqdm']:
            loader = tqdm(loader)
        for i, data in enumerate(loader):
            _input, _label = self.model.get_data(data)
            poison_input = self.attack.add_mark(_input)
            clean_entropy.append(self.check(_input, _label))
            poison_entropy.append(self.check(poison_input, _label))
        clean_entropy = torch.cat(clean_entropy).flatten().sort()[0]
        poison_entropy = torch.cat(poison_entropy).flatten().sort()[0]
        _dict = {
            'clean': to_numpy(clean_entropy),
            'poison': to_numpy(poison_entropy)
        }
        result_file = f'{self.folder_path}{self.get_filename()}.npy'
        np.save(result_file, _dict)
        print('File Saved at : ', result_file)
        print('Entropy Clean  Median: ', float(clean_entropy.median()))
        print('Entropy Poison Median: ', float(poison_entropy.median()))

        threshold_low = float(clean_entropy[int(0.05 * len(clean_entropy))])
        threshold_high = float(clean_entropy[int(0.95 * len(clean_entropy))])
        y_true = torch.cat(
            (torch.zeros_like(clean_entropy), torch.ones_like(poison_entropy)))
        entropy = torch.cat((clean_entropy, poison_entropy))
        y_pred = torch.where(((entropy < threshold_low).int() +
                              (entropy > threshold_high).int()).bool(),
                             torch.ones_like(entropy),
                             torch.zeros_like(entropy))
        print(f'Threshold: ({threshold_low:5.3f}, {threshold_high:5.3f})')
        print("f1_score:", metrics.f1_score(y_true, y_pred))
        print("precision_score:", metrics.precision_score(y_true, y_pred))
        print("recall_score:", metrics.recall_score(y_true, y_pred))
        print("accuracy_score:", metrics.accuracy_score(y_true, y_pred))
Exemplo n.º 8
0
    def get_dominant_colour(self, img: torch.Tensor, k_means_num=None):
        """[summary]

        Args:
            img (torch.Tensor): # (C, H, W)
            k_means_num (int, optional): Defaults to 3.

        """
        if k_means_num is None:
            k_means_num = self.k_means_num
        img = to_numpy(img.transpose(0, -1).flatten(end_dim=-2))  # (*, C)
        kmeans_result = KMeans(n_clusters=k_means_num).fit(img)
        unique, counts = np.unique(kmeans_result.labels_, return_counts=True)
        center = kmeans_result.cluster_centers_[unique[np.argmax(counts)]]
        return torch.tensor(center)
Exemplo n.º 9
0
 def save_npz(self, npz_path: str):
     _dict = {}
     if not self.mark_distributed:
         _dict |= {'org_mark': to_numpy(self.org_mark),
                   'org_mask': to_numpy(self.org_mask),
                   'org_alpha_mask': to_numpy(self.org_alpha_mask)}
     if not self.random_pos:
         _dict |= {'mark': to_numpy(self.mark),
                   'mask': to_numpy(self.mask),
                   'alpha_mask': to_numpy(self.alpha_mask)}
     np.savez(npz_path, **_dict)
Exemplo n.º 10
0
 def get_potential_triggers(self,
                            neuron_dict: dict[int, list[dict]],
                            _input: torch.Tensor,
                            _label: torch.Tensor,
                            use_mask=True) -> dict[int, list[dict]]:
     losses = AverageMeter('Loss', ':.4e')
     norms = AverageMeter('Norm', ':6.2f')
     jaccard = AverageMeter('Jaccard Idx', ':6.2f')
     score_list = [0.0] * len(list(neuron_dict.keys()))
     result_dict = {}
     for label, label_list in neuron_dict.items():
         print('label: ', label)
         best_score = 100.0
         for _dict in reversed(label_list):
             layer = _dict['layer']
             neuron = _dict['neuron']
             value = _dict['value']
             # color = ('{red}' if label == self.attack.target_class else '{green}').format(**ansi)
             # _str = f'layer: {layer:<20} neuron: {neuron:<5d} label: {label:<5d}'
             # prints('{color}{_str}{reset}'.format(color=color, _str=_str, **ansi), indent=4)
             mark, mask, loss = self.remask(_input,
                                            layer=layer,
                                            neuron=neuron,
                                            label=label,
                                            use_mask=use_mask)
             self.attack.mark.mark = mark
             self.attack.mark.alpha_mask = mask
             self.attack.mark.mask = torch.ones_like(mark, dtype=torch.bool)
             self.attack.target_class = label
             attack_loss, attack_acc = self.model._validate(
                 verbose=False,
                 get_data_fn=self.attack.get_data,
                 keep_org=False)
             _dict['loss'] = loss
             _dict['attack_acc'] = attack_acc
             _dict['attack_loss'] = attack_loss
             _dict['mask'] = to_numpy(mask)
             _dict['mark'] = to_numpy(mark)
             _dict['norm'] = float(mask.norm(p=1))
             score = attack_loss + 7e-2 * float(mask.norm(p=1))
             if score < best_score:
                 best_score = score
                 result_dict[label] = _dict
             if attack_acc > 90:
                 losses.update(loss)
                 norms.update(mask.norm(p=1))
             _str = f'    layer: {layer:20s}    neuron: {neuron:5d}    value: {value:.3f}'
             _str += f'    loss: {loss:10.3f}'
             f'    ATK Acc: {attack_acc:.3f}'
             f'    ATK Loss: {attack_loss:10.3f}'
             f'    Norm: {mask.norm(p=1):.3f}'
             f'    Score: {score:.3f}'
             if not self.attack.mark.random_pos:
                 overlap = jaccard_idx(mask, self.real_mask)
                 _dict['jaccard'] = overlap
                 _str += f'    Jaccard: {overlap:.3f}'
                 if attack_acc > 90:
                     jaccard.update(overlap)
             else:
                 _dict['jaccard'] = 0.0
             print(_str)
             if not os.path.exists(self.folder_path):
                 os.makedirs(self.folder_path)
             np.save(
                 self.folder_path +
                 self.get_filename(target_class=self.target_class) + '.npy',
                 neuron_dict)
             np.save(
                 self.folder_path +
                 self.get_filename(target_class=self.target_class) +
                 '_best.npy', result_dict)
         print(
             f'Label: {label:3d}  loss: {result_dict[label]["loss"]:10.3f}  ATK loss: {result_dict[label]["attack_loss"]:10.3f}  Norm: {result_dict[label]["norm"]:10.3f}  Jaccard: {result_dict[label]["jaccard"]:10.3f}  Score: {best_score:.3f}'
         )
         score_list[label] = best_score
     print('Score: ', score_list)
     print('Score MAD: ', normalize_mad(score_list))
     return neuron_dict