From b0edadd60917fcd2d63950a22f100d83d0d4e52f Mon Sep 17 00:00:00 2001 From: jin-xiulang Date: Tue, 17 Nov 2020 14:07:25 +0800 Subject: [PATCH] Fix an issue --- mindarmour/adv_robustness/attacks/attack.py | 18 +++++++++++------- .../attacks/black/genetic_attack.py | 18 +++++++++++------- .../adv_robustness/attacks/black/pso_attack.py | 16 ++++++++++------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/mindarmour/adv_robustness/attacks/attack.py b/mindarmour/adv_robustness/attacks/attack.py index 8aa8901..149941f 100644 --- a/mindarmour/adv_robustness/attacks/attack.py +++ b/mindarmour/adv_robustness/attacks/attack.py @@ -222,21 +222,25 @@ class Attack: - numpy.ndarray, the number of objects that are correctly detected. """ model = check_model('model', model, BlackModel) - box_and_confi, pred_labels = model.predict(*inputs) + boxes_and_confi, pred_labels = model.predict(*inputs) det_scores = [] correct_labels_num = [] - gt_boxes_num = gt_boxes.shape[0] + # repeat gt_boxes and gt_labels for all particles cloned from the same sample in PSOAttack/GeneticAttack + if gt_boxes.shape[0] == 1 and boxes_and_confi.shape[0] > 1: + gt_boxes = np.repeat(gt_boxes, boxes_and_confi.shape[0], axis=0) + gt_labels = np.repeat(gt_labels, boxes_and_confi.shape[0], axis=0) iou_thres = 0.5 - for boxes, labels in zip(box_and_confi, pred_labels): + for boxes, labels, gt_box, gt_label in zip(boxes_and_confi, pred_labels, gt_boxes, gt_labels): + gt_box_num = gt_box.shape[0] score = 0 box_num = boxes.shape[0] - correct_label_flag = np.zeros(gt_labels.shape) + correct_label_flag = np.zeros(gt_label.shape) for i in range(box_num): pred_box = boxes[i] max_iou_confi = 0 - for j in range(gt_boxes_num): - iou = calculate_iou(pred_box[:4], gt_boxes[j][:4]) - if labels[i] == gt_labels[j] and iou > iou_thres: + for j in range(gt_box_num): + iou = calculate_iou(pred_box[:4], gt_box[j][:4]) + if labels[i] == gt_label[j] and iou > iou_thres: max_iou_confi = max(max_iou_confi, pred_box[-1] + iou) correct_label_flag[j] = 1 score += max_iou_confi diff --git a/mindarmour/adv_robustness/attacks/black/genetic_attack.py b/mindarmour/adv_robustness/attacks/black/genetic_attack.py index f744d65..dbacc40 100644 --- a/mindarmour/adv_robustness/attacks/black/genetic_attack.py +++ b/mindarmour/adv_robustness/attacks/black/genetic_attack.py @@ -47,10 +47,11 @@ class GeneticAttack(Attack): turns on untargeted attack. It should be noted that only untargeted attack is supproted for model_type='detection', Default: False. reserve_ratio (Union[int, float]): The percentage of objects that can be detected after attacks, - specifically for model_type='detection'. Default: 0.3. + specifically for model_type='detection'. Reserve_ratio should be in the range of (0, 1). Default: 0.3. pop_size (int): The number of particles, which should be greater than zero. Default: 6. - mutation_rate (Union[int, float]): The probability of mutations. Default: 0.005. + mutation_rate (Union[int, float]): The probability of mutations, which should be in the range of (0, 1). + Default: 0.005. per_bounds (Union[int, float]): Maximum L_inf distance. max_steps (int): The maximum round of iteration for each adversarial example. Default: 1000. @@ -83,7 +84,7 @@ class GeneticAttack(Attack): self._targeted = check_param_type('targeted', targeted, bool) self._reserve_ratio = check_value_non_negative('reserve_ratio', reserve_ratio) if self._reserve_ratio > 1: - msg = "reserve_ratio should be less than 1.0, but got {}.".format(self._reserve_ratio) + msg = "reserve_ratio should not be greater than 1.0, but got {}.".format(self._reserve_ratio) LOGGER.error(TAG, msg) raise ValueError(msg) self._sparse = check_param_type('sparse', sparse, bool) @@ -92,8 +93,11 @@ class GeneticAttack(Attack): self._step_size = check_value_positive('step_size', step_size) self._temp = check_value_positive('temp', temp) self._max_steps = check_int_positive('max_steps', max_steps) - self._mutation_rate = check_value_positive('mutation_rate', - mutation_rate) + self._mutation_rate = check_value_non_negative('mutation_rate', mutation_rate) + if self._mutation_rate > 1: + msg = "mutation_rate should not be greater than 1.0, but got {}.".format(self._mutation_rate) + LOGGER.error(TAG, msg) + raise ValueError(msg) self._adaptive = check_param_type('adaptive', adaptive, bool) # initial global optimum fitness value self._best_fit = -np.inf @@ -163,7 +167,7 @@ class GeneticAttack(Attack): msg = "The parameter 'sparse' of GeneticAttack is True, but the input labels is not sparse style " \ "and got its shape as {}.".format(labels.shape) LOGGER.error(TAG, msg) - raise ValueError + raise ValueError(msg) else: labels = np.argmax(labels, axis=1) images = inputs @@ -186,7 +190,7 @@ class GeneticAttack(Attack): auxiliary_input_i = tuple() for item in auxiliary_inputs: auxiliary_input_i += (np.expand_dims(item[i], axis=0),) - gt_boxes_i, gt_labels_i = gt_boxes[i], gt_labels[i] + gt_boxes_i, gt_labels_i = np.expand_dims(gt_boxes[i], axis=0), np.expand_dims(gt_labels[i], axis=0) inputs_i = (images[i],) + auxiliary_input_i confi_ori, gt_object_num = self._detection_scores(inputs_i, gt_boxes_i, gt_labels_i, model=self._model) LOGGER.info(TAG, 'The number of ground-truth objects is %s', gt_object_num[0]) diff --git a/mindarmour/adv_robustness/attacks/black/pso_attack.py b/mindarmour/adv_robustness/attacks/black/pso_attack.py index 46e9e40..2811dc3 100644 --- a/mindarmour/adv_robustness/attacks/black/pso_attack.py +++ b/mindarmour/adv_robustness/attacks/black/pso_attack.py @@ -50,7 +50,7 @@ class PSOAttack(Attack): than zero. Default: 6. t_max (int): The maximum round of iteration for each adversarial example, which should be greater than zero. Default: 1000. - pm (Union[int, float]): The probability of mutations. Default: 0.5. + pm (Union[int, float]): The probability of mutations, which should be in the range of (0, 1). Default: 0.5. bounds (Union[list, tuple, None]): Upper and lower bounds of data. In form of (clip_min, clip_max). Default: None. targeted (bool): If True, turns on the targeted attack. If False, @@ -61,7 +61,7 @@ class PSOAttack(Attack): model_type (str): The type of targeted model. 'classification' and 'detection' are supported now. default: 'classification'. reserve_ratio (Union[int, float]): The percentage of objects that can be detected after attacks, - specifically for model_type='detection'. Default: 0.3. + specifically for model_type='detection'. Reserve_ratio should be in the range of (0, 1). Default: 0.3. Examples: >>> attack = PSOAttack(model) @@ -77,7 +77,11 @@ class PSOAttack(Attack): self._c2 = check_value_positive('c2', c2) self._c = check_value_positive('c', c) self._pop_size = check_int_positive('pop_size', pop_size) - self._pm = check_value_positive('pm', pm) + self._pm = check_value_non_negative('pm', pm) + if self._pm > 1: + msg = "pm should not be greater than 1.0, but got {}.".format(self._pm) + LOGGER.error(TAG, msg) + raise ValueError(msg) self._bounds = bounds if self._bounds is not None: self._bounds = check_param_multi_types('bounds', bounds, [list, tuple]) @@ -93,7 +97,7 @@ class PSOAttack(Attack): raise ValueError(msg) self._reserve_ratio = check_value_non_negative('reserve_ratio', reserve_ratio) if self._reserve_ratio > 1: - msg = "reserve_ratio should be less than 1.0, but got {}.".format(self._reserve_ratio) + msg = "reserve_ratio should not be greater than 1.0, but got {}.".format(self._reserve_ratio) LOGGER.error(TAG, msg) raise ValueError(msg) @@ -200,7 +204,7 @@ class PSOAttack(Attack): msg = "The parameter 'sparse' of PSOAttack is True, but the input labels is not sparse style and " \ "got its shape as {}.".format(labels.shape) LOGGER.error(TAG, msg) - raise ValueError + raise ValueError(msg) else: labels = np.argmax(labels, axis=1) images = inputs @@ -227,7 +231,7 @@ class PSOAttack(Attack): auxiliary_input_i = tuple() for item in auxiliary_inputs: auxiliary_input_i += (np.expand_dims(item[i], axis=0),) - gt_boxes_i, gt_labels_i = gt_boxes[i], gt_labels[i] + gt_boxes_i, gt_labels_i = np.expand_dims(gt_boxes[i], axis=0), np.expand_dims(gt_labels[i], axis=0) inputs_i = (images[i],) + auxiliary_input_i confi_ori, gt_object_num = self._detection_scores(inputs_i, gt_boxes_i, gt_labels_i, self._model) LOGGER.info(TAG, 'The number of ground-truth objects is %s', gt_object_num[0])